you_shall_not_pass 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a79fae216fadbeb00fde315821f821aa02d74b7
4
- data.tar.gz: d0ab7c087b94a4aadda386632355083703c376fc
3
+ metadata.gz: aebfe45a21e352593dba3c1d5cc1baae6e1f9b66
4
+ data.tar.gz: 8c6f55da43443b50d645136e4350013195c32e32
5
5
  SHA512:
6
- metadata.gz: f9156130df570722857fc64a371fd79773192663149c1cd067e0524bfb7bd4705be9ad3fde7684c3a1ede19f736e27f17efe0ebaaaf05464e1743de8e8ed6c3c
7
- data.tar.gz: 3b7e2881fca8cc9552391b7b30cf62d8af1b640eaafe6e692e6a5978858c963735c72ff3477b6796f204f4126bf7db9a5e260643cc061ee3ee326575432bbd06
6
+ metadata.gz: 36fa32a3062e4b639f3e0c753335b4258e14d7c08e60ab00b26d824da38b40d00916ce6a2cd080a81ddcc94bf99cb619c51ae0a3b07bcb6e6253382103390b74
7
+ data.tar.gz: c90158efd3dd6010b86fb9177f3093f2f7d5865b8aff219bc121a1815a5bd3f4db0b1b4487f217354835f1e5ba361f2f119121f14fa2bb996b64a8cf58efd61a
@@ -1,7 +1,7 @@
1
1
  require "you_shall_not_pass/version"
2
2
  require "you_shall_not_pass/authorizator"
3
3
  require "you_shall_not_pass/policy"
4
- require "you_shall_not_pass/callable"
4
+ require "callable"
5
5
 
6
6
  module YouShallNotPass
7
7
  end
@@ -1,39 +1,31 @@
1
- require "you_shall_not_pass/callable"
1
+ require "callable"
2
+ require "fattr"
3
+
2
4
  module YouShallNotPass
3
5
  class Authorizator
4
- include Callable
5
-
6
- attr_reader :user
7
-
8
- def initialize(user)
9
- @user = user
6
+ def initialize(**attrs)
7
+ attrs.each do |attr, value|
8
+ send attr, value
9
+ end
10
10
  end
11
-
12
- def can_all?(action, **options, &block)
13
- available_policies = Array(policies[action.to_sym])
14
- can = available_policies.any? && available_policies.all? do |policy|
15
- Callable(policy).call(**options)
11
+
12
+ def can?(permission, **args)
13
+ Array(policies.fetch(permission)).all? do |policy|
14
+ Callable(policy).call(**args) == true
16
15
  end
17
-
18
- if block_given?
19
- yield if can
16
+ rescue KeyError => e
17
+ if permission =~ /_and_/
18
+ permission.to_s.split("_and_").all? { |policy| can?(policy.to_sym, **args)}
19
+ elsif permission =~ /_or_/
20
+ permission.to_s.split("_or_").any? { |policy| can?(policy.to_sym, **args)}
20
21
  else
21
- can
22
+ raise e
22
23
  end
23
- end
24
- alias :can? :can_all?
25
24
 
26
- def can_any?(action, **options, &block)
27
- available_policies = Array(policies[action.to_sym])
28
- can = available_policies.any? && available_policies.any? do |policy|
29
- Callable(policy).call(**options)
30
- end
25
+ end
31
26
 
32
- if block_given?
33
- yield if can
34
- else
35
- can
36
- end
27
+ def perform_for(permission, **args)
28
+ yield if can?(permission, **args)
37
29
  end
38
30
 
39
31
  def policies
@@ -44,31 +36,8 @@ module YouShallNotPass
44
36
 
45
37
  private
46
38
 
47
- def get_policies
48
- if policies_dir
49
- entries = Dir.new(policies_dir).entries
50
- policy_files = entries.grep(/_policy.rb/)
51
- .map { |p|
52
- p["_policy.rb"] = ""
53
- policy_class = "#{p.camelize}Policy".constantize
54
- [p.to_sym, policy_class.new(self)]
55
- }.to_h
56
- else
57
- Hash.new
58
- end
59
- end
60
-
61
- def self.set_policies_dir(dir)
62
- @policies_dir = dir
63
- end
64
-
65
- def self.policies_dir
66
- @policies_dir
67
- end
68
-
69
- def policies_dir
70
- self.class.policies_dir
39
+ def self.attribute(attr)
40
+ fattr attr
71
41
  end
72
42
  end
73
-
74
43
  end
@@ -1,3 +1,3 @@
1
1
  module YouShallNotPass
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -2,7 +2,299 @@ require "spec_helper"
2
2
  require "you_shall_not_pass/authorizator"
3
3
 
4
4
  scope YouShallNotPass::Authorizator do
