be9-acl9 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.textile +8 -0
- data/README.textile +12 -3
- data/Rakefile +10 -0
- data/VERSION.yml +1 -1
- data/lib/acl9/config.rb +1 -0
- data/lib/acl9/controller_extensions.rb +22 -1
- data/lib/acl9/controller_extensions/dsl_base.rb +8 -4
- data/lib/acl9/controller_extensions/generators.rb +52 -10
- data/lib/acl9/helpers.rb +2 -2
- data/lib/acl9/model_extensions.rb +82 -8
- data/lib/acl9/model_extensions/object.rb +32 -0
- data/lib/acl9/model_extensions/subject.rb +85 -17
- data/test/access_control_test.rb +144 -15
- data/test/dsl_base_test.rb +64 -62
- data/test/roles_test.rb +67 -22
- data/test/support/controllers.rb +57 -3
- data/test/support/models.rb +20 -0
- data/test/support/schema.rb +22 -0
- data/test/test_helper.rb +4 -0
- metadata +9 -8
@@ -1,16 +1,55 @@
|
|
1
1
|
module Acl9
|
2
2
|
module ModelExtensions
|
3
3
|
module Subject
|
4
|
+
##
|
5
|
+
# Role check.
|
6
|
+
#
|
7
|
+
# There is a global option, +Acl9.config[:protect_global_roles]+, which governs
|
8
|
+
# this method behavior.
|
9
|
+
#
|
10
|
+
# If protect_global_roles is +false+, an object role is automatically counted
|
11
|
+
# as global role. E.g.
|
12
|
+
#
|
13
|
+
# Acl9.config[:protect_global_roles] = false
|
14
|
+
# user.has_role!(:manager, @foo)
|
15
|
+
# user.has_role?(:manager, @foo) # => true
|
16
|
+
# user.has_role?(:manager) # => true
|
17
|
+
#
|
18
|
+
# In this case manager is anyone who "manages" at least one object.
|
19
|
+
#
|
20
|
+
# However, if protect_global_roles option set to +true+, you'll need to
|
21
|
+
# explicitly grant global role with same name.
|
22
|
+
#
|
23
|
+
# Acl9.config[:protect_global_roles] = true
|
24
|
+
# user.has_role!(:manager, @foo)
|
25
|
+
# user.has_role?(:manager) # => false
|
26
|
+
# user.has_role!(:manager)
|
27
|
+
# user.has_role?(:manager) # => true
|
28
|
+
#
|
29
|
+
# protect_global_roles option is +false+ by default as for now, but this
|
30
|
+
# may change in future!
|
31
|
+
#
|
32
|
+
# @return [Boolean] Whether +self+ has a role +role_name+ on +object+.
|
33
|
+
# @param [Symbol,String] role_name Role name
|
34
|
+
# @param [Object] object Object to query a role on
|
35
|
+
#
|
36
|
+
# @see Acl9::ModelExtensions::Object#accepts_role?
|
4
37
|
def has_role?(role_name, object = nil)
|
5
|
-
!! if object.nil?
|
6
|
-
self.
|
7
|
-
self.
|
38
|
+
!! if object.nil? && !::Acl9.config[:protect_global_roles]
|
39
|
+
self.role_objects.find_by_name(role_name.to_s) ||
|
40
|
+
self.role_objects.member?(get_role(role_name, nil))
|
8
41
|
else
|
9
42
|
role = get_role(role_name, object)
|
10
|
-
role && self.
|
43
|
+
role && self.role_objects.exists?(role.id)
|
11
44
|
end
|
12
45
|
end
|
13
46
|
|
47
|
+
##
|
48
|
+
# Add specified role on +object+ to +self+.
|
49
|
+
#
|
50
|
+
# @param [Symbol,String] role_name Role name
|
51
|
+
# @param [Object] object Object to add a role for
|
52
|
+
# @see Acl9::ModelExtensions::Object#accepts_role!
|
14
53
|
def has_role!(role_name, object = nil)
|
15
54
|
role = get_role(role_name, object)
|
16
55
|
|
@@ -21,37 +60,66 @@ module Acl9
|
|
21
60
|
else { :authorizable => object }
|
22
61
|
end.merge( { :name => role_name.to_s })
|
23
62
|
|
24
|
-
role = self._auth_role_class.create(role_attrs)
|
63
|
+
role = self._auth_role_class.create(role_attrs)
|
25
64
|
end
|
26
65
|
|
27
|
-
self.
|
66
|
+
self.role_objects << role if role && !self.role_objects.exists?(role.id)
|
28
67
|
end
|
29
68
|
|
69
|
+
##
|
70
|
+
# Free +self+ from a specified role on +object+.
|
71
|
+
#
|
72
|
+
# @param [Symbol,String] role_name Role name
|
73
|
+
# @param [Object] object Object to remove a role on
|
74
|
+
# @see Acl9::ModelExtensions::Object#accepts_no_role!
|
30
75
|
def has_no_role!(role_name, object = nil)
|
31
76
|
delete_role(get_role(role_name, object))
|
32
77
|
end
|
33
78
|
|
79
|
+
##
|
80
|
+
# Are there any roles for +self+ on +object+?
|
81
|
+
#
|
82
|
+
# @param [Object] object Object to query roles
|
83
|
+
# @return [Boolean] Returns true if +self+ has any roles on +object+.
|
84
|
+
# @see Acl9::ModelExtensions::Object#accepts_roles_by?
|
34
85
|
def has_roles_for?(object)
|
35
|
-
!!self.
|
86
|
+
!!self.role_objects.detect(&role_selecting_lambda(object))
|
36
87
|
end
|
37
88
|
|
38
89
|
alias :has_role_for? :has_roles_for?
|
39
90
|
|
91
|
+
##
|
92
|
+
# Which roles does +self+ have on +object+?
|
93
|
+
#
|
94
|
+
# @return [Array<Role>] Role instances, associated both with +self+ and +object+
|
95
|
+
# @param [Object] object Object to query roles
|
96
|
+
# @see Acl9::ModelExtensions::Object#accepted_roles_by
|
97
|
+
# @example
|
98
|
+
# user = User.find(...)
|
99
|
+
# product = Product.find(...)
|
100
|
+
#
|
101
|
+
# user.roles_for(product).map(&:name).sort #=> role names in alphabetical order
|
40
102
|
def roles_for(object)
|
41
|
-
self.
|
103
|
+
self.role_objects.select(&role_selecting_lambda(object))
|
42
104
|
end
|
43
105
|
|
106
|
+
##
|
107
|
+
# Unassign any roles on +object+ from +self+.
|
108
|
+
#
|
109
|
+
# @param [Object,nil] object Object to unassign roles for. +nil+ means unassign global roles.
|
44
110
|
def has_no_roles_for!(object = nil)
|
45
111
|
roles_for(object).each { |role| delete_role(role) }
|
46
112
|
end
|
47
113
|
|
114
|
+
##
|
115
|
+
# Unassign all roles from +self+.
|
48
116
|
def has_no_roles!
|
49
|
-
# for some reason simple
|
117
|
+
# for some reason simple
|
50
118
|
#
|
51
119
|
# self.roles.each { |role| delete_role(role) }
|
52
120
|
#
|
53
121
|
# doesn't work. seems like a bug in ActiveRecord
|
54
|
-
self.
|
122
|
+
self.role_objects.map(&:id).each do |role_id|
|
55
123
|
delete_role self._auth_role_class.find(role_id)
|
56
124
|
end
|
57
125
|
end
|
@@ -65,8 +133,8 @@ module Acl9
|
|
65
133
|
when nil
|
66
134
|
lambda { |role| role.authorizable.nil? }
|
67
135
|
else
|
68
|
-
lambda do |role|
|
69
|
-
role.authorizable_type == object.class.base_class.to_s && role.authorizable == object
|
136
|
+
lambda do |role|
|
137
|
+
role.authorizable_type == object.class.base_class.to_s && role.authorizable == object
|
70
138
|
end
|
71
139
|
end
|
72
140
|
end
|
@@ -80,20 +148,20 @@ module Acl9
|
|
80
148
|
when nil
|
81
149
|
[ 'name = ? and authorizable_type IS NULL and authorizable_id IS NULL', role_name ]
|
82
150
|
else
|
83
|
-
[
|
151
|
+
[
|
84
152
|
'name = ? and authorizable_type = ? and authorizable_id = ?',
|
85
|
-
role_name, object.class.base_class.to_s, object.id
|
153
|
+
role_name, object.class.base_class.to_s, object.id
|
86
154
|
]
|
87
155
|
end
|
88
156
|
|
89
157
|
self._auth_role_class.first :conditions => cond
|
90
158
|
end
|
91
159
|
|
92
|
-
def delete_role(role)
|
160
|
+
def delete_role(role)
|
93
161
|
if role
|
94
|
-
self.
|
162
|
+
self.role_objects.delete role
|
95
163
|
|
96
|
-
role.destroy if role.send(self.class.to_s.tableize).empty?
|
164
|
+
role.destroy if role.send(self.class.to_s.demodulize.tableize).empty?
|
97
165
|
end
|
98
166
|
end
|
99
167
|
|
data/test/access_control_test.rb
CHANGED
@@ -22,7 +22,7 @@ class Bartender
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class TheOnlyUser
|
25
|
+
class TheOnlyUser
|
26
26
|
include Singleton
|
27
27
|
|
28
28
|
def has_role?(role, subj)
|
@@ -30,6 +30,16 @@ class TheOnlyUser
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
class Beholder
|
34
|
+
def initialize(role)
|
35
|
+
@role = role.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_role?(role, obj)
|
39
|
+
role.to_s == @role
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
33
43
|
#######################################################################
|
34
44
|
|
35
45
|
module BaseTests
|
@@ -38,18 +48,18 @@ module BaseTests
|
|
38
48
|
klass.class_eval do
|
39
49
|
[:index, :show].each do |act|
|
40
50
|
it "should permit anonymous to #{act}" do
|
41
|
-
get act
|
51
|
+
get act
|
42
52
|
@response.body.should == 'OK'
|
43
53
|
end
|
44
54
|
end
|
45
55
|
|
46
56
|
[:new, :edit, :update, :delete, :destroy].each do |act|
|
47
57
|
it "should forbid anonymous to #{act}" do
|
48
|
-
get act
|
58
|
+
get act
|
49
59
|
@response.body.should == 'AccessDenied'
|
50
60
|
end
|
51
61
|
end
|
52
|
-
|
62
|
+
|
53
63
|
[:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
|
54
64
|
it "should permit admin to #{act}" do
|
55
65
|
get act, :user => Admin.new
|
@@ -66,6 +76,10 @@ module ShouldRespondToAcl
|
|
66
76
|
it "should add :acl as a method" do
|
67
77
|
@controller.should respond_to(:acl)
|
68
78
|
end
|
79
|
+
|
80
|
+
it "should_not add :acl? as a method" do
|
81
|
+
@controller.should_not respond_to(:acl?)
|
82
|
+
end
|
69
83
|
end
|
70
84
|
end
|
71
85
|
end
|
@@ -106,12 +120,12 @@ end
|
|
106
120
|
|
107
121
|
class ACLIvarsTest < ActionController::TestCase
|
108
122
|
tests ACLIvars
|
109
|
-
|
123
|
+
|
110
124
|
it "should allow owner of foo to destroy" do
|
111
125
|
delete :destroy, :user => OwnerOfFoo.new
|
112
126
|
@response.body.should == 'OK'
|
113
127
|
end
|
114
|
-
|
128
|
+
|
115
129
|
it "should allow bartender to destroy" do
|
116
130
|
delete :destroy, :user => Bartender.new
|
117
131
|
@response.body.should == 'OK'
|
@@ -125,7 +139,7 @@ class ACLSubjectMethodTest < ActionController::TestCase
|
|
125
139
|
get :index, :user => TheOnlyUser.instance
|
126
140
|
@response.body.should == 'OK'
|
127
141
|
end
|
128
|
-
|
142
|
+
|
129
143
|
it "should deny anonymous to index" do
|
130
144
|
get :index
|
131
145
|
@response.body.should == 'AccessDenied'
|
@@ -139,13 +153,39 @@ class ACLObjectsHashTest < ActionController::TestCase
|
|
139
153
|
get :allow, :user => OwnerOfFoo.new
|
140
154
|
@response.body.should == 'OK'
|
141
155
|
end
|
142
|
-
|
156
|
+
|
143
157
|
it "should return AccessDenied when not logged in" do
|
144
158
|
get :allow
|
145
159
|
@response.body.should == 'AccessDenied'
|
146
160
|
end
|
147
161
|
end
|
148
162
|
|
163
|
+
class ACLActionOverrideTest < ActionController::TestCase
|
164
|
+
tests ACLActionOverride
|
165
|
+
|
166
|
+
it "should allow index action to anonymous" do
|
167
|
+
get :check_allow, :_action => :index
|
168
|
+
@response.body.should == 'OK'
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should deny show action to anonymous" do
|
172
|
+
get :check_allow, :_action => :show
|
173
|
+
@response.body.should == 'AccessDenied'
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should deny edit action to regular user" do
|
177
|
+
get :check_allow_with_foo, :_action => :edit, :user => TheOnlyUser.instance
|
178
|
+
|
179
|
+
@response.body.should == 'AccessDenied'
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should allow edit action to owner of foo" do
|
183
|
+
get :check_allow_with_foo, :_action => :edit, :user => OwnerOfFoo.new
|
184
|
+
|
185
|
+
@response.body.should == 'OK'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
149
189
|
class ACLHelperMethodTest < ActionController::TestCase
|
150
190
|
tests ACLHelperMethod
|
151
191
|
|
@@ -153,28 +193,116 @@ class ACLHelperMethodTest < ActionController::TestCase
|
|
153
193
|
get :allow, :user => OwnerOfFoo.new
|
154
194
|
@response.body.should == 'OK'
|
155
195
|
end
|
156
|
-
|
196
|
+
|
157
197
|
it "should return AccessDenied when not logged in" do
|
158
198
|
get :allow
|
159
199
|
@response.body.should == 'AccessDenied'
|
160
200
|
end
|
161
201
|
end
|
162
202
|
|
203
|
+
#######################################################################
|
204
|
+
|
205
|
+
module ACLQueryMixin
|
206
|
+
def self.included(base)
|
207
|
+
base.class_eval do
|
208
|
+
describe "#acl_question_mark" do # describe "#acl?" doesn't work
|
209
|
+
before do
|
210
|
+
@editor = Beholder.new(:editor)
|
211
|
+
@viewer = Beholder.new(:viewer)
|
212
|
+
@owneroffoo = OwnerOfFoo.new
|
213
|
+
end
|
214
|
+
|
215
|
+
[:edit, :update, :destroy].each do |meth|
|
216
|
+
it "should return true for editor/#{meth}" do
|
217
|
+
@controller.current_user = @editor
|
218
|
+
@controller.acl?(meth).should == true
|
219
|
+
@controller.acl?(meth.to_s).should == true
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should return false for viewer/#{meth}" do
|
223
|
+
@controller.current_user = @viewer
|
224
|
+
@controller.acl?(meth).should == false
|
225
|
+
@controller.acl?(meth.to_s).should == false
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
[:index, :show].each do |meth|
|
230
|
+
it "should return false for editor/#{meth}" do
|
231
|
+
@controller.current_user = @editor
|
232
|
+
@controller.acl?(meth).should == false
|
233
|
+
@controller.acl?(meth.to_s).should == false
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should return true for viewer/#{meth}" do
|
237
|
+
@controller.current_user = @viewer
|
238
|
+
@controller.acl?(meth).should == true
|
239
|
+
@controller.acl?(meth.to_s).should == true
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should return false for editor/fooize" do
|
244
|
+
@controller.current_user = @editor
|
245
|
+
@controller.acl?(:fooize).should == false
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should return true for foo owner" do
|
249
|
+
@controller.current_user = @owneroffoo
|
250
|
+
@controller.acl?(:fooize, :foo => MyDearFoo.instance).should == true
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
class ACLQueryMethodTest < ActionController::TestCase
|
258
|
+
tests ACLQueryMethod
|
259
|
+
|
260
|
+
it "should respond to :acl?" do
|
261
|
+
@controller.should respond_to(:acl?)
|
262
|
+
end
|
263
|
+
|
264
|
+
include ACLQueryMixin
|
265
|
+
end
|
266
|
+
|
267
|
+
class ACLQueryMethodWithLambdaTest < ActionController::TestCase
|
268
|
+
tests ACLQueryMethodWithLambda
|
269
|
+
|
270
|
+
it "should respond to :acl?" do
|
271
|
+
@controller.should respond_to(:acl?)
|
272
|
+
end
|
273
|
+
|
274
|
+
include ACLQueryMixin
|
275
|
+
end
|
276
|
+
|
277
|
+
#######################################################################
|
278
|
+
|
279
|
+
class ACLNamedQueryMethodTest < ActionController::TestCase
|
280
|
+
tests ACLNamedQueryMethod
|
281
|
+
|
282
|
+
it "should respond to :allow_ay" do
|
283
|
+
@controller.should respond_to(:allow_ay)
|
284
|
+
end
|
285
|
+
|
286
|
+
include ACLQueryMixin
|
287
|
+
end
|
288
|
+
|
289
|
+
#######################################################################
|
290
|
+
|
163
291
|
class ArgumentsCheckingTest < ActiveSupport::TestCase
|
164
292
|
def arg_err(&block)
|
165
293
|
lambda do
|
166
294
|
block.call
|
167
295
|
end.should raise_error(ArgumentError)
|
168
296
|
end
|
169
|
-
|
297
|
+
|
170
298
|
it "should raise ArgumentError without a block" do
|
171
299
|
arg_err do
|
172
300
|
class FailureController < ApplicationController
|
173
|
-
access_control
|
301
|
+
access_control
|
174
302
|
end
|
175
303
|
end
|
176
304
|
end
|
177
|
-
|
305
|
+
|
178
306
|
it "should raise ArgumentError with 1st argument which is not a symbol" do
|
179
307
|
arg_err do
|
180
308
|
class FailureController < ApplicationController
|
@@ -182,7 +310,7 @@ class ArgumentsCheckingTest < ActiveSupport::TestCase
|
|
182
310
|
end
|
183
311
|
end
|
184
312
|
end
|
185
|
-
|
313
|
+
|
186
314
|
it "should raise ArgumentError with more than 1 positional argument" do
|
187
315
|
arg_err do
|
188
316
|
class FailureController < ApplicationController
|
@@ -190,7 +318,7 @@ class ArgumentsCheckingTest < ActiveSupport::TestCase
|
|
190
318
|
end
|
191
319
|
end
|
192
320
|
end
|
193
|
-
|
321
|
+
|
194
322
|
it "should raise ArgumentError with :helper => true and no method name" do
|
195
323
|
arg_err do
|
196
324
|
class FailureController < ApplicationController
|
@@ -198,7 +326,7 @@ class ArgumentsCheckingTest < ActiveSupport::TestCase
|
|
198
326
|
end
|
199
327
|
end
|
200
328
|
end
|
201
|
-
|
329
|
+
|
202
330
|
it "should raise ArgumentError with :helper => :method and a method name" do
|
203
331
|
arg_err do
|
204
332
|
class FailureController < ApplicationController
|
@@ -207,3 +335,4 @@ class ArgumentsCheckingTest < ActiveSupport::TestCase
|
|
207
335
|
end
|
208
336
|
end
|
209
337
|
end
|
338
|
+
|
data/test/dsl_base_test.rb
CHANGED
@@ -31,19 +31,19 @@ class DslTester < Acl9::Dsl::Base
|
|
31
31
|
@_objects = {}
|
32
32
|
@_current_action = nil
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def permit(user, *args)
|
36
36
|
check_allowance(user, *args).should == true
|
37
37
|
|
38
38
|
self
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def forbid(user, *args)
|
42
42
|
check_allowance(user, *args).should == false
|
43
43
|
|
44
44
|
self
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def show_code
|
48
48
|
puts "\n", allowance_expression
|
49
49
|
self
|
@@ -91,7 +91,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
91
91
|
def acl(&block)
|
92
92
|
tester = DslTester.new
|
93
93
|
tester.acl_block!(&block)
|
94
|
-
|
94
|
+
|
95
95
|
tester
|
96
96
|
end
|
97
97
|
|
@@ -99,7 +99,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
99
99
|
actions.each { |act| tester.permit(user, act, vars) }
|
100
100
|
(@all_actions - actions).each { |act| tester.forbid(user, act, vars) }
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
before do
|
104
104
|
@user = FakeUser.new
|
105
105
|
@user2 = FakeUser.new
|
@@ -111,29 +111,29 @@ class DslBaseTest < Test::Unit::TestCase
|
|
111
111
|
|
112
112
|
describe "default" do
|
113
113
|
it "should set default action to deny if none specified" do
|
114
|
-
acl do end.default_action.should == :deny
|
114
|
+
acl do end.default_action.should == :deny
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
it "should set default action to allow" do
|
118
|
-
acl do
|
118
|
+
acl do
|
119
119
|
default :allow
|
120
120
|
end.default_action.should == :allow
|
121
121
|
end
|
122
|
-
|
122
|
+
|
123
123
|
it "should set default action to deny" do
|
124
|
-
acl do
|
124
|
+
acl do
|
125
125
|
default :deny
|
126
126
|
end.default_action.should == :deny
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
it "should raise ArgumentError with unknown default_action" do
|
130
|
-
arg_err do
|
130
|
+
arg_err do
|
131
131
|
default 123
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
it "should raise ArgumentError when default is called more than once" do
|
136
|
-
arg_err do
|
136
|
+
arg_err do
|
137
137
|
default :deny
|
138
138
|
default :deny
|
139
139
|
end
|
@@ -145,7 +145,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
145
145
|
acl do
|
146
146
|
end.forbid(nil).forbid(@user)
|
147
147
|
end
|
148
|
-
|
148
|
+
|
149
149
|
it "should allow everyone with default allow" do
|
150
150
|
acl do
|
151
151
|
default :allow
|
@@ -157,7 +157,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
157
157
|
it "allow should raise an ArgumentError" do
|
158
158
|
arg_err { allow }
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
it "deny should raise an ArgumentError" do
|
162
162
|
arg_err { deny }
|
163
163
|
end
|
@@ -169,20 +169,20 @@ class DslBaseTest < Test::Unit::TestCase
|
|
169
169
|
allow nil
|
170
170
|
end.permit(nil).forbid(@user)
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
it "'allow anonymous' should allow anonymous, but not logged in" do
|
174
174
|
acl do
|
175
175
|
allow anonymous
|
176
176
|
end.permit(nil).forbid(@user)
|
177
177
|
end
|
178
|
-
|
178
|
+
|
179
179
|
it "'deny nil' should deny anonymous, but not logged in" do
|
180
180
|
acl do
|
181
181
|
default :allow
|
182
182
|
deny nil
|
183
183
|
end.forbid(nil).permit(@user)
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
it "'deny anonymous' should deny anonymous, but not logged in" do
|
187
187
|
acl do
|
188
188
|
default :allow
|
@@ -192,17 +192,19 @@ class DslBaseTest < Test::Unit::TestCase
|
|
192
192
|
end
|
193
193
|
|
194
194
|
describe "all" do
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|
206
208
|
end
|
207
209
|
end
|
208
210
|
|
@@ -214,7 +216,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
214
216
|
deny :bzz
|
215
217
|
end.permit(nil).permit(@user)
|
216
218
|
end
|
217
|
-
|
219
|
+
|
218
220
|
it "should deny when deny is matched, but allow is not" do
|
219
221
|
acl do
|
220
222
|
default :allow
|
@@ -222,7 +224,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
222
224
|
allow :blah
|
223
225
|
end.forbid(nil).forbid(@user)
|
224
226
|
end
|
225
|
-
|
227
|
+
|
226
228
|
it "should allow when allow is matched, but deny is not" do
|
227
229
|
@user << :cool
|
228
230
|
acl do
|
@@ -231,7 +233,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
231
233
|
allow :cool
|
232
234
|
end.permit(@user)
|
233
235
|
end
|
234
|
-
|
236
|
+
|
235
237
|
it "should allow both allow and deny conditions are matched" do
|
236
238
|
@user << :cool
|
237
239
|
acl do
|
@@ -239,7 +241,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
239
241
|
deny :cool
|
240
242
|
allow :cool
|
241
243
|
end.permit(@user)
|
242
|
-
|
244
|
+
|
243
245
|
acl do
|
244
246
|
default :allow
|
245
247
|
deny all
|
@@ -247,14 +249,14 @@ class DslBaseTest < Test::Unit::TestCase
|
|
247
249
|
end.permit(@user).permit(nil).permit(@user2)
|
248
250
|
end
|
249
251
|
end
|
250
|
-
|
252
|
+
|
251
253
|
describe "logged_in" do
|
252
254
|
it "'allow logged_in' should allow logged in, but not anonymous" do
|
253
255
|
acl do
|
254
256
|
allow logged_in
|
255
257
|
end.forbid(nil).permit(@user)
|
256
258
|
end
|
257
|
-
|
259
|
+
|
258
260
|
it "'allow logged_in' should deny logged in, but not anonymous" do
|
259
261
|
acl do
|
260
262
|
default :allow
|
@@ -271,7 +273,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
271
273
|
deny :bzz
|
272
274
|
end.forbid(nil).forbid(@user)
|
273
275
|
end
|
274
|
-
|
276
|
+
|
275
277
|
it "should deny when deny is matched, but allow is not" do
|
276
278
|
acl do
|
277
279
|
default :deny
|
@@ -279,7 +281,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
279
281
|
allow :blah
|
280
282
|
end.forbid(nil).forbid(@user)
|
281
283
|
end
|
282
|
-
|
284
|
+
|
283
285
|
it "should allow when allow is matched, but deny is not" do
|
284
286
|
@user << :cool
|
285
287
|
acl do
|
@@ -288,7 +290,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
288
290
|
allow :cool
|
289
291
|
end.permit(@user)
|
290
292
|
end
|
291
|
-
|
293
|
+
|
292
294
|
it "should deny both allow and deny conditions are matched" do
|
293
295
|
@user << :cool
|
294
296
|
acl do
|
@@ -296,7 +298,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
296
298
|
deny :cool
|
297
299
|
allow :cool
|
298
300
|
end.forbid(@user)
|
299
|
-
|
301
|
+
|
300
302
|
acl do
|
301
303
|
default :deny
|
302
304
|
deny all
|
@@ -311,7 +313,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
311
313
|
|
312
314
|
acl { allow :admin }.permit(@user).forbid(nil).forbid(@user2)
|
313
315
|
end
|
314
|
-
|
316
|
+
|
315
317
|
it "#allow with plural role name" do
|
316
318
|
@user << :mouse
|
317
319
|
|
@@ -333,13 +335,13 @@ class DslBaseTest < Test::Unit::TestCase
|
|
333
335
|
allow :cool
|
334
336
|
end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
|
335
337
|
end
|
336
|
-
|
338
|
+
|
337
339
|
it "#deny with role" do
|
338
340
|
@user << :foo
|
339
341
|
|
340
342
|
acl { default :allow; deny :foo }.forbid(@user).permit(nil).permit(@user2)
|
341
343
|
end
|
342
|
-
|
344
|
+
|
343
345
|
it "#deny with plural role name" do
|
344
346
|
@user << :mouse
|
345
347
|
|
@@ -394,7 +396,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
394
396
|
allow :owner, :of => ThatFoo
|
395
397
|
end.permit(@user).forbid(nil).forbid(@user2)
|
396
398
|
end
|
397
|
-
|
399
|
+
|
398
400
|
[:of, :for, :in, :on, :at, :by].each do |prep|
|
399
401
|
it "#deny with object role (:#{prep}) should check controller's ivar" do
|
400
402
|
@user << [:bastard, @foo]
|
@@ -409,7 +411,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
409
411
|
permit(nil, :foo => @foo).
|
410
412
|
permit(@user2, :foo => @foo)
|
411
413
|
end
|
412
|
-
|
414
|
+
|
413
415
|
it "#deny with invalid value for preposition :#{prep} should raise an ArgumentError" do
|
414
416
|
arg_err do
|
415
417
|
deny :her, :for => "him"
|
@@ -450,7 +452,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
450
452
|
after do
|
451
453
|
%w(index show).each { |act| @list.permit(nil, act) }
|
452
454
|
%w(edit update delete destroy).each { |act| @list.forbid(nil, act) }
|
453
|
-
|
455
|
+
|
454
456
|
%w(index show edit update).each { |act| @list.permit(@user, act) }
|
455
457
|
%w(delete destroy).each { |act| @list.forbid(@user, act) }
|
456
458
|
|
@@ -469,7 +471,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
469
471
|
allow 'trusted', :to => %w(edit update delete destroy)
|
470
472
|
end
|
471
473
|
end
|
472
|
-
|
474
|
+
|
473
475
|
it ":except should limit rule scope to all actions except specified" do
|
474
476
|
@user << :manager
|
475
477
|
@user2 << :trusted
|
@@ -500,7 +502,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
500
502
|
permit(nil, :call => OpenStruct.new(:meth => true)).
|
501
503
|
forbid(nil, :call => OpenStruct.new(:meth => false))
|
502
504
|
end
|
503
|
-
|
505
|
+
|
504
506
|
it "allow ... :unless" do
|
505
507
|
acl do
|
506
508
|
allow nil, :unless => :meth
|
@@ -508,7 +510,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
508
510
|
permit(nil, :call => OpenStruct.new(:meth => false)).
|
509
511
|
forbid(nil, :call => OpenStruct.new(:meth => true))
|
510
512
|
end
|
511
|
-
|
513
|
+
|
512
514
|
it "deny ... :if" do
|
513
515
|
acl do
|
514
516
|
default :allow
|
@@ -538,7 +540,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
538
540
|
allow :bzz, :whoa
|
539
541
|
end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
|
540
542
|
end
|
541
|
-
|
543
|
+
|
542
544
|
it "#allow should be able to receive a role list (object roles)" do
|
543
545
|
@user << [:maker, @foo]
|
544
546
|
@user2 << [:faker, @foo2]
|
@@ -554,7 +556,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
554
556
|
forbid(@user3, :foo => @foo2).
|
555
557
|
forbid(nil)
|
556
558
|
end
|
557
|
-
|
559
|
+
|
558
560
|
it "#allow should be able to receive a role list (class roles)" do
|
559
561
|
@user << [:frooble, ThatFoo]
|
560
562
|
@user2 << [:oombigle, ThatFoo]
|
@@ -568,7 +570,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
568
570
|
forbid(@user3).
|
569
571
|
forbid(nil)
|
570
572
|
end
|
571
|
-
|
573
|
+
|
572
574
|
it "#deny should be able to receive a role list (global roles)" do
|
573
575
|
@user << :bzz
|
574
576
|
@user2 << :whoa
|
@@ -578,7 +580,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
578
580
|
deny :bzz, :whoa
|
579
581
|
end.forbid(@user).forbid(@user2).permit(nil).permit(@user3)
|
580
582
|
end
|
581
|
-
|
583
|
+
|
582
584
|
it "#deny should be able to receive a role list (object roles)" do
|
583
585
|
@user << [:maker, @foo]
|
584
586
|
@user2 << [:faker, @foo2]
|
@@ -596,7 +598,7 @@ class DslBaseTest < Test::Unit::TestCase
|
|
596
598
|
permit(@user3, :foo => @foo2).
|
597
599
|
permit(nil)
|
598
600
|
end
|
599
|
-
|
601
|
+
|
600
602
|
it "#deny should be able to receive a role list (class roles)" do
|
601
603
|
@user << [:frooble, ThatFoo]
|
602
604
|
@user2 << [:oombigle, ThatFoo]
|
@@ -645,25 +647,25 @@ class DslBaseTest < Test::Unit::TestCase
|
|
645
647
|
actions :foo, :bar
|
646
648
|
end
|
647
649
|
end
|
648
|
-
|
650
|
+
|
649
651
|
it "should raise an ArgumentError when actions has no arguments" do
|
650
652
|
arg_err do
|
651
653
|
actions do end
|
652
654
|
end
|
653
655
|
end
|
654
|
-
|
656
|
+
|
655
657
|
it "should raise an ArgumentError when actions is called inside actions block" do
|
656
658
|
arg_err do
|
657
|
-
actions :foo, :bar do
|
659
|
+
actions :foo, :bar do
|
658
660
|
actions :foo, :bar do
|
659
661
|
end
|
660
662
|
end
|
661
663
|
end
|
662
664
|
end
|
663
|
-
|
665
|
+
|
664
666
|
it "should raise an ArgumentError when default is called inside actions block" do
|
665
667
|
arg_err do
|
666
|
-
actions :foo, :bar do
|
668
|
+
actions :foo, :bar do
|
667
669
|
default :allow
|
668
670
|
end
|
669
671
|
end
|
@@ -672,15 +674,15 @@ class DslBaseTest < Test::Unit::TestCase
|
|
672
674
|
[:to, :except].each do |opt|
|
673
675
|
it "should raise an ArgumentError when allow is called with #{opt} option" do
|
674
676
|
arg_err do
|
675
|
-
actions :foo do
|
677
|
+
actions :foo do
|
676
678
|
allow all, opt => :bar
|
677
679
|
end
|
678
680
|
end
|
679
681
|
end
|
680
|
-
|
682
|
+
|
681
683
|
it "should raise an ArgumentError when deny is called with #{opt} option" do
|
682
684
|
arg_err do
|
683
|
-
actions :foo do
|
685
|
+
actions :foo do
|
684
686
|
deny all, opt => :bar
|
685
687
|
end
|
686
688
|
end
|