zuul 0.1.1 → 0.2.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/lib/generators/zuul/orm_helpers.rb +21 -0
- data/lib/generators/zuul/permission_generator.rb +57 -0
- data/lib/generators/zuul/permission_role_generator.rb +40 -0
- data/lib/generators/zuul/permission_subject_generator.rb +40 -0
- data/lib/generators/zuul/role_generator.rb +58 -0
- data/lib/generators/zuul/role_subject_generator.rb +40 -0
- data/lib/generators/zuul/subject_generator.rb +39 -0
- data/lib/generators/zuul/templates/permission.rb +18 -0
- data/lib/generators/zuul/templates/permission_existing.rb +25 -0
- data/lib/generators/zuul/templates/permission_role.rb +17 -0
- data/lib/generators/zuul/templates/permission_role_existing.rb +24 -0
- data/lib/generators/zuul/templates/permission_subject.rb +17 -0
- data/lib/generators/zuul/templates/permission_subject_existing.rb +24 -0
- data/lib/generators/zuul/templates/role.rb +20 -0
- data/lib/generators/zuul/templates/role_existing.rb +27 -0
- data/lib/generators/zuul/templates/role_subject.rb +17 -0
- data/lib/generators/zuul/templates/role_subject_existing.rb +24 -0
- data/lib/tasks/zuul.rake +56 -0
- data/lib/zuul.rb +14 -5
- data/lib/zuul/action_controller.rb +108 -0
- data/lib/zuul/action_controller/dsl.rb +384 -0
- data/lib/zuul/action_controller/evaluators.rb +60 -0
- data/lib/zuul/active_record.rb +338 -0
- data/lib/zuul/active_record/context.rb +38 -0
- data/lib/zuul/active_record/permission.rb +31 -0
- data/lib/zuul/active_record/permission_role.rb +29 -0
- data/lib/zuul/active_record/permission_subject.rb +29 -0
- data/lib/zuul/active_record/role.rb +117 -0
- data/lib/zuul/active_record/role_subject.rb +29 -0
- data/lib/zuul/active_record/scope.rb +71 -0
- data/lib/zuul/active_record/subject.rb +239 -0
- data/lib/zuul/configuration.rb +149 -0
- data/lib/zuul/context.rb +53 -0
- data/lib/zuul/exceptions.rb +3 -0
- data/lib/zuul/exceptions/access_denied.rb +9 -0
- data/lib/zuul/exceptions/invalid_context.rb +9 -0
- data/lib/zuul/exceptions/undefined_scope.rb +9 -0
- data/lib/zuul/railtie.rb +5 -0
- data/lib/zuul/version.rb +3 -0
- data/lib/zuul_viz.rb +195 -0
- data/spec/db/schema.rb +172 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/capture_stdout.rb +12 -0
- data/spec/support/models.rb +167 -0
- data/spec/zuul/active_record/context_spec.rb +55 -0
- data/spec/zuul/active_record/permission_role_spec.rb +84 -0
- data/spec/zuul/active_record/permission_spec.rb +174 -0
- data/spec/zuul/active_record/permission_subject_spec.rb +84 -0
- data/spec/zuul/active_record/role_spec.rb +694 -0
- data/spec/zuul/active_record/role_subject_spec.rb +84 -0
- data/spec/zuul/active_record/scope_spec.rb +75 -0
- data/spec/zuul/active_record/subject_spec.rb +1186 -0
- data/spec/zuul/active_record_spec.rb +624 -0
- data/spec/zuul/configuration_spec.rb +254 -0
- data/spec/zuul/context_spec.rb +128 -0
- data/spec/zuul_spec.rb +15 -0
- metadata +181 -70
- data/.document +0 -5
- data/.gitignore +0 -23
- data/LICENSE +0 -20
- data/README.rdoc +0 -65
- data/Rakefile +0 -54
- data/VERSION +0 -1
- data/lib/zuul/restrict_access.rb +0 -104
- data/lib/zuul/valid_roles.rb +0 -37
- data/spec/rails_root/app/controllers/application_controller.rb +0 -2
- data/spec/rails_root/app/models/user.rb +0 -8
- data/spec/rails_root/config/boot.rb +0 -110
- data/spec/rails_root/config/database.yml +0 -5
- data/spec/rails_root/config/environment.rb +0 -7
- data/spec/rails_root/config/environments/test.rb +0 -7
- data/spec/rails_root/config/initializers/session_store.rb +0 -15
- data/spec/rails_root/config/routes.rb +0 -4
- data/spec/rails_root/db/test.sqlite3 +0 -0
- data/spec/rails_root/log/test.log +0 -5388
- data/spec/rails_root/spec/controllers/require_user_spec.rb +0 -138
- data/spec/rails_root/spec/controllers/restrict_access_spec.rb +0 -64
- data/spec/rails_root/spec/models/user_spec.rb +0 -37
- data/spec/rails_root/spec/spec_helper.rb +0 -34
- data/zuul.gemspec +0 -78
@@ -0,0 +1,624 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Zuul::ActiveRecord" do
|
4
|
+
|
5
|
+
def prep_dummy
|
6
|
+
Dummy.send :include, Zuul::ActiveRecord
|
7
|
+
Dummy.send :instance_variable_set, :@auth_config, Zuul::Configuration.new
|
8
|
+
Dummy.send :instance_variable_set, :@auth_scopes, {:default => Zuul::ActiveRecord::Scope.new(Zuul::Configuration.new)}
|
9
|
+
Dummy.send :include, Zuul::ActiveRecord::AuthorizationMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should extend ActiveRecord::Base with Zuul::ActiveRecord" do
|
13
|
+
ActiveRecord::Base.ancestors.include?(Zuul::ActiveRecord).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should provide the acts_as_authorization_* and acts_as_authorization_*? methods" do
|
17
|
+
[:subject, :role, :permission, :context].each do |type|
|
18
|
+
ActiveRecord::Base.respond_to?("acts_as_authorization_#{type.to_s}").should be_true
|
19
|
+
ActiveRecord::Base.respond_to?("acts_as_authorization_#{type.to_s}?").should be_true
|
20
|
+
Dummy.new.respond_to?("acts_as_authorization_#{type.to_s}").should be_false
|
21
|
+
Dummy.new.respond_to?("acts_as_authorization_#{type.to_s}?").should be_true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "acts_as_authorization_*" do
|
26
|
+
it "should extend the model with Zuul::ActiveRecord::AuthorizationMethods" do
|
27
|
+
User.acts_as_authorization_subject
|
28
|
+
Role.acts_as_authorization_role
|
29
|
+
Permission.acts_as_authorization_permission
|
30
|
+
Context.acts_as_authorization_context
|
31
|
+
[User, Role, Permission, Context].each do |model|
|
32
|
+
model.ancestors.include?(Zuul::ActiveRecord::AuthorizationMethods).should be_true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# TODO maybe move these into 4 different specs for each method?
|
37
|
+
it "should allow passing class arguments to be used with reflections" do
|
38
|
+
Soldier.acts_as_authorization_subject :role_class => Rank, :permission_class => Skill
|
39
|
+
Soldier.auth_scope.role_class.should == Rank
|
40
|
+
Soldier.auth_scope.permission_class.should == Skill
|
41
|
+
|
42
|
+
Rank.acts_as_authorization_role :subject_class => Soldier, :permission_class => Skill
|
43
|
+
Rank.auth_scope.subject_class.should == Soldier
|
44
|
+
Rank.auth_scope.permission_class.should == Skill
|
45
|
+
|
46
|
+
Skill.acts_as_authorization_permission :subject_class => Soldier, :role_class => Rank
|
47
|
+
Skill.auth_scope.subject_class.should == Soldier
|
48
|
+
Skill.auth_scope.role_class.should == Rank
|
49
|
+
|
50
|
+
Weapon.acts_as_authorization_context :permission_class => Skill
|
51
|
+
Weapon.auth_scope.permission_class.should == Skill
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should allow class arguments to be provided as classes, strings or symbols" do
|
55
|
+
Soldier.acts_as_authorization_subject :role_class => Rank, :permission_class => "Skill"
|
56
|
+
Soldier.auth_scope.role_class.should == Rank
|
57
|
+
Soldier.auth_scope.permission_class.should == Skill
|
58
|
+
Rank.acts_as_authorization_role :subject_class => :soldier, :permission_class => "skill"
|
59
|
+
Rank.auth_scope.subject_class.should == Soldier
|
60
|
+
Rank.auth_scope.permission_class.should == Skill
|
61
|
+
Skill.acts_as_authorization_permission :subject_class => Soldier, :role_class => :Rank
|
62
|
+
Skill.auth_scope.subject_class.should == Soldier
|
63
|
+
Skill.auth_scope.role_class.should == Rank
|
64
|
+
Weapon.acts_as_authorization_context :permission_class => Skill
|
65
|
+
Weapon.auth_scope.permission_class.should == Skill
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should allow using namespaced classes" do
|
69
|
+
ZuulModels::User.acts_as_authorization_subject :role_class => ZuulModels::Role, :permission_class => "ZuulModels::Permission"
|
70
|
+
ZuulModels::User.auth_scope.role_class.should == ZuulModels::Role
|
71
|
+
ZuulModels::User.auth_scope.permission_class.should == ZuulModels::Permission
|
72
|
+
ZuulModels::User.auth_scope.role_subject_class.should == ZuulModels::RoleUser
|
73
|
+
ZuulModels::User.auth_scope.permission_subject_class.should == ZuulModels::PermissionUser
|
74
|
+
ZuulModels::User.auth_scope.permission_role_class.should == ZuulModels::PermissionRole
|
75
|
+
|
76
|
+
ZuulModels::Role.acts_as_authorization_role :subject_class => ZuulModels::User, :permission_class => ZuulModels::Permission
|
77
|
+
ZuulModels::Role.auth_scope.subject_class.should == ZuulModels::User
|
78
|
+
ZuulModels::Role.auth_scope.permission_class.should == ZuulModels::Permission
|
79
|
+
ZuulModels::Role.auth_scope.role_subject_class.should == ZuulModels::RoleUser
|
80
|
+
ZuulModels::Role.auth_scope.permission_subject_class.should == ZuulModels::PermissionUser
|
81
|
+
ZuulModels::Role.auth_scope.permission_role_class.should == ZuulModels::PermissionRole
|
82
|
+
|
83
|
+
ZuulModels::Permission.acts_as_authorization_permission :subject_class => "ZuulModels::User", :role_class => ZuulModels::Role
|
84
|
+
ZuulModels::Permission.auth_scope.subject_class.should == ZuulModels::User
|
85
|
+
ZuulModels::Permission.auth_scope.role_class.should == ZuulModels::Role
|
86
|
+
ZuulModels::Permission.auth_scope.role_subject_class.should == ZuulModels::RoleUser
|
87
|
+
ZuulModels::Permission.auth_scope.permission_subject_class.should == ZuulModels::PermissionUser
|
88
|
+
ZuulModels::Permission.auth_scope.permission_role_class.should == ZuulModels::PermissionRole
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "acts_as_authorization_*?" do
|
94
|
+
it "should return false by default" do
|
95
|
+
[User, Role, Permission, Context].each do |model|
|
96
|
+
[:subject, :role, :permission, :context].each do |type|
|
97
|
+
model.send("acts_as_authorization_#{type.to_s}?").should be_false
|
98
|
+
model.new.send("acts_as_authorization_#{type.to_s}?").should be_false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return true if the model acts_as_authorization_*" do
|
104
|
+
User.acts_as_authorization_subject
|
105
|
+
User.acts_as_authorization_subject?.should be_true
|
106
|
+
User.new.acts_as_authorization_subject?.should be_true
|
107
|
+
|
108
|
+
Role.acts_as_authorization_role
|
109
|
+
Role.acts_as_authorization_role?.should be_true
|
110
|
+
Role.new.acts_as_authorization_role?.should be_true
|
111
|
+
|
112
|
+
Permission.acts_as_authorization_permission
|
113
|
+
Permission.acts_as_authorization_permission?.should be_true
|
114
|
+
Permission.new.acts_as_authorization_permission?.should be_true
|
115
|
+
|
116
|
+
Context.acts_as_authorization_context
|
117
|
+
Context.acts_as_authorization_context?.should be_true
|
118
|
+
Context.new.acts_as_authorization_context?.should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should return the same value from instances and their classes" do
|
122
|
+
User.acts_as_authorization_subject
|
123
|
+
Role.acts_as_authorization_role
|
124
|
+
Permission.acts_as_authorization_permission
|
125
|
+
Context.acts_as_authorization_context
|
126
|
+
[User, Role, Permission, Context].each do |model|
|
127
|
+
[:subject, :role, :permission, :context].each do |type|
|
128
|
+
model.new.send("acts_as_authorization_#{type.to_s}?").should == model.send("acts_as_authorization_#{type.to_s}?")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "acts_as_authorization_subject" do
|
135
|
+
it "should extend the model with Zuul::ActiveRecord::Subject" do
|
136
|
+
User.acts_as_authorization_subject
|
137
|
+
User.ancestors.include?(Zuul::ActiveRecord::Subject).should be_true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should extend the model with Zuul::ActiveRecord::Subject:RoleMethods" do
|
141
|
+
User.acts_as_authorization_subject
|
142
|
+
User.ancestors.include?(Zuul::ActiveRecord::Subject::RoleMethods).should be_true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should extend the model with Zuul::ActiveRecord::Subject:PermissionMethods if permissions enabled" do
|
146
|
+
User.acts_as_authorization_subject
|
147
|
+
User.ancestors.include?(Zuul::ActiveRecord::Subject::PermissionMethods).should be_true
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should not extend the model with Zuul::ActiveRecord::Subject:PermissionMethods if permissions disabled" do
|
151
|
+
User.acts_as_authorization_subject :with_permissions => false
|
152
|
+
User.ancestors.include?(Zuul::ActiveRecord::Subject::PermissionMethods).should be_false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "acts_as_authorization_role" do
|
157
|
+
it "should extend the model with Zuul::ActiveRecord::Role" do
|
158
|
+
Role.acts_as_authorization_role
|
159
|
+
Role.ancestors.include?(Zuul::ActiveRecord::Role).should be_true
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should extend the model with Zuul::ActiveRecord::ContextMethods" do
|
163
|
+
Role.acts_as_authorization_role
|
164
|
+
Role.ancestors.include?(Zuul::ActiveRecord::ContextMethods).should be_true
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should extend the model with Zuul::ActiveRecord::Role::PermissionMethods if permissions enabled" do
|
168
|
+
Role.acts_as_authorization_role
|
169
|
+
Role.ancestors.include?(Zuul::ActiveRecord::Role::PermissionMethods).should be_true
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should not extend the model with Zuul::ActiveRecord::Role::PermissionMethods if permissions disabled" do
|
173
|
+
Role.acts_as_authorization_role :with_permissions => false
|
174
|
+
Role.ancestors.include?(Zuul::ActiveRecord::Role::PermissionMethods).should be_false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "acts_as_authorization_permission" do
|
179
|
+
it "should extend the model with Zuul::ActiveRecord::Permission" do
|
180
|
+
Permission.acts_as_authorization_permission
|
181
|
+
Permission.ancestors.include?(Zuul::ActiveRecord::Permission).should be_true
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should extend the model with Zuul::ActiveRecord::ContextMethods" do
|
185
|
+
Permission.acts_as_authorization_permission
|
186
|
+
Permission.ancestors.include?(Zuul::ActiveRecord::ContextMethods).should be_true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "acts_as_authorization_context" do
|
191
|
+
it "should extend the model with Zuul::ActiveRecord::Context" do
|
192
|
+
Context.acts_as_authorization_context
|
193
|
+
Context.ancestors.include?(Zuul::ActiveRecord::Context).should be_true
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "AuthorizationMethods" do
|
198
|
+
describe "auth_scope" do
|
199
|
+
before(:each) do
|
200
|
+
Role.acts_as_authorization_role
|
201
|
+
Permission.acts_as_authorization_permission
|
202
|
+
User.acts_as_authorization_subject
|
203
|
+
Level.acts_as_authorization_role :permission_class => :ability
|
204
|
+
Ability.acts_as_authorization_permission :role_class => :level
|
205
|
+
User.acts_as_authorization_subject :scope => :character, :role_class => :level, :permission_class => :ability
|
206
|
+
end
|
207
|
+
|
208
|
+
context "class method" do
|
209
|
+
it "should return the requested scope" do
|
210
|
+
User.auth_scope.name.should == :default
|
211
|
+
User.auth_scope(:character).name.should == :character
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should raise an exception if the scope doesn't exist" do
|
215
|
+
expect { User.auth_scope(:noscope) }.to raise_exception(Zuul::Exceptions::UndefinedScope)
|
216
|
+
end
|
217
|
+
|
218
|
+
context "when calling a method" do
|
219
|
+
it "should allow calling a method within the requested scope" do
|
220
|
+
User.instance_eval do
|
221
|
+
def scope_test_method
|
222
|
+
role_class_name
|
223
|
+
end
|
224
|
+
end
|
225
|
+
User.auth_scope(:character, :scope_test_method).should == User.auth_scope(:character).role_class_name
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should allow calling a method with arguments within the requested scope" do
|
229
|
+
suffix = rand(100)*rand(100)
|
230
|
+
User.instance_eval do
|
231
|
+
def scope_test_method(suf)
|
232
|
+
"#{role_class_name}_#{suf}"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
User.auth_scope(:character, :scope_test_method, suffix).should == "#{User.auth_scope(:character).role_class_name}_#{suffix}"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "when passing a block" do
|
240
|
+
it "should allow executing a block within the requested scope" do
|
241
|
+
User.auth_scope(:character) do
|
242
|
+
role_class_name
|
243
|
+
end.should == User.auth_scope(:character).role_class_name
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should allow executing a block with arguments within the requested scope" do
|
247
|
+
suffix = rand(100)*rand(100)
|
248
|
+
User.auth_scope(:character, suffix) do |suf|
|
249
|
+
"#{role_class_name}_#{suf}"
|
250
|
+
end.should == "#{User.auth_scope(:character).role_class_name}_#{suffix}"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "instance method" do
|
256
|
+
before(:each) do
|
257
|
+
@user = User.create(:name => "Tester")
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should return the requested scope" do
|
261
|
+
@user.auth_scope.name.should == :default
|
262
|
+
@user.auth_scope(:character).name.should == :character
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should raise an exception if the scope doesn't exist" do
|
266
|
+
expect { @user.auth_scope(:noscope) }.to raise_exception(Zuul::Exceptions::UndefinedScope)
|
267
|
+
end
|
268
|
+
|
269
|
+
context "when calling a method" do
|
270
|
+
it "should allow calling a method within the requested scope" do
|
271
|
+
@user.instance_eval do
|
272
|
+
def scope_test_method
|
273
|
+
role_class_name
|
274
|
+
end
|
275
|
+
end
|
276
|
+
@user.auth_scope(:character, :scope_test_method).should == @user.auth_scope(:character).role_class_name
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should allow calling a method with arguments within the requested scope" do
|
280
|
+
suffix = rand(100)*rand(100)
|
281
|
+
@user.instance_eval do
|
282
|
+
def scope_test_method(suf)
|
283
|
+
"#{role_class_name}_#{suf}"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
@user.auth_scope(:character, :scope_test_method, suffix).should == "#{@user.auth_scope(:character).role_class_name}_#{suffix}"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
context "when passing a block" do
|
291
|
+
it "should allow executing a block within the requested scope" do
|
292
|
+
@user.auth_scope(:character) do
|
293
|
+
role_class_name
|
294
|
+
end.should == @user.auth_scope(:character).role_class_name
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should allow executing a block with arguments within the requested scope" do
|
298
|
+
suffix = rand(100)*rand(100)
|
299
|
+
@user.auth_scope(:character, suffix) do |suf|
|
300
|
+
"#{role_class_name}_#{suf}"
|
301
|
+
end.should == "#{@user.auth_scope(:character).role_class_name}_#{suffix}"
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "target_role" do
|
308
|
+
before(:each) do
|
309
|
+
prep_dummy
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should require a role object or slug and a context" do
|
313
|
+
expect { Dummy.new.target_role }.to raise_exception
|
314
|
+
expect { Dummy.new.target_role(:role) }.to raise_exception
|
315
|
+
expect { Dummy.new.target_role(:role, nil) }.to_not raise_exception
|
316
|
+
end
|
317
|
+
|
318
|
+
it "should accept a role object" do
|
319
|
+
expect { Dummy.new.target_role(Role.new, nil) }.to_not raise_exception
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should accept a string or symbol" do
|
323
|
+
expect { Dummy.new.target_role(:role, nil) }.to_not raise_exception
|
324
|
+
expect { Dummy.new.target_role('role', nil) }.to_not raise_exception
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should allow forcing context" do
|
328
|
+
expect { Dummy.new.target_role(:role, nil, true) }.to_not raise_exception
|
329
|
+
expect { Dummy.new.target_role('role', nil, false) }.to_not raise_exception
|
330
|
+
end
|
331
|
+
|
332
|
+
context "when looking up a role" do
|
333
|
+
it "should just return the role object if one is passed" do
|
334
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
335
|
+
Dummy.new.target_role(role, nil).should === role
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should use the defined role_class for the lookup" do
|
339
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
340
|
+
Dummy.new.target_role(:admin, nil).should be_an_instance_of(Role)
|
341
|
+
# TODO add another example that uses different role class
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should use the provided slug for the lookup" do
|
345
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
346
|
+
Dummy.new.target_role(:admin, nil).slug.should == 'admin'
|
347
|
+
Dummy.new.target_role('admin', nil).slug.should == 'admin'
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should normalize symbols and strings to lowercase and underscored" do
|
351
|
+
role = Role.create(:name => 'My Cool Role', :slug => 'my_cool_role', :level => 40)
|
352
|
+
Dummy.new.target_role('MyCoolRole', nil).should == role
|
353
|
+
Dummy.new.target_role(:MyCoolRole, nil).should == role
|
354
|
+
end
|
355
|
+
|
356
|
+
context "within a context" do
|
357
|
+
it "should go up the context chain to find roles" do
|
358
|
+
context = Context.create(:name => "Test Context")
|
359
|
+
nil_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
360
|
+
Dummy.new.target_role(:admin, nil).should == nil_role
|
361
|
+
Dummy.new.target_role(:admin, Context).should == nil_role
|
362
|
+
Dummy.new.target_role(:admin, context).should == nil_role
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should use the closest contextual match" do
|
366
|
+
context = Context.create(:name => "Test Context")
|
367
|
+
|
368
|
+
nil_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
369
|
+
Dummy.new.target_role(:admin, nil).should == nil_role
|
370
|
+
Dummy.new.target_role(:admin, Context).should == nil_role
|
371
|
+
Dummy.new.target_role(:admin, context).should == nil_role
|
372
|
+
|
373
|
+
class_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context')
|
374
|
+
Dummy.new.target_role(:admin, nil).should == nil_role
|
375
|
+
Dummy.new.target_role(:admin, Context).should == class_role
|
376
|
+
Dummy.new.target_role(:admin, context).should == class_role
|
377
|
+
|
378
|
+
inst_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context', :context_id => context.id)
|
379
|
+
Dummy.new.target_role(:admin, nil).should == nil_role
|
380
|
+
Dummy.new.target_role(:admin, Context).should == class_role
|
381
|
+
Dummy.new.target_role(:admin, context).should == inst_role
|
382
|
+
end
|
383
|
+
|
384
|
+
context "when forcing the context" do
|
385
|
+
it "should not go up the context chain" do
|
386
|
+
context = Context.create(:name => "Test Context")
|
387
|
+
|
388
|
+
nil_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
389
|
+
Dummy.new.target_role(:admin, nil, true).should == nil_role
|
390
|
+
Dummy.new.target_role(:admin, Context, true).should be_nil
|
391
|
+
Dummy.new.target_role(:admin, context, true).should be_nil
|
392
|
+
|
393
|
+
class_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context')
|
394
|
+
Dummy.new.target_role(:admin, nil, true).should == nil_role
|
395
|
+
Dummy.new.target_role(:admin, Context, true).should == class_role
|
396
|
+
Dummy.new.target_role(:admin, context, true).should be_nil
|
397
|
+
|
398
|
+
inst_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context', :context_id => context.id)
|
399
|
+
Dummy.new.target_role(:admin, nil, true).should == nil_role
|
400
|
+
Dummy.new.target_role(:admin, Context, true).should == class_role
|
401
|
+
Dummy.new.target_role(:admin, context, true).should == inst_role
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
describe "target_permission" do
|
409
|
+
before(:each) do
|
410
|
+
prep_dummy
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should require a permission object or slug and a context" do
|
414
|
+
expect { Dummy.new.target_permission }.to raise_exception
|
415
|
+
expect { Dummy.new.target_permission(:permission) }.to raise_exception
|
416
|
+
expect { Dummy.new.target_permission(:permission, nil) }.to_not raise_exception
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should accept a permission object" do
|
420
|
+
expect { Dummy.new.target_permission(Permission.new, nil) }.to_not raise_exception
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should accept a string or symbol" do
|
424
|
+
expect { Dummy.new.target_permission(:permission, nil) }.to_not raise_exception
|
425
|
+
expect { Dummy.new.target_permission('permission', nil) }.to_not raise_exception
|
426
|
+
end
|
427
|
+
|
428
|
+
it "should allow forcing context" do
|
429
|
+
expect { Dummy.new.target_permission(:permission, nil, true) }.to_not raise_exception
|
430
|
+
expect { Dummy.new.target_permission('permission', nil, false) }.to_not raise_exception
|
431
|
+
end
|
432
|
+
|
433
|
+
context "when looking up a permission" do
|
434
|
+
it "should just return the permission object if one is passed" do
|
435
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
436
|
+
Dummy.new.target_permission(permission, nil).should === permission
|
437
|
+
end
|
438
|
+
|
439
|
+
it "should use the defined permission_class for the lookup" do
|
440
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
441
|
+
Dummy.new.target_permission(:do_something, nil).should be_an_instance_of(Permission)
|
442
|
+
# TODO add another example that uses different permission class
|
443
|
+
end
|
444
|
+
|
445
|
+
it "should use the provided slug for the lookup" do
|
446
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
447
|
+
Dummy.new.target_permission(:do_something, nil).slug.should == 'do_something'
|
448
|
+
Dummy.new.target_permission('do_something', nil).slug.should == 'do_something'
|
449
|
+
end
|
450
|
+
|
451
|
+
it "should normalize symbols and strings to lowercase and underscored" do
|
452
|
+
permission = Permission.create(:name => 'My Cool Permission', :slug => 'my_cool_permission')
|
453
|
+
Dummy.new.target_permission('MyCoolPermission', nil).should == permission
|
454
|
+
Dummy.new.target_permission(:MyCoolPermission, nil).should == permission
|
455
|
+
end
|
456
|
+
|
457
|
+
context "within a context" do
|
458
|
+
it "should go up the context chain to find permissions" do
|
459
|
+
context = Context.create(:name => "Test Context")
|
460
|
+
nil_permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
461
|
+
Dummy.new.target_permission(:do_something, nil).should == nil_permission
|
462
|
+
Dummy.new.target_permission(:do_something, Context).should == nil_permission
|
463
|
+
Dummy.new.target_permission(:do_something, context).should == nil_permission
|
464
|
+
end
|
465
|
+
|
466
|
+
it "should use the closest contextual match" do
|
467
|
+
context = Context.create(:name => "Test Context")
|
468
|
+
|
469
|
+
nil_permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
470
|
+
Dummy.new.target_permission(:do_something, nil).should == nil_permission
|
471
|
+
Dummy.new.target_permission(:do_something, Context).should == nil_permission
|
472
|
+
Dummy.new.target_permission(:do_something, context).should == nil_permission
|
473
|
+
|
474
|
+
class_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context')
|
475
|
+
Dummy.new.target_permission(:do_something, nil).should == nil_permission
|
476
|
+
Dummy.new.target_permission(:do_something, Context).should == class_permission
|
477
|
+
Dummy.new.target_permission(:do_something, context).should == class_permission
|
478
|
+
|
479
|
+
inst_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context', :context_id => context.id)
|
480
|
+
Dummy.new.target_permission(:do_something, nil).should == nil_permission
|
481
|
+
Dummy.new.target_permission(:do_something, Context).should == class_permission
|
482
|
+
Dummy.new.target_permission(:do_something, context).should == inst_permission
|
483
|
+
end
|
484
|
+
|
485
|
+
context "when forcing the context" do
|
486
|
+
it "should not go up the context chain" do
|
487
|
+
context = Context.create(:name => "Test Context")
|
488
|
+
|
489
|
+
nil_permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
490
|
+
Dummy.new.target_permission(:do_something, nil, true).should == nil_permission
|
491
|
+
Dummy.new.target_permission(:do_something, Context, true).should be_nil
|
492
|
+
Dummy.new.target_permission(:do_something, context, true).should be_nil
|
493
|
+
|
494
|
+
class_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context')
|
495
|
+
Dummy.new.target_permission(:do_something, nil, true).should == nil_permission
|
496
|
+
Dummy.new.target_permission(:do_something, Context, true).should == class_permission
|
497
|
+
Dummy.new.target_permission(:do_something, context, true).should be_nil
|
498
|
+
|
499
|
+
inst_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context', :context_id => context.id)
|
500
|
+
Dummy.new.target_permission(:do_something, nil, true).should == nil_permission
|
501
|
+
Dummy.new.target_permission(:do_something, Context, true).should == class_permission
|
502
|
+
Dummy.new.target_permission(:do_something, context, true).should == inst_permission
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
describe "verify_target_context" do
|
510
|
+
before(:each) do
|
511
|
+
Role.acts_as_authorization_role # this is to enable Role#context, can remove/rework this once those context methods are broken out
|
512
|
+
Permission.acts_as_authorization_permission # this is to enable Permission#context, can remove/rework this once those context methods are broken out
|
513
|
+
prep_dummy
|
514
|
+
end
|
515
|
+
|
516
|
+
it "should require a target role or permission and a context" do
|
517
|
+
expect { Dummy.new.verify_target_context }.to raise_exception
|
518
|
+
expect { Dummy.new.verify_target_context(nil) }.to raise_exception
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should accept a role or a permission as the target" do
|
522
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
523
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
524
|
+
Dummy.new.verify_target_context(role, nil).should be_true
|
525
|
+
Dummy.new.verify_target_context(permission, nil).should be_true
|
526
|
+
end
|
527
|
+
|
528
|
+
it "should return false if a nil target is provided" do
|
529
|
+
Dummy.new.verify_target_context(nil, nil).should be_false
|
530
|
+
end
|
531
|
+
|
532
|
+
it "should allow forcing context" do
|
533
|
+
expect { Dummy.new.verify_target_context(nil, nil, true) }.to_not raise_exception
|
534
|
+
end
|
535
|
+
|
536
|
+
context "when not forcing context" do
|
537
|
+
it "should allow nil context targets to be used within any other context" do
|
538
|
+
context = Context.create(:name => "Test Context")
|
539
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
540
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
541
|
+
Dummy.new.verify_target_context(role, nil).should be_true
|
542
|
+
Dummy.new.verify_target_context(role, Context).should be_true
|
543
|
+
Dummy.new.verify_target_context(role, context).should be_true
|
544
|
+
Dummy.new.verify_target_context(permission, nil).should be_true
|
545
|
+
Dummy.new.verify_target_context(permission, Context).should be_true
|
546
|
+
Dummy.new.verify_target_context(permission, context).should be_true
|
547
|
+
end
|
548
|
+
|
549
|
+
it "should allow class context targets to be used within the context of their class or any instances of their class" do
|
550
|
+
context = Context.create(:name => "Test Context")
|
551
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context')
|
552
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context')
|
553
|
+
Dummy.new.verify_target_context(role, Context).should be_true
|
554
|
+
Dummy.new.verify_target_context(role, context).should be_true
|
555
|
+
Dummy.new.verify_target_context(permission, Context).should be_true
|
556
|
+
Dummy.new.verify_target_context(permission, context).should be_true
|
557
|
+
end
|
558
|
+
|
559
|
+
it "should allow instance targets to be used within their own instance context" do
|
560
|
+
context = Context.create(:name => "Test Context")
|
561
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context', :context_id => context.id)
|
562
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context', :context_id => context.id)
|
563
|
+
Dummy.new.verify_target_context(role, context).should be_true
|
564
|
+
Dummy.new.verify_target_context(permission, context).should be_true
|
565
|
+
end
|
566
|
+
|
567
|
+
it "should not allow class context targets to be used within any other class or nil contexts" do
|
568
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context')
|
569
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context')
|
570
|
+
Dummy.new.verify_target_context(role, nil).should be_false
|
571
|
+
Dummy.new.verify_target_context(role, Weapon).should be_false
|
572
|
+
Dummy.new.verify_target_context(permission, nil).should be_false
|
573
|
+
Dummy.new.verify_target_context(permission, Weapon).should be_false
|
574
|
+
end
|
575
|
+
|
576
|
+
it "should not allow instance context targets to be used within any other class or instance contexts or a nil context" do
|
577
|
+
context = Context.create(:name => "Test Context")
|
578
|
+
other_context = Context.create(:name => "Another Test Context")
|
579
|
+
role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context', :context_id => context.id)
|
580
|
+
permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context', :context_id => context.id)
|
581
|
+
Dummy.new.verify_target_context(role, nil).should be_false
|
582
|
+
Dummy.new.verify_target_context(role, Context).should be_false
|
583
|
+
Dummy.new.verify_target_context(role, Weapon).should be_false
|
584
|
+
Dummy.new.verify_target_context(role, other_context).should be_false
|
585
|
+
Dummy.new.verify_target_context(permission, nil).should be_false
|
586
|
+
Dummy.new.verify_target_context(permission, Context).should be_false
|
587
|
+
Dummy.new.verify_target_context(permission, Weapon).should be_false
|
588
|
+
Dummy.new.verify_target_context(permission, other_context).should be_false
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
context "when forcing context" do
|
593
|
+
it "should only allow the target to be used within the provided context" do
|
594
|
+
context = Context.create(:name => "Test Context")
|
595
|
+
nil_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100)
|
596
|
+
class_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context')
|
597
|
+
inst_role = Role.create(:name => 'Admin', :slug => 'admin', :level => 100, :context_type => 'Context', :context_id => context.id)
|
598
|
+
Dummy.new.verify_target_context(nil_role, nil, true).should be_true
|
599
|
+
Dummy.new.verify_target_context(nil_role, Context, true).should be_false
|
600
|
+
Dummy.new.verify_target_context(nil_role, context, true).should be_false
|
601
|
+
Dummy.new.verify_target_context(class_role, nil, true).should be_false
|
602
|
+
Dummy.new.verify_target_context(class_role, Context, true).should be_true
|
603
|
+
Dummy.new.verify_target_context(class_role, context, true).should be_false
|
604
|
+
Dummy.new.verify_target_context(inst_role, nil, true).should be_false
|
605
|
+
Dummy.new.verify_target_context(inst_role, Context, true).should be_false
|
606
|
+
Dummy.new.verify_target_context(inst_role, context, true).should be_true
|
607
|
+
nil_permission = Permission.create(:name => 'Do Something', :slug => 'do_something')
|
608
|
+
class_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context')
|
609
|
+
inst_permission = Permission.create(:name => 'Do Something', :slug => 'do_something', :context_type => 'Context', :context_id => context.id)
|
610
|
+
Dummy.new.verify_target_context(nil_permission, nil, true).should be_true
|
611
|
+
Dummy.new.verify_target_context(nil_permission, Context, true).should be_false
|
612
|
+
Dummy.new.verify_target_context(nil_permission, context, true).should be_false
|
613
|
+
Dummy.new.verify_target_context(class_permission, nil, true).should be_false
|
614
|
+
Dummy.new.verify_target_context(class_permission, Context, true).should be_true
|
615
|
+
Dummy.new.verify_target_context(class_permission, context, true).should be_false
|
616
|
+
Dummy.new.verify_target_context(inst_permission, nil, true).should be_false
|
617
|
+
Dummy.new.verify_target_context(inst_permission, Context, true).should be_false
|
618
|
+
Dummy.new.verify_target_context(inst_permission, context, true).should be_true
|
619
|
+
end
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
end
|