permissions 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []