be9-acl9 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.textile +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
|