5
- spec do
6
- true
5
+ scope "#can?" do
6
+ scope "no policies" do
7
+ spec "no policies defined" do
8
+ @ex = capture_exception(KeyError) do
9
+ YouShallNotPass::Authorizator.new.can?(:whatever)
10
+ end
11
+
12
+ @ex.class == KeyError
13
+ end
14
+ end
15
+
16
+ scope "lambdas, procs and other callables" do
17
+ class Action
18
+ def initialize(val)
19
+ @val = val
20
+ end
21
+
22
+ def call(*)
23
+ @val
24
+ end
25
+ end
26
+
27
+ class MyAuthenticator < YouShallNotPass::Authorizator
28
+ def policies
29
+ {
30
+ can_lambda: -> (*) { true },
31
+ cant_lambda: -> (*) { false },
32
+
33
+ can_proc: proc { true },
34
+ cant_proc: proc { false },
35
+
36
+ can_action: Action.new(true),
37
+ cant_action: Action.new(false),
38
+
39
+ can_true: true,
40
+ cant_false: false,
41
+
42
+ can_array: [ true, proc { true }, true ],
43
+ cant_array: [ true, false, true ],
44
+ }
45
+ end
46
+ end
47
+
48
+ let(:authorizator) { MyAuthenticator.new }
49
+
50
+ spec "allow lambda" do
51
+ authorizator.can?(:can_lambda)
52
+ end
53
+
54
+ spec "reject lambda" do
55
+ ! authorizator.can?(:cant_lambda)
56
+ end
57
+
58
+ spec "allow proc" do
59
+ authorizator.can?(:can_proc)
60
+ end
61
+
62
+ spec "reject proc" do
63
+ ! authorizator.can?(:cant_proc)
64
+ end
65
+
66
+ spec "allow action" do
67
+ authorizator.can?(:can_action)
68
+ end
69
+
70
+ spec "reject action" do
71
+ ! authorizator.can?(:cant_action)
72
+ end
73
+
74
+ spec "allow true" do
75
+ authorizator.can?(:can_true)
76
+ end
77
+
78
+ spec "reject false" do
79
+ ! authorizator.can?(:cant_false)
80
+ end
81
+
82
+ spec "allow array" do
83
+ authorizator.can?(:can_array)
84
+ end
85
+
86
+ spec "reject array" do
87
+ ! authorizator.can?(:cant_array)
88
+ end
89
+ end
90
+ end
91
+
92
+ scope "arguments" do
93
+ class MyAuthenticatorWithArgs < YouShallNotPass::Authorizator
94
+ def policies
95
+ {
96
+ lambda: -> (a:, b:) { a == b },
97
+ proc: proc { |a:, b:| a == b },
98
+
99
+ splat: -> (**args) { args.all? { |k, v| k == v} },
100
+ }
101
+ end
102
+ end
103
+
104
+ let(:authorizator) { MyAuthenticatorWithArgs.new }
105
+
106
+ spec "allow lambda" do
107
+ authorizator.can?(:lambda, a: 1, b: 1)
108
+ end
109
+
110
+ spec "reject lambda" do
111
+ ! authorizator.can?(:lambda, a: 1, b: 2)
112
+ end
113
+
114
+ spec "allow proc" do
115
+ authorizator.can?(:proc, a: 1, b: 1)
116
+ end
117
+
118
+ spec "reject proc" do
119
+ ! authorizator.can?(:proc, a: 1, b: 2)
120
+ end
121
+
122
+ spec "allow splat" do
123
+ authorizator.can?(:splat, a: :a , b: :b , c: :c )
124
+ end
125
+
126
+ spec "reject splat" do
127
+ ! authorizator.can?(:splat, a: :a, b: :b, c: :a)
128
+ end
129
+ end
130
+
131
+ scope "#perform_for" do
132
+ class BasicAuthorizator < YouShallNotPass::Authorizator
133
+ def policies
134
+ {
135
+ can: true,
136
+ cant: false,
137
+
138
+ use_args: -> (**args) { args.all? { |k, v| k == v } }
139
+ }
140
+ end
141
+ end
142
+
143
+ let(:authorizator) { BasicAuthorizator.new }
144
+
145
+ spec "executes the block if it is allowed" do
146
+ authorizator.perform_for(:can) do
147
+ @i_can = true
148
+ end
149
+
150
+ !! defined? @i_can
151
+ end
152
+
153
+ spec "doesn't execute the block if it isn't allowed" do
154
+ authorizator.perform_for(:cant) do
155
+ @i_can = true
156
+ end
157
+
158
+ ! defined? @i_can
159
+ end
160
+
161
+ spec "passes the arguments" do
162
+ authorizator.perform_for(:use_args, a: :a, b: :b) do
163
+ @i_can = true
164
+ end
165
+
166
+ !! defined? @i_can
167
+ end
168
+ end
169
+
170
+ scope "conditional policies" do
171
+ class NumberAuthenticator < YouShallNotPass::Authorizator
172
+ def policies
173
+ {
174
+ one: true,
175
+ two: true,
176
+ three: false,
177
+ four: false,
178
+ }
179
+ end
180
+ end
181
+
182
+ let(:authorizator) { NumberAuthenticator.new }
183
+
184
+ spec "allow _and_" do
185
+ authorizator.can?(:one_and_two)
186
+ end
187
+
188
+ spec "reject _and_" do
189
+ ! authorizator.can?(:one_and_three)
190
+ end
191
+
192
+ spec "allow _or_" do
193
+ authorizator.can?(:one_or_two)
194
+ end
195
+
196
+ spec "reject _or_" do
197
+ ! authorizator.can?(:three_or_four)
198
+ end
199
+
200
+ spec "allow _and_or_" do
201
+ authorizator.can?(:one_and_two_or_three)
202
+ end
203
+
204
+ spec "reject _and_or_" do
205
+ ! authorizator.can?(:one_and_three_or_four)
206
+ end
207
+
208
+ scope "regular policies vs conditional policies" do
209
+ class ConditionalAuthorizator < YouShallNotPass::Authorizator
210
+ def policies
211
+ {
212
+ one: true,
213
+ two: true,
214
+ one_and_two: false,
215
+ one_or_two: false
216
+ }
217
+ end
218
+ end
219
+
220
+ let(:authorizator) { ConditionalAuthorizator.new }
221
+
222
+ spec "_and_" do
223
+ ! authorizator.can?(:one_and_two)
224
+ end
225
+
226
+ spec "_or_" do
227
+ ! authorizator.can?(:one_or_two)
228
+ end
229
+ end
230
+ end
231
+
232
+ scope "#polices" do
233
+ class MergePolicies < YouShallNotPass::Authorizator
234
+ def action_policies
235
+ {
236
+ create_user: true,
237
+ update_user: true,
238
+ }
239
+ end
240
+
241
+ def role_policies
242
+ {
243
+ admin: true,
244
+ editor: true,
245
+ }
246
+ end
247
+
248
+ def feature_policies
249
+ {
250
+ avatars: true,
251
+ random_player: true,
252
+ }
253
+ end
254
+ end
255
+
256
+ spec do
257
+ YouShallNotPass::Authorizator.new.policies == {}
258
+ end
259
+
260
+ let(:authorizator) { MergePolicies.new }
261
+
262
+ spec "merges all the policies" do
263
+ @expected = {
264
+ create_user: true,
265
+ update_user: true,
266
+ admin: true,
267
+ editor: true,
268
+ avatars: true,
269
+ random_player: true,
270
+ }
271
+
272
+ authorizator.policies == @expected
273
+ end
274
+ end
275
+
276
+ scope ".attribute" do
277
+ class UserAuthorizator < YouShallNotPass::Authorizator
278
+ attribute :user
279
+ attribute :role
280
+
281
+ def policies
282
+ {
283
+ something: proc { user == "Me" && role == :admin }
284
+ }
285
+ end
286
+ end
287
+
288
+ spec "can initialize with attributes" do
289
+ authorizator = UserAuthorizator.new(user: "Me", role: :admin)
290
+
291
+ authorizator.can?(:something)
292
+ end
293
+
294
+ spec "can initialize with attributes" do
295
+ authorizator = UserAuthorizator.new(user: "Me", role: :user)
296
+
297
+ ! authorizator.can?(:something)
298
+ end
7
299
  end
