permissions 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9bfba6131fb8f4d043ee8d5583def68e610231d8
4
+ data.tar.gz: 5eb1358ab58b09ee5517b437d5c8d1904bafd4b2
5
+ SHA512:
6
+ metadata.gz: 36d2667cd3358117d81dea70dd07c7815d7bc7f4f26f70eb34fd0c9cbea75ac6d21000903362fa4f1870daa82a207414a34795e4b926179ea870e0a9765c0f45
7
+ data.tar.gz: 945e45848d83d5fdb589d23227dfb3bd99f3f0baaad31129bc55df45aeebe3c8edc119c0ebdfbd8e8b8803aee2d2ecd14d79ea9001264635b5b6b22a50e4d9f7
@@ -0,0 +1 @@
1
+ .gs/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ permissions (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ clap (1.0.0)
10
+ cutest (1.2.3)
11
+ clap
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ cutest
18
+ permissions!
19
+
20
+ BUNDLED WITH
21
+ 1.15.1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Steven Weiss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ # Permissions
2
+
3
+ A small library for adding permissions to an application for authorization.
4
+
5
+ ## Installation
6
+
7
+ `gem install permissions`
8
+
9
+ ## Usage
10
+
11
+ ### API
12
+
13
+ `for(*keys, &block)`: Creates a permission with the given block for each key.
14
+
15
+ `authorize?(key, *args)`: Runs permission block for key with args.
16
+
17
+ `deep_dup`: Copies permissions to a new object.
18
+
19
+ #### Authorizable
20
+
21
+ `permissions`: Must be implemented by your application.
22
+
23
+ `authorize_for?(key, *args)` Based off the implemented permissions, calls block with args for the given key.
24
+
25
+ ### Example
26
+
27
+ ```ruby
28
+ require 'permissions'
29
+
30
+ class User
31
+ include Permissions::Authorizable
32
+
33
+ def initialize(permissions)
34
+ @permissions = permissions
35
+ end
36
+
37
+ # Authorizables must provide their own implementation of "permissions".
38
+ # An attr_reader would do.
39
+ def permissions
40
+ @permissions
41
+ end
42
+ end
43
+
44
+ class Command
45
+ attr_reader :user
46
+
47
+ def initialize(user)
48
+ @user = user
49
+ end
50
+
51
+ # Not provided by the library. An advanced example
52
+ # on how to authorize things like: "Does an object
53
+ # belong to a particular user?"
54
+ def authorize?(other)
55
+ other.authorize_for?(self.class, self)
56
+ end
57
+ end
58
+
59
+ permissions = Permissions.new
60
+
61
+ permissions.for(Command) { |user, command| user == command.user }
62
+
63
+ user = User.new(permissions)
64
+
65
+ command = Command.new(user)
66
+
67
+ command.authorize?(user) # true
68
+ ```
69
+
70
+ More examples can be found by in the tests.
@@ -0,0 +1,9 @@
1
+ task :install do
2
+ sh 'mkdir -p .gs & gs bundle install --system'
3
+ end
4
+
5
+ task :test, :file_name do |t, args|
6
+ file_name = args[:file_name] || '*'
7
+
8
+ sh "gs cutest -r ./test/#{file_name}_test.rb"
9
+ end
@@ -0,0 +1,37 @@
1
+ class Permissions
2
+ VERSION = '0.1.0'
3
+
4
+ module Authorizable
5
+ def permissions
6
+ raise NotImplementedError
7
+ end
8
+
9
+ def authorize_for?(key, *args)
10
+ permissions.authorize?(key, self, *args)
11
+ end
12
+ end
13
+
14
+ attr_reader :permissions, :default
15
+
16
+ def initialize(permissions = {}, &default)
17
+ @permissions = permissions
18
+
19
+ if block_given?
20
+ @default = default
21
+ else
22
+ @default = lambda { false }
23
+ end
24
+ end
25
+
26
+ def for(*keys, &block)
27
+ keys.each { |key| permissions[key] = block }
28
+ end
29
+
30
+ def authorize?(key, *args)
31
+ permissions.fetch(key, default).call(*args)
32
+ end
33
+
34
+ def deep_dup
35
+ Permissions.new({}.merge(permissions)) { default }
36
+ end
37
+ end
@@ -0,0 +1,14 @@
1
+ require_relative "./lib/permissions"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "permissions"
5
+ s.summary = "Permissions"
6
+ s.version = Permissions::VERSION
7
+ s.authors = ["Steve Weiss"]
8
+ s.email = ["weissst@mail.gvsu.edu"]
9
+ s.homepage = "https://github.com/sirscriptalot/permissions"
10
+ s.license = "MIT"
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_development_dependency "cutest"
14
+ end
@@ -0,0 +1,131 @@
1
+ require_relative '../lib/permissions'
2
+
3
+ class User
4
+ include Permissions::Authorizable
5
+
6
+ def initialize(permissions)
7
+ @permissions = permissions
8
+ end
9
+
10
+ # Authorizables must provide their own implementation of "permissions".
11
+ # An attr_reader would do.
12
+ def permissions
13
+ @permissions
14
+ end
15
+ end
16
+
17
+ class Command
18
+ attr_reader :user
19
+
20
+ def initialize(user)
21
+ @user = user
22
+ end
23
+
24
+ # Not provided by the library. An advanced example
25
+ # on how to authorize things like: "Does an object
26
+ # belong to a particular user?"
27
+ def authorize?(other)
28
+ other.authorize_for?(self.class, self)
29
+ end
30
+ end
31
+
32
+ class Create < Command
33
+ def execute
34
+ 'Create something...'
35
+ end
36
+ end
37
+
38
+ class Update < Command
39
+ def execute
40
+ 'Update something...'
41
+ end
42
+ end
43
+
44
+ class Delete < Command
45
+ def execute
46
+ 'Delete something...'
47
+ end
48
+ end
49
+
50
+ def assert_authorize_for(user, subject)
51
+ assert user.authorize_for?(subject), "#{user} is not authorized for #{subject}, it should be"
52
+ end
53
+
54
+ def refute_authorize_for(user, subject)
55
+ assert !user.authorize_for?(subject), "#{user} is authorized for #{subject}, it should not be"
56
+ end
57
+
58
+ def assert_authorize(subject, user)
59
+ assert subject.authorize?(user), "#{subject} does not authorize #{user}, it should"
60
+ end
61
+
62
+ def refute_authorize(subject, user)
63
+ assert !subject.authorize?(user), "#{subject} does authorize #{user}, it should not"
64
+ end
65
+
66
+ # Create a Permissions object.
67
+ guest_permissions = Permissions.new
68
+
69
+ # Create permissions, guests are allowed to execute Create.
70
+ guest_permissions.for(Create) { true }
71
+
72
+ # Guests cannot Update or Delete, this is also the default permission.
73
+ guest_permissions.for(Update, Delete) { false }
74
+
75
+ # As a convenience, deep_dup lets you copy existing permissions.
76
+ member_permissions = guest_permissions.deep_dup
77
+
78
+ # Users are allowed to update if they "own" the subject.
79
+ member_permissions.for(Update, Delete) { |user, command| user == command.user }
80
+
81
+ # Specify a custom default permissions to allow admins to do everything.
82
+ admin_permissions = Permissions.new { true }
83
+
84
+ guest = User.new(guest_permissions)
85
+
86
+ member = User.new(member_permissions)
87
+
88
+ admin = User.new(admin_permissions)
89
+
90
+ member_update = Update.new(member) # Commands with "ownership".
91
+
92
+ member_delete = Delete.new(member)
93
+
94
+ admin_update = Update.new(admin)
95
+
96
+ admin_delete = Delete.new(admin)
97
+
98
+ test '#authorize_for?' do
99
+ # Guest
100
+ assert_authorize_for guest, Create
101
+ refute_authorize_for guest, Update
102
+ refute_authorize_for guest, Delete
103
+
104
+ # Member
105
+ assert_authorize_for member, Create
106
+ assert_authorize_for admin, Create
107
+
108
+ # Admin
109
+ assert_authorize_for admin, Update
110
+ assert_authorize_for admin, Delete
111
+ end
112
+
113
+ test '#authorize?' do
114
+ # Guest
115
+ refute_authorize member_update, guest
116
+ refute_authorize member_delete, guest
117
+ refute_authorize admin_update, guest
118
+ refute_authorize admin_delete, guest
119
+
120
+ # Member
121
+ assert_authorize member_update, member
122
+ assert_authorize member_delete, member
123
+ refute_authorize admin_update, member
124
+ refute_authorize admin_delete, member
125
+
126
+ # Admin
127
+ assert_authorize member_update, admin
128
+ assert_authorize member_delete, admin
129
+ assert_authorize admin_update, admin
130
+ assert_authorize admin_delete, admin
131
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: permissions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Weiss
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cutest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ - weissst@mail.gvsu.edu
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE
38
+ - README.md
39
+ - Rakefile
40
+ - lib/permissions.rb
41
+ - permissions.gemspec
42
+ - test/permissions_test.rb
43
+ homepage: https://github.com/sirscriptalot/permissions
44
+ licenses:
45
+ - MIT
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.6.11
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Permissions
67
+ test_files: []