you_shall_not_pass 0.0.1 → 0.0.2

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