8
300
  end
@@ -21,4 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "matest", "~> 1.5"
24
+
25
+ spec.add_dependency "callable", "~> 0.0.3"
26
+ spec.add_dependency "fattr", "~> 2.2.2"
24
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: you_shall_not_pass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Federico Iachetti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-30 00:00:00.000000000 Z
11
+ date: 2015-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: callable
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: fattr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.2
55
83
  description: Embrace authorization with this simple library.
56
84
  email:
57
85
  - iachetti.federico@gmail.com
@@ -66,7 +94,6 @@ files:
66
94
  - Rakefile
67
95
  - lib/you_shall_not_pass.rb
68
96
  - lib/you_shall_not_pass/authorizator.rb
69
- - lib/you_shall_not_pass/callable.rb
70
97
  - lib/you_shall_not_pass/policy.rb
71
98
  - lib/you_shall_not_pass/version.rb
72
99
  - spec/spec_helper.rb
@@ -1,16 +0,0 @@
1
- module YouShallNotPass
2
-
3
- module Callable
4
- def Callable( callable_or_not )
5
- callable_or_not.respond_to?(:call) ? callable_or_not : proc { |*args| callable_or_not }
6
- end
7
-
8
- def callable
9
- Callable( self )
10
- end
11
-
12
- def callable?
13
- self.respond_to? :call
14
- end
15
- end
16
- end