acl9 0.11.0

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