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