be9-acl9 0.9.1

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