aegis 1.1.8 → 2.0.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/.gitignore +4 -0
- data/README.rdoc +58 -165
- data/Rakefile +20 -12
- data/VERSION +1 -1
- data/aegis.gemspec +85 -56
- data/lib/aegis.rb +9 -6
- data/lib/aegis/access_denied.rb +4 -0
- data/lib/aegis/action.rb +99 -0
- data/lib/aegis/compiler.rb +113 -0
- data/lib/aegis/has_role.rb +89 -110
- data/lib/aegis/parser.rb +110 -0
- data/lib/aegis/permissions.rb +164 -107
- data/lib/aegis/resource.rb +158 -0
- data/lib/aegis/role.rb +25 -55
- data/lib/aegis/sieve.rb +39 -0
- data/lib/rails/action_controller.rb +38 -0
- data/lib/rails/active_record.rb +1 -5
- data/spec/action_controller_spec.rb +100 -0
- data/spec/app_root/app/controllers/application_controller.rb +7 -0
- data/spec/app_root/app/controllers/reviews_controller.rb +36 -0
- data/spec/app_root/app/models/permissions.rb +14 -0
- data/spec/app_root/app/models/property.rb +5 -0
- data/spec/app_root/app/models/review.rb +5 -0
- data/{test → spec}/app_root/app/models/user.rb +1 -2
- data/{test → spec}/app_root/config/boot.rb +0 -0
- data/{test → spec}/app_root/config/database.yml +0 -0
- data/{test → spec}/app_root/config/environment.rb +0 -0
- data/{test → spec}/app_root/config/environments/in_memory.rb +0 -0
- data/{test → spec}/app_root/config/environments/mysql.rb +0 -0
- data/{test → spec}/app_root/config/environments/postgresql.rb +0 -0
- data/{test → spec}/app_root/config/environments/sqlite.rb +0 -0
- data/{test → spec}/app_root/config/environments/sqlite3.rb +0 -0
- data/spec/app_root/config/routes.rb +7 -0
- data/{test/app_root/db/migrate/20090408115228_create_users.rb → spec/app_root/db/migrate/001_create_users.rb} +2 -1
- data/spec/app_root/db/migrate/002_create_properties.rb +13 -0
- data/spec/app_root/db/migrate/003_create_reviews.rb +14 -0
- data/{test → spec}/app_root/lib/console_with_fixtures.rb +0 -0
- data/{test → spec}/app_root/log/.gitignore +0 -0
- data/{test → spec}/app_root/script/console +0 -0
- data/spec/controllers/reviews_controller_spec.rb +19 -0
- data/spec/has_role_spec.rb +177 -0
- data/spec/permissions_spec.rb +550 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +6 -9
- metadata +73 -57
- data/lib/aegis/constants.rb +0 -6
- data/lib/aegis/normalization.rb +0 -26
- data/lib/aegis/permission_error.rb +0 -5
- data/lib/aegis/permission_evaluator.rb +0 -34
- data/test/app_root/app/controllers/application_controller.rb +0 -2
- data/test/app_root/app/models/old_soldier.rb +0 -6
- data/test/app_root/app/models/permissions.rb +0 -49
- data/test/app_root/app/models/soldier.rb +0 -5
- data/test/app_root/app/models/trust_fund_kid.rb +0 -5
- data/test/app_root/app/models/user_subclass.rb +0 -2
- data/test/app_root/app/models/veteran_soldier.rb +0 -6
- data/test/app_root/config/routes.rb +0 -4
- data/test/app_root/db/migrate/20090429075648_create_soldiers.rb +0 -14
- data/test/app_root/db/migrate/20091110075648_create_veteran_soldiers.rb +0 -14
- data/test/app_root/db/migrate/20091110075649_create_trust_fund_kids.rb +0 -15
- data/test/has_role_options_test.rb +0 -64
- data/test/has_role_test.rb +0 -54
- data/test/permissions_test.rb +0 -109
- data/test/validation_test.rb +0 -55
@@ -0,0 +1,550 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe Aegis::Permissions do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
permissions = @permissions = Class.new(Aegis::Permissions) do
|
8
|
+
role :user
|
9
|
+
role :moderator
|
10
|
+
role :admin, :default_permission => :allow
|
11
|
+
end
|
12
|
+
|
13
|
+
@user_class = Class.new(ActiveRecord::Base) do
|
14
|
+
set_table_name 'users'
|
15
|
+
has_role :permissions => permissions
|
16
|
+
end
|
17
|
+
|
18
|
+
@user = @user_class.new(:role_name => 'user')
|
19
|
+
@moderator = @user_class.new(:role_name => 'moderator')
|
20
|
+
@admin = @user_class.new(:role_name => 'admin')
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'find_role_by_name' do
|
25
|
+
|
26
|
+
it "should look up previously defined roles" do
|
27
|
+
|
28
|
+
user_role = @permissions.find_role_by_name('user')
|
29
|
+
admin_role = @permissions.find_role_by_name('admin')
|
30
|
+
|
31
|
+
user_role.name.should == 'user'
|
32
|
+
user_role.may_by_default?.should be_false
|
33
|
+
|
34
|
+
admin_role.name.should == 'admin'
|
35
|
+
admin_role.may_by_default?.should be_true
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be nil if no role with that name was defined" do
|
40
|
+
@permissions.find_role_by_name('nonexisting_role').should be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'permission definition' do
|
46
|
+
|
47
|
+
it "should allow the definition of simple actions" do
|
48
|
+
|
49
|
+
@permissions.class_eval do
|
50
|
+
action :action_name do
|
51
|
+
allow :user
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
@permissions.may?(@user, 'action_name').should be_true
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow the definition of multiple actions at once" do
|
60
|
+
|
61
|
+
@permissions.class_eval do
|
62
|
+
action :action1, :action2 do
|
63
|
+
allow
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
@permissions.may?(@user, 'action1').should be_true
|
68
|
+
@permissions.may?(@user, 'action2').should be_true
|
69
|
+
@permissions.may?(@user, 'action3').should be_false
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should match an allow/deny directive to everyone is no role is named" do
|
74
|
+
@permissions.class_eval do
|
75
|
+
action :allowed_to_all do
|
76
|
+
allow
|
77
|
+
end
|
78
|
+
action :denied_to_all do
|
79
|
+
deny
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@permissions.may?(@user, 'allowed_to_all').should be_true
|
84
|
+
@permissions.may?(@admin, 'denied_to_all').should be_false
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow to grant permissions to multiple roles at once" do
|
88
|
+
|
89
|
+
@permissions.class_eval do
|
90
|
+
action :action_name do
|
91
|
+
allow :user, :moderator
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
@permissions.may?(@user, 'action_name').should be_true
|
96
|
+
@permissions.may?(@moderator, 'action_name').should be_true
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return the default permission when queried for undefined actions" do
|
101
|
+
|
102
|
+
@permissions.may?(@user, 'undefined_action').should be_false
|
103
|
+
@permissions.may?(@admin, 'undefined_action').should be_true
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should distinguish between roles" do
|
108
|
+
|
109
|
+
@permissions.class_eval do
|
110
|
+
action :update_news do
|
111
|
+
allow :moderator
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
@permissions.may?(@user, 'update_news').should be_false
|
116
|
+
@permissions.may?(@moderator, 'update_news').should be_true
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should run sieves in a sequence, the result being the last matching sieve" do
|
121
|
+
|
122
|
+
@permissions.class_eval do
|
123
|
+
action :update_news do
|
124
|
+
allow :everyone
|
125
|
+
deny :user
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
@permissions.may?(@user, 'update_news').should be_false
|
130
|
+
@permissions.may?(@moderator, 'update_news').should be_true
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should evaluate collection resources" do
|
135
|
+
|
136
|
+
@permissions.class_eval do
|
137
|
+
resources :posts do
|
138
|
+
allow :moderator
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
@permissions.may?(@moderator, 'update_post', "the post").should be_true
|
143
|
+
@permissions.may?(@moderator, 'show_post', "the post").should be_true
|
144
|
+
@permissions.may?(@moderator, 'create_post', "the post").should be_true
|
145
|
+
@permissions.may?(@moderator, 'destroy_post', "the post").should be_true
|
146
|
+
@permissions.may?(@moderator, 'index_posts').should be_true
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should allow to configure generated resource actions" do
|
151
|
+
|
152
|
+
@permissions.class_eval do
|
153
|
+
resources :posts do
|
154
|
+
action :index do
|
155
|
+
allow :user
|
156
|
+
end
|
157
|
+
action :show do
|
158
|
+
allow :user
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
@permissions.may?(@user, 'update_post', "the post").should be_false
|
164
|
+
@permissions.may?(@user, 'show_post', "the post").should be_true
|
165
|
+
@permissions.may?(@user, 'create_post', "the post").should be_false
|
166
|
+
@permissions.may?(@user, 'destroy_post', "the post").should be_false
|
167
|
+
@permissions.may?(@user, 'index_posts').should be_true
|
168
|
+
|
169
|
+
@permissions.find_action_by_path('index_posts').takes_object.should be_false
|
170
|
+
@permissions.find_action_by_path('show_post').takes_object.should be_true
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should raise an error if an action takes an object but does not get it in the arguments" do
|
175
|
+
|
176
|
+
@permissions.class_eval do
|
177
|
+
resources :posts do
|
178
|
+
allow :moderator
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
@permissions.may?(@moderator, 'update_post', "the post").should be_true
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should evaluate sieves with blocks" do
|
187
|
+
|
188
|
+
@permissions.class_eval do
|
189
|
+
resources :posts do
|
190
|
+
allow :user do
|
191
|
+
user.name == 'Waldo'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
frank = @user_class.new(:name => 'Frank', :role_name => 'user')
|
197
|
+
waldo = @user_class.new(:name => 'Waldo', :role_name => 'user')
|
198
|
+
|
199
|
+
frank.may_update_post?('the post').should be_false
|
200
|
+
waldo.may_update_post?('the post').should be_true
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should evaluate singleton resources, which take no object" do
|
205
|
+
|
206
|
+
@permissions.class_eval do
|
207
|
+
resource :session do
|
208
|
+
allow :moderator
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
@permissions.may?(@moderator, 'update_session').should be_true
|
213
|
+
@permissions.may?(@moderator, 'show_session').should be_true
|
214
|
+
@permissions.may?(@moderator, 'create_session').should be_true
|
215
|
+
@permissions.may?(@moderator, 'destroy_session').should be_true
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should allow to nest resources into collection resources" do
|
220
|
+
|
221
|
+
@permissions.class_eval do
|
222
|
+
resources :properties do
|
223
|
+
resources :comments do
|
224
|
+
allow :moderator
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
@permissions.may?(@moderator, 'update_property_comment', "the property", "the comment").should be_true
|
230
|
+
@permissions.may?(@moderator, 'show_property_comment', "the property", "the comment").should be_true
|
231
|
+
@permissions.may?(@moderator, 'create_property_comment', "the property").should be_true
|
232
|
+
@permissions.may?(@moderator, 'destroy_property_comment', "the property", "the comment").should be_true
|
233
|
+
@permissions.may?(@moderator, 'index_property_comments', "the property").should be_true
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should allow to nest resources into singleton resources" do
|
238
|
+
|
239
|
+
@permissions.class_eval do
|
240
|
+
resource :account do
|
241
|
+
resources :bookings do
|
242
|
+
allow :moderator
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
@permissions.may?(@moderator, 'update_account_booking', "the booking").should be_true
|
248
|
+
@permissions.may?(@moderator, 'show_account_booking', "the booking").should be_true
|
249
|
+
@permissions.may?(@moderator, 'create_account_booking').should be_true
|
250
|
+
@permissions.may?(@moderator, 'destroy_account_booking', "the booking").should be_true
|
251
|
+
@permissions.may?(@moderator, 'index_account_bookings').should be_true
|
252
|
+
|
253
|
+
@permissions.find_action_by_path('update_account').should_not be_abstract
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should support namespaces, which act like singleton resources but don't generate actions by default" do
|
258
|
+
|
259
|
+
@permissions.class_eval do
|
260
|
+
namespace :admin do
|
261
|
+
resources :bookings do
|
262
|
+
allow :moderator
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
@permissions.may?(@moderator, 'update_admin_booking', "the booking").should be_true
|
268
|
+
@permissions.may?(@moderator, 'show_admin_booking', "the booking").should be_true
|
269
|
+
@permissions.may?(@moderator, 'create_admin_booking').should be_true
|
270
|
+
@permissions.may?(@moderator, 'destroy_admin_booking', "the booking").should be_true
|
271
|
+
@permissions.may?(@moderator, 'index_admin_bookings').should be_true
|
272
|
+
|
273
|
+
@permissions.find_action_by_path('update_admin').should be_abstract
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should allow multiple levels of resource-nesting" do
|
278
|
+
|
279
|
+
@permissions.class_eval do
|
280
|
+
resources :properties do
|
281
|
+
resources :reviews do
|
282
|
+
resources :comments do
|
283
|
+
allow :moderator
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
@permissions.may?(@moderator, 'update_property_review_comment', "the review", "the comment").should be_true
|
290
|
+
@permissions.may?(@moderator, 'show_property_review_comment', "the review", "the comment").should be_true
|
291
|
+
@permissions.may?(@moderator, 'create_property_review_comment', "the review").should be_true
|
292
|
+
@permissions.may?(@moderator, 'destroy_property_review_comment', "the review", "the comment").should be_true
|
293
|
+
@permissions.may?(@moderator, 'index_property_review_comments', "the review").should be_true
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should raise an error if an action takes a parent object but does not get it in the arguments" do
|
298
|
+
|
299
|
+
@permissions.class_eval do
|
300
|
+
resources :properties do
|
301
|
+
resources :comments
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
lambda { @permissions.may?(@moderator, 'update_property_comment', "the comment") }.should raise_error(ArgumentError)
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should allow sieves with blocks and arguments" do
|
310
|
+
|
311
|
+
@permissions.class_eval do
|
312
|
+
action :sign_in do
|
313
|
+
allow do |password|
|
314
|
+
user.password == password
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
@user.stub(:password => "secret")
|
320
|
+
@user.may_sign_in?("wrong_password").should be_false
|
321
|
+
@user.may_sign_in?("secret").should be_true
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should provide the object and parent_object for a sieve block" do
|
326
|
+
spy = stub("spy")
|
327
|
+
@permissions.class_eval do
|
328
|
+
resources :properties do
|
329
|
+
resources :comments do
|
330
|
+
allow :moderator do |additional_argument|
|
331
|
+
spy.observe(parent_object, object, additional_argument)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
spy.should_receive(:observe).with("the property", "the comment", "additional argument")
|
338
|
+
@moderator.may_update_property_comment?("the property", "the comment", "additional argument")
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should evaluate additional resource actions" do
|
342
|
+
|
343
|
+
@permissions.class_eval do
|
344
|
+
resources :properties do
|
345
|
+
action :zoom_into do
|
346
|
+
allow :user
|
347
|
+
end
|
348
|
+
action :view_all, :collection => true do
|
349
|
+
allow :user
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
@permissions.may?(@user, "zoom_into_property", "the property").should be_true
|
355
|
+
@permissions.may?(@user, "view_all_properties", "the property").should be_true
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should allow rules that only affect reading actions" do
|
360
|
+
|
361
|
+
@permissions.class_eval do
|
362
|
+
resources :posts do
|
363
|
+
reading do
|
364
|
+
allow :user
|
365
|
+
end
|
366
|
+
action :syndicate, :writing => false
|
367
|
+
action :close
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
@permissions.may?(@user, 'update_post', "the post").should be_false
|
372
|
+
@permissions.may?(@user, 'show_post', "the post").should be_true
|
373
|
+
@permissions.may?(@user, 'create_post', "the post").should be_false
|
374
|
+
@permissions.may?(@user, 'destroy_post', "the post").should be_false
|
375
|
+
@permissions.may?(@user, 'index_posts').should be_true
|
376
|
+
@permissions.may?(@user, 'syndicate_post', "the post").should be_true
|
377
|
+
@permissions.may?(@user, 'close_post", "the post').should be_false
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should allow rules that only affect writing actions" do
|
382
|
+
|
383
|
+
@permissions.class_eval do
|
384
|
+
resources :posts do
|
385
|
+
writing do
|
386
|
+
allow :moderator
|
387
|
+
end
|
388
|
+
action :syndicate, :writing => false
|
389
|
+
action :close
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
# debugger
|
394
|
+
|
395
|
+
@permissions.may?(@moderator, 'update_post', "the post").should be_true
|
396
|
+
@permissions.may?(@moderator, 'show_post', "the post").should be_false
|
397
|
+
@permissions.may?(@moderator, 'create_post', "the post").should be_true
|
398
|
+
@permissions.may?(@moderator, 'destroy_post', "the post").should be_true
|
399
|
+
@permissions.may?(@moderator, 'index_posts').should be_false
|
400
|
+
@permissions.may?(@moderator, 'syndicate_post', "the post").should be_false
|
401
|
+
@permissions.may?(@moderator, "close_post", "the post").should be_true
|
402
|
+
|
403
|
+
end
|
404
|
+
|
405
|
+
it "should allow resources with only selected actions" do
|
406
|
+
@permissions.class_eval do
|
407
|
+
resources :posts, :only => [:show, :update]
|
408
|
+
end
|
409
|
+
@permissions.find_action_by_path('update_post').should_not be_abstract
|
410
|
+
@permissions.find_action_by_path('show_post').should_not be_abstract
|
411
|
+
@permissions.find_action_by_path('create_post').should be_abstract
|
412
|
+
@permissions.find_action_by_path('destroy_post').should be_abstract
|
413
|
+
@permissions.find_action_by_path('index_posts').should be_abstract
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should allow resources with all actions except a selected few" do
|
417
|
+
@permissions.class_eval do
|
418
|
+
resources :posts, :except => [:show, :update]
|
419
|
+
end
|
420
|
+
@permissions.find_action_by_path('update_post').should be_abstract
|
421
|
+
@permissions.find_action_by_path('show_post').should be_abstract
|
422
|
+
@permissions.find_action_by_path('create_post').should_not be_abstract
|
423
|
+
@permissions.find_action_by_path('destroy_post').should_not be_abstract
|
424
|
+
@permissions.find_action_by_path('index_posts').should_not be_abstract
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
it "should alias action names for all actions and resources, aliasing #new and #edit by default" do
|
429
|
+
|
430
|
+
@permissions.class_eval do
|
431
|
+
|
432
|
+
alias_action :delete => :destroy
|
433
|
+
|
434
|
+
resources :properties do
|
435
|
+
resources :comments
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
@permissions.find_action_by_path('delete_property').should_not be_abstract
|
440
|
+
@permissions.find_action_by_path('new_property').should_not be_abstract
|
441
|
+
@permissions.find_action_by_path('edit_property').should_not be_abstract
|
442
|
+
|
443
|
+
@permissions.find_action_by_path('delete_property_comment').should_not be_abstract
|
444
|
+
@permissions.find_action_by_path('new_property_comment').should_not be_abstract
|
445
|
+
@permissions.find_action_by_path('edit_property_comment').should_not be_abstract
|
446
|
+
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
describe 'may!' do
|
451
|
+
|
452
|
+
it "should return if permission is granted" do
|
453
|
+
lambda { @permissions.may!(@admin, :delete_everything) }.should_not raise_error
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should raise an error if permission is denied" do
|
457
|
+
lambda { @permissions.may!(@user, :delete_everything) }.should raise_error(Aegis::AccessDenied)
|
458
|
+
end
|
459
|
+
|
460
|
+
end
|
461
|
+
|
462
|
+
describe 'behavior when checking permissions without a user' do
|
463
|
+
|
464
|
+
it "should raise an error if the user is nil" do
|
465
|
+
lambda { @permissions.may?(nil, :some_action) }.should raise_error
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should substitute the results from the blank user strategy" do
|
469
|
+
@permissions.class_eval do
|
470
|
+
missing_user_means { User.new(:role_name => 'user') }
|
471
|
+
action :create_post do
|
472
|
+
allow :moderator
|
473
|
+
end
|
474
|
+
action :show_post do
|
475
|
+
allow :user
|
476
|
+
end
|
477
|
+
end
|
478
|
+
@permissions.may?(nil, :create_post).should be_false
|
479
|
+
@permissions.may?(nil, :show_post).should be_true
|
480
|
+
end
|
481
|
+
|
482
|
+
end
|
483
|
+
|
484
|
+
describe 'behavior when a permission is not defined' do
|
485
|
+
|
486
|
+
it "should use the default permission if the strategy is :default_permission" do
|
487
|
+
@permissions.class_eval do
|
488
|
+
missing_action_means :default_permission
|
489
|
+
end
|
490
|
+
@user.may_missing_action?.should be_false
|
491
|
+
@admin.may_missing_action?.should be_true
|
492
|
+
end
|
493
|
+
|
494
|
+
it "should grant everyone access if the strategy is :allow" do
|
495
|
+
@permissions.class_eval do
|
496
|
+
missing_action_means :allow
|
497
|
+
end
|
498
|
+
@user.may_missing_action?.should be_true
|
499
|
+
@admin.may_missing_action?.should be_true
|
500
|
+
end
|
501
|
+
|
502
|
+
it "should deny everyone access if the strategy is :deny" do
|
503
|
+
@permissions.class_eval do
|
504
|
+
missing_action_means :deny
|
505
|
+
end
|
506
|
+
@user.may_missing_action?.should be_false
|
507
|
+
@admin.may_missing_action?.should be_false
|
508
|
+
end
|
509
|
+
|
510
|
+
it "should raise an error if the strategy is :error" do
|
511
|
+
@permissions.class_eval do
|
512
|
+
missing_action_means :error
|
513
|
+
end
|
514
|
+
lambda { @user.may_missing_action? }.should raise_error
|
515
|
+
lambda { @admin.may_missing_action? }.should raise_error
|
516
|
+
end
|
517
|
+
|
518
|
+
end
|
519
|
+
|
520
|
+
describe 'guess_action' do
|
521
|
+
|
522
|
+
it "should guess an action based on the given resource and action name, trying both singular and plural" do
|
523
|
+
|
524
|
+
@permissions.class_eval do
|
525
|
+
resources :posts
|
526
|
+
end
|
527
|
+
|
528
|
+
@permissions.guess_action(:posts, :index).should_not be_abstract
|
529
|
+
@permissions.guess_action(:posts, :update).should_not be_abstract
|
530
|
+
@permissions.guess_action(:posts, :unknown_action).should be_abstract
|
531
|
+
|
532
|
+
end
|
533
|
+
|
534
|
+
it "should consult the actions map first and use the the default behaviour for unmapped actions" do
|
535
|
+
|
536
|
+
@permissions.class_eval do
|
537
|
+
resources :posts, :only => [:update] do
|
538
|
+
action :view_all, :collection => true
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
@permissions.guess_action(:posts, 'index', 'index' => 'view_all_posts').should_not be_abstract
|
543
|
+
@permissions.guess_action(:posts, 'update', 'index' => 'view_all_posts').should_not be_abstract
|
544
|
+
|
545
|
+
end
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
end
|
550
|
+
|