acl9 0.11.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.
- data/CHANGELOG.textile +32 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +888 -0
- data/Rakefile +40 -0
- data/TODO +42 -0
- data/VERSION.yml +4 -0
- data/lib/acl9.rb +16 -0
- data/lib/acl9/config.rb +10 -0
- data/lib/acl9/controller_extensions.rb +85 -0
- data/lib/acl9/controller_extensions/dsl_base.rb +229 -0
- data/lib/acl9/controller_extensions/generators.rb +197 -0
- data/lib/acl9/helpers.rb +19 -0
- data/lib/acl9/model_extensions.rb +133 -0
- data/lib/acl9/model_extensions/object.rb +59 -0
- data/lib/acl9/model_extensions/subject.rb +175 -0
- data/test/access_control_test.rb +338 -0
- data/test/dsl_base_test.rb +758 -0
- data/test/helpers_test.rb +93 -0
- data/test/roles_test.rb +310 -0
- data/test/support/controllers.rb +207 -0
- data/test/support/models.rb +47 -0
- data/test/support/schema.rb +69 -0
- data/test/test_helper.rb +31 -0
- metadata +103 -0
@@ -0,0 +1,758 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'test_helper'
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'acl9', 'controller_extensions', 'dsl_base')
|
4
|
+
|
5
|
+
class FakeUser
|
6
|
+
def initialize
|
7
|
+
@roles = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def has_role?(role, object = nil)
|
11
|
+
@roles.include?([role.to_s, object])
|
12
|
+
end
|
13
|
+
|
14
|
+
def <<(role)
|
15
|
+
role = [role] unless role.is_a? Array
|
16
|
+
|
17
|
+
role << nil if role.size == 1
|
18
|
+
raise unless role[0]
|
19
|
+
|
20
|
+
role[0] = role[0].to_s
|
21
|
+
|
22
|
+
@roles[role] = true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class DslTester < Acl9::Dsl::Base
|
27
|
+
def initialize
|
28
|
+
super
|
29
|
+
|
30
|
+
@_subject = nil
|
31
|
+
@_objects = {}
|
32
|
+
@_current_action = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def permit(user, *args)
|
36
|
+
check_allowance(user, *args).should == true
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def forbid(user, *args)
|
42
|
+
check_allowance(user, *args).should == false
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def show_code
|
48
|
+
puts "\n", allowance_expression
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def check_allowance(subject, *args)
|
55
|
+
@_subject = subject
|
56
|
+
@_current_action = (args[0] || 'index').to_s
|
57
|
+
@_objects = args.last.is_a?(Hash) ? args.last : {}
|
58
|
+
@_callable = @_objects.delete(:call)
|
59
|
+
|
60
|
+
instance_eval(allowance_expression)
|
61
|
+
end
|
62
|
+
|
63
|
+
def _subject_ref
|
64
|
+
"@_subject"
|
65
|
+
end
|
66
|
+
|
67
|
+
def _object_ref(object)
|
68
|
+
"@_objects[:#{object}]"
|
69
|
+
end
|
70
|
+
|
71
|
+
def _action_ref
|
72
|
+
"@_current_action"
|
73
|
+
end
|
74
|
+
|
75
|
+
def _method_ref(method)
|
76
|
+
"@_callable.send(:#{method})"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#describe Acl9::Dsl::Base do
|
81
|
+
class DslBaseTest < Test::Unit::TestCase
|
82
|
+
class ThatFoo; end
|
83
|
+
class ThatBar; end
|
84
|
+
|
85
|
+
def arg_err(&block)
|
86
|
+
lambda do
|
87
|
+
acl(&block)
|
88
|
+
end.should raise_error(ArgumentError)
|
89
|
+
end
|
90
|
+
|
91
|
+
def acl(&block)
|
92
|
+
tester = DslTester.new
|
93
|
+
tester.acl_block!(&block)
|
94
|
+
|
95
|
+
tester
|
96
|
+
end
|
97
|
+
|
98
|
+
def permit_some(tester, user, actions, vars = {})
|
99
|
+
actions.each { |act| tester.permit(user, act, vars) }
|
100
|
+
(@all_actions - actions).each { |act| tester.forbid(user, act, vars) }
|
101
|
+
end
|
102
|
+
|
103
|
+
before do
|
104
|
+
@user = FakeUser.new
|
105
|
+
@user2 = FakeUser.new
|
106
|
+
@user3 = FakeUser.new
|
107
|
+
@foo = ThatFoo.new
|
108
|
+
@foo2 = ThatFoo.new
|
109
|
+
@foo3 = ThatFoo.new
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "default" do
|
113
|
+
it "should set default action to deny if none specified" do
|
114
|
+
acl do end.default_action.should == :deny
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should set default action to allow" do
|
118
|
+
acl do
|
119
|
+
default :allow
|
120
|
+
end.default_action.should == :allow
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should set default action to deny" do
|
124
|
+
acl do
|
125
|
+
default :deny
|
126
|
+
end.default_action.should == :deny
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should raise ArgumentError with unknown default_action" do
|
130
|
+
arg_err do
|
131
|
+
default 123
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should raise ArgumentError when default is called more than once" do
|
136
|
+
arg_err do
|
137
|
+
default :deny
|
138
|
+
default :deny
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "empty blocks" do
|
144
|
+
it "should deny everyone with default deny" do
|
145
|
+
acl do
|
146
|
+
end.forbid(nil).forbid(@user)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should allow everyone with default allow" do
|
150
|
+
acl do
|
151
|
+
default :allow
|
152
|
+
end.permit(nil).permit(@user)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "empty" do
|
157
|
+
it "allow should raise an ArgumentError" do
|
158
|
+
arg_err { allow }
|
159
|
+
end
|
160
|
+
|
161
|
+
it "deny should raise an ArgumentError" do
|
162
|
+
arg_err { deny }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "anonymous" do
|
167
|
+
it "'allow nil' should allow anonymous, but not logged in" do
|
168
|
+
acl do
|
169
|
+
allow nil
|
170
|
+
end.permit(nil).forbid(@user)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "'allow anonymous' should allow anonymous, but not logged in" do
|
174
|
+
acl do
|
175
|
+
allow anonymous
|
176
|
+
end.permit(nil).forbid(@user)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "'deny nil' should deny anonymous, but not logged in" do
|
180
|
+
acl do
|
181
|
+
default :allow
|
182
|
+
deny nil
|
183
|
+
end.forbid(nil).permit(@user)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "'deny anonymous' should deny anonymous, but not logged in" do
|
187
|
+
acl do
|
188
|
+
default :allow
|
189
|
+
deny anonymous
|
190
|
+
end.forbid(nil).permit(@user)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "all" do
|
195
|
+
[:all, :everyone, :everybody, :anyone].each do |pseudorole|
|
196
|
+
it "'allow #{pseudorole}' should allow all" do
|
197
|
+
acl do
|
198
|
+
allow send(pseudorole)
|
199
|
+
end.permit(nil).permit(@user)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "'deny #{pseudorole}' should deny all" do
|
203
|
+
acl do
|
204
|
+
default :allow
|
205
|
+
deny send(pseudorole)
|
206
|
+
end.forbid(nil).forbid(@user)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "default :allow" do
|
212
|
+
it "should allow when neither allow nor deny conditions are matched" do
|
213
|
+
acl do
|
214
|
+
default :allow
|
215
|
+
allow :blah
|
216
|
+
deny :bzz
|
217
|
+
end.permit(nil).permit(@user)
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should deny when deny is matched, but allow is not" do
|
221
|
+
acl do
|
222
|
+
default :allow
|
223
|
+
deny all
|
224
|
+
allow :blah
|
225
|
+
end.forbid(nil).forbid(@user)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should allow when allow is matched, but deny is not" do
|
229
|
+
@user << :cool
|
230
|
+
acl do
|
231
|
+
default :allow
|
232
|
+
deny nil
|
233
|
+
allow :cool
|
234
|
+
end.permit(@user)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should allow both allow and deny conditions are matched" do
|
238
|
+
@user << :cool
|
239
|
+
acl do
|
240
|
+
default :allow
|
241
|
+
deny :cool
|
242
|
+
allow :cool
|
243
|
+
end.permit(@user)
|
244
|
+
|
245
|
+
acl do
|
246
|
+
default :allow
|
247
|
+
deny all
|
248
|
+
allow all
|
249
|
+
end.permit(@user).permit(nil).permit(@user2)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe "logged_in" do
|
254
|
+
it "'allow logged_in' should allow logged in, but not anonymous" do
|
255
|
+
acl do
|
256
|
+
allow logged_in
|
257
|
+
end.forbid(nil).permit(@user)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "'allow logged_in' should deny logged in, but not anonymous" do
|
261
|
+
acl do
|
262
|
+
default :allow
|
263
|
+
deny logged_in
|
264
|
+
end.permit(nil).forbid(@user)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "default :deny" do
|
269
|
+
it "should deny when neither allow nor deny conditions are matched" do
|
270
|
+
acl do
|
271
|
+
default :deny
|
272
|
+
allow :blah
|
273
|
+
deny :bzz
|
274
|
+
end.forbid(nil).forbid(@user)
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should deny when deny is matched, but allow is not" do
|
278
|
+
acl do
|
279
|
+
default :deny
|
280
|
+
deny all
|
281
|
+
allow :blah
|
282
|
+
end.forbid(nil).forbid(@user)
|
283
|
+
end
|
284
|
+
|
285
|
+
it "should allow when allow is matched, but deny is not" do
|
286
|
+
@user << :cool
|
287
|
+
acl do
|
288
|
+
default :deny
|
289
|
+
deny nil
|
290
|
+
allow :cool
|
291
|
+
end.permit(@user)
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should deny both allow and deny conditions are matched" do
|
295
|
+
@user << :cool
|
296
|
+
acl do
|
297
|
+
default :deny
|
298
|
+
deny :cool
|
299
|
+
allow :cool
|
300
|
+
end.forbid(@user)
|
301
|
+
|
302
|
+
acl do
|
303
|
+
default :deny
|
304
|
+
deny all
|
305
|
+
allow all
|
306
|
+
end.forbid(@user).forbid(nil).forbid(@user2)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "global roles" do
|
311
|
+
it "#allow with role" do
|
312
|
+
@user << :admin
|
313
|
+
|
314
|
+
acl { allow :admin }.permit(@user).forbid(nil).forbid(@user2)
|
315
|
+
end
|
316
|
+
|
317
|
+
it "#allow with plural role name" do
|
318
|
+
@user << :mouse
|
319
|
+
|
320
|
+
acl do
|
321
|
+
allow :mice
|
322
|
+
end.permit(@user).forbid(nil).forbid(@user2)
|
323
|
+
end
|
324
|
+
|
325
|
+
it "#allow with several roles" do
|
326
|
+
@user << :admin
|
327
|
+
@user << :cool
|
328
|
+
|
329
|
+
@user2 << :cool
|
330
|
+
|
331
|
+
@user3 << :super
|
332
|
+
|
333
|
+
acl do
|
334
|
+
allow :admin
|
335
|
+
allow :cool
|
336
|
+
end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
|
337
|
+
end
|
338
|
+
|
339
|
+
it "#deny with role" do
|
340
|
+
@user << :foo
|
341
|
+
|
342
|
+
acl { default :allow; deny :foo }.forbid(@user).permit(nil).permit(@user2)
|
343
|
+
end
|
344
|
+
|
345
|
+
it "#deny with plural role name" do
|
346
|
+
@user << :mouse
|
347
|
+
|
348
|
+
acl do
|
349
|
+
default :allow
|
350
|
+
deny :mice
|
351
|
+
end.forbid(@user).permit(nil).permit(@user2)
|
352
|
+
end
|
353
|
+
|
354
|
+
it "#deny with several roles" do
|
355
|
+
@user << :admin
|
356
|
+
@user << :cool
|
357
|
+
|
358
|
+
@user2 << :cool
|
359
|
+
|
360
|
+
@user3 << :super
|
361
|
+
|
362
|
+
acl do
|
363
|
+
default :allow
|
364
|
+
deny :admin
|
365
|
+
deny :cool
|
366
|
+
end.forbid(@user).forbid(@user2).permit(nil).permit(@user3)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
describe "prepositions" do
|
371
|
+
[:of, :for, :in, :on, :at, :by].each do |prep|
|
372
|
+
it "#allow with object role (:#{prep}) should check controller's ivar" do
|
373
|
+
@user << [:manager, @foo]
|
374
|
+
|
375
|
+
acl do
|
376
|
+
allow :manager, prep => :foo
|
377
|
+
end.
|
378
|
+
permit(@user, :foo => @foo).
|
379
|
+
forbid(@user, :foo => @foo2).
|
380
|
+
forbid(@user, :foo => ThatFoo).
|
381
|
+
forbid(nil, :foo => @foo).
|
382
|
+
forbid(@user2, :foo => @foo)
|
383
|
+
end
|
384
|
+
|
385
|
+
it "#allow with invalid value for preposition :#{prep} should raise an ArgumentError" do
|
386
|
+
arg_err do
|
387
|
+
allow :hom, :by => 1
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
it "#allow with a class role should verify this role against a class" do
|
393
|
+
@user << [:owner, ThatFoo]
|
394
|
+
|
395
|
+
acl do
|
396
|
+
allow :owner, :of => ThatFoo
|
397
|
+
end.permit(@user).forbid(nil).forbid(@user2)
|
398
|
+
end
|
399
|
+
|
400
|
+
[:of, :for, :in, :on, :at, :by].each do |prep|
|
401
|
+
it "#deny with object role (:#{prep}) should check controller's ivar" do
|
402
|
+
@user << [:bastard, @foo]
|
403
|
+
|
404
|
+
acl do
|
405
|
+
default :allow
|
406
|
+
deny :bastard, prep => :foo
|
407
|
+
end.
|
408
|
+
forbid(@user, :foo => @foo).
|
409
|
+
permit(@user, :foo => @foo2).
|
410
|
+
permit(@user, :foo => ThatFoo).
|
411
|
+
permit(nil, :foo => @foo).
|
412
|
+
permit(@user2, :foo => @foo)
|
413
|
+
end
|
414
|
+
|
415
|
+
it "#deny with invalid value for preposition :#{prep} should raise an ArgumentError" do
|
416
|
+
arg_err do
|
417
|
+
deny :her, :for => "him"
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
it "#deny with a class role should verify this role against a class" do
|
423
|
+
@user << [:ignorant, ThatFoo]
|
424
|
+
|
425
|
+
acl do
|
426
|
+
default :allow
|
427
|
+
deny :ignorant, :of => ThatFoo
|
428
|
+
end.forbid(@user).permit(nil).permit(@user2)
|
429
|
+
end
|
430
|
+
|
431
|
+
it "#allow with several prepositions should raise an ArgumentError" do
|
432
|
+
arg_err do
|
433
|
+
allow :some, :by => :one, :for => :another
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
it "#deny with several prepositions should raise an ArgumentError" do
|
438
|
+
arg_err do
|
439
|
+
deny :some, :in => :here, :on => :today
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
describe ":to and :except" do
|
445
|
+
it "should raise an ArgumentError when both :to and :except are specified" do
|
446
|
+
arg_err do
|
447
|
+
allow all, :to => :index, :except => ['show', 'edit']
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
describe "" do
|
452
|
+
after do
|
453
|
+
%w(index show).each { |act| @list.permit(nil, act) }
|
454
|
+
%w(edit update delete destroy).each { |act| @list.forbid(nil, act) }
|
455
|
+
|
456
|
+
%w(index show edit update).each { |act| @list.permit(@user, act) }
|
457
|
+
%w(delete destroy).each { |act| @list.forbid(@user, act) }
|
458
|
+
|
459
|
+
%w(index show edit update delete destroy).each { |act| @list.permit(@user2, act) }
|
460
|
+
end
|
461
|
+
|
462
|
+
it ":to should limit rule scope to specified actions" do
|
463
|
+
@user << :manager
|
464
|
+
@user2 << :trusted
|
465
|
+
|
466
|
+
@list = acl do
|
467
|
+
allow all, :to => [:index, :show]
|
468
|
+
|
469
|
+
allow 'manager', :to => :edit
|
470
|
+
allow 'manager', :to => 'update'
|
471
|
+
allow 'trusted', :to => %w(edit update delete destroy)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
it ":except should limit rule scope to all actions except specified" do
|
476
|
+
@user << :manager
|
477
|
+
@user2 << :trusted
|
478
|
+
|
479
|
+
@list = acl do
|
480
|
+
allow all, :except => %w(edit update delete destroy)
|
481
|
+
|
482
|
+
allow 'manager', :except => %w(delete destroy)
|
483
|
+
allow 'trusted'
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe "conditions" do
|
490
|
+
[:if, :unless].each do |cond|
|
491
|
+
it "should raise ArgumentError when #{cond} is not a Symbol" do
|
492
|
+
arg_err do
|
493
|
+
allow nil, cond => 123
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
it "allow ... :if" do
|
499
|
+
acl do
|
500
|
+
allow nil, :if => :meth
|
501
|
+
end.
|
502
|
+
permit(nil, :call => OpenStruct.new(:meth => true)).
|
503
|
+
forbid(nil, :call => OpenStruct.new(:meth => false))
|
504
|
+
end
|
505
|
+
|
506
|
+
it "allow ... :unless" do
|
507
|
+
acl do
|
508
|
+
allow nil, :unless => :meth
|
509
|
+
end.
|
510
|
+
permit(nil, :call => OpenStruct.new(:meth => false)).
|
511
|
+
forbid(nil, :call => OpenStruct.new(:meth => true))
|
512
|
+
end
|
513
|
+
|
514
|
+
it "deny ... :if" do
|
515
|
+
acl do
|
516
|
+
default :allow
|
517
|
+
deny nil, :if => :meth
|
518
|
+
end.
|
519
|
+
permit(nil, :call => OpenStruct.new(:meth => false)).
|
520
|
+
forbid(nil, :call => OpenStruct.new(:meth => true))
|
521
|
+
end
|
522
|
+
|
523
|
+
it "deny ... :unless" do
|
524
|
+
acl do
|
525
|
+
default :allow
|
526
|
+
deny nil, :unless => :meth
|
527
|
+
end.
|
528
|
+
permit(nil, :call => OpenStruct.new(:meth => true)).
|
529
|
+
forbid(nil, :call => OpenStruct.new(:meth => false))
|
530
|
+
end
|
531
|
+
|
532
|
+
end
|
533
|
+
|
534
|
+
describe "several roles as arguments" do
|
535
|
+
it "#allow should be able to receive a role list (global roles)" do
|
536
|
+
@user << :bzz
|
537
|
+
@user2 << :whoa
|
538
|
+
|
539
|
+
acl do
|
540
|
+
allow :bzz, :whoa
|
541
|
+
end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
|
542
|
+
end
|
543
|
+
|
544
|
+
it "#allow should be able to receive a role list (object roles)" do
|
545
|
+
@user << [:maker, @foo]
|
546
|
+
@user2 << [:faker, @foo2]
|
547
|
+
|
548
|
+
acl do
|
549
|
+
allow :maker, :faker, :of => :foo
|
550
|
+
end.
|
551
|
+
permit(@user, :foo => @foo).
|
552
|
+
forbid(@user, :foo => @foo2).
|
553
|
+
permit(@user2, :foo => @foo2).
|
554
|
+
forbid(@user2, :foo => @foo).
|
555
|
+
forbid(@user3, :foo => @foo).
|
556
|
+
forbid(@user3, :foo => @foo2).
|
557
|
+
forbid(nil)
|
558
|
+
end
|
559
|
+
|
560
|
+
it "#allow should be able to receive a role list (class roles)" do
|
561
|
+
@user << [:frooble, ThatFoo]
|
562
|
+
@user2 << [:oombigle, ThatFoo]
|
563
|
+
@user3 << :frooble
|
564
|
+
|
565
|
+
acl do
|
566
|
+
allow :frooble, :oombigle, :by => ThatFoo
|
567
|
+
end.
|
568
|
+
permit(@user).
|
569
|
+
permit(@user2).
|
570
|
+
forbid(@user3).
|
571
|
+
forbid(nil)
|
572
|
+
end
|
573
|
+
|
574
|
+
it "#deny should be able to receive a role list (global roles)" do
|
575
|
+
@user << :bzz
|
576
|
+
@user2 << :whoa
|
577
|
+
|
578
|
+
acl do
|
579
|
+
default :allow
|
580
|
+
deny :bzz, :whoa
|
581
|
+
end.forbid(@user).forbid(@user2).permit(nil).permit(@user3)
|
582
|
+
end
|
583
|
+
|
584
|
+
it "#deny should be able to receive a role list (object roles)" do
|
585
|
+
@user << [:maker, @foo]
|
586
|
+
@user2 << [:faker, @foo2]
|
587
|
+
@user3 = FakeUser.new
|
588
|
+
|
589
|
+
acl do
|
590
|
+
default :allow
|
591
|
+
deny :maker, :faker, :of => :foo
|
592
|
+
end.
|
593
|
+
forbid(@user, :foo => @foo).
|
594
|
+
permit(@user, :foo => @foo2).
|
595
|
+
forbid(@user2, :foo => @foo2).
|
596
|
+
permit(@user2, :foo => @foo).
|
597
|
+
permit(@user3, :foo => @foo).
|
598
|
+
permit(@user3, :foo => @foo2).
|
599
|
+
permit(nil)
|
600
|
+
end
|
601
|
+
|
602
|
+
it "#deny should be able to receive a role list (class roles)" do
|
603
|
+
@user << [:frooble, ThatFoo]
|
604
|
+
@user2 << [:oombigle, ThatFoo]
|
605
|
+
@user3 << :frooble
|
606
|
+
|
607
|
+
acl do
|
608
|
+
default :allow
|
609
|
+
deny :frooble, :oombigle, :by => ThatFoo
|
610
|
+
end.
|
611
|
+
forbid(@user).
|
612
|
+
forbid(@user2).
|
613
|
+
permit(@user3).
|
614
|
+
permit(nil)
|
615
|
+
end
|
616
|
+
|
617
|
+
it "should also respect :to and :except" do
|
618
|
+
class Moo; end
|
619
|
+
|
620
|
+
@user << :foo
|
621
|
+
@user2 << [:joo, @foo]
|
622
|
+
@user3 << [:qoo, Moo]
|
623
|
+
|
624
|
+
acl do
|
625
|
+
allow :foo, :boo, :to => [:index, :show]
|
626
|
+
allow :zoo, :joo, :by => :foo, :to => [:edit, :update]
|
627
|
+
allow :qoo, :woo, :of => Moo
|
628
|
+
deny :qoo, :woo, :of => Moo, :except => [:delete, :destroy]
|
629
|
+
end.
|
630
|
+
permit(@user, 'index').
|
631
|
+
permit(@user, 'show').
|
632
|
+
forbid(@user, 'edit').
|
633
|
+
permit(@user2, 'edit', :foo => @foo).
|
634
|
+
permit(@user2, 'update', :foo => @foo).
|
635
|
+
forbid(@user2, 'show', :foo => @foo).
|
636
|
+
forbid(@user2, 'show').
|
637
|
+
permit(@user3, 'delete').
|
638
|
+
permit(@user3, 'destroy').
|
639
|
+
forbid(@user3, 'edit').
|
640
|
+
forbid(@user3, 'show')
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
describe "actions block" do
|
645
|
+
it "should raise an ArgumentError when actions has no block" do
|
646
|
+
arg_err do
|
647
|
+
actions :foo, :bar
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
it "should raise an ArgumentError when actions has no arguments" do
|
652
|
+
arg_err do
|
653
|
+
actions do end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
it "should raise an ArgumentError when actions is called inside actions block" do
|
658
|
+
arg_err do
|
659
|
+
actions :foo, :bar do
|
660
|
+
actions :foo, :bar do
|
661
|
+
end
|
662
|
+
end
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
666
|
+
it "should raise an ArgumentError when default is called inside actions block" do
|
667
|
+
arg_err do
|
668
|
+
actions :foo, :bar do
|
669
|
+
default :allow
|
670
|
+
end
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
[:to, :except].each do |opt|
|
675
|
+
it "should raise an ArgumentError when allow is called with #{opt} option" do
|
676
|
+
arg_err do
|
677
|
+
actions :foo do
|
678
|
+
allow all, opt => :bar
|
679
|
+
end
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
it "should raise an ArgumentError when deny is called with #{opt} option" do
|
684
|
+
arg_err do
|
685
|
+
actions :foo do
|
686
|
+
deny all, opt => :bar
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
it "empty actions block should do nothing" do
|
693
|
+
acl do
|
694
|
+
actions :foo do
|
695
|
+
end
|
696
|
+
|
697
|
+
allow all
|
698
|
+
end.permit(nil).permit(nil, :foo)
|
699
|
+
end
|
700
|
+
|
701
|
+
it "#allow should limit its scope to specified actions" do
|
702
|
+
@user << :bee
|
703
|
+
|
704
|
+
acl do
|
705
|
+
actions :edit do
|
706
|
+
allow :bee
|
707
|
+
end
|
708
|
+
end.
|
709
|
+
permit(@user, :edit).
|
710
|
+
forbid(@user, :update)
|
711
|
+
end
|
712
|
+
|
713
|
+
it "#deny should limit its scope to specified actions" do
|
714
|
+
@user << :bee
|
715
|
+
|
716
|
+
acl do
|
717
|
+
default :allow
|
718
|
+
actions :edit do
|
719
|
+
deny :bee
|
720
|
+
end
|
721
|
+
end.
|
722
|
+
forbid(@user, :edit).
|
723
|
+
permit(@user, :update)
|
724
|
+
end
|
725
|
+
|
726
|
+
it "#allow and #deny should work together inside actions block" do
|
727
|
+
@foo = ThatFoo.new
|
728
|
+
@user << [:owner, @foo]
|
729
|
+
@user2 << :hacker
|
730
|
+
@user2 << :the_destroyer
|
731
|
+
@user3 << [:owner, @foo]
|
732
|
+
@user3 << :hacker
|
733
|
+
|
734
|
+
list = acl do
|
735
|
+
actions :show, :index do
|
736
|
+
allow all
|
737
|
+
end
|
738
|
+
|
739
|
+
actions :edit, :update do
|
740
|
+
allow :owner, :of => :object
|
741
|
+
deny :hacker
|
742
|
+
end
|
743
|
+
|
744
|
+
actions :delete, :destroy do
|
745
|
+
allow :owner, :of => :object
|
746
|
+
allow :the_destroyer
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
@all_actions = %w(show index edit update delete destroy)
|
751
|
+
|
752
|
+
permit_some(list, @user, @all_actions, :object => @foo)
|
753
|
+
permit_some(list, @user2, %w(show index delete destroy))
|
754
|
+
permit_some(list, @user3, %w(show index delete destroy), :object => @foo)
|
755
|
+
end
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|