cancancan 1.11.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/cancancan.gemspec +15 -19
  3. data/lib/cancan/ability/actions.rb +91 -0
  4. data/lib/cancan/ability/rules.rb +85 -0
  5. data/lib/cancan/ability.rb +74 -136
  6. data/lib/cancan/conditions_matcher.rb +93 -0
  7. data/lib/cancan/controller_additions.rb +34 -40
  8. data/lib/cancan/controller_resource.rb +47 -212
  9. data/lib/cancan/controller_resource_builder.rb +24 -0
  10. data/lib/cancan/controller_resource_finder.rb +40 -0
  11. data/lib/cancan/controller_resource_loader.rb +116 -0
  12. data/lib/cancan/controller_resource_name_finder.rb +21 -0
  13. data/lib/cancan/controller_resource_sanitizer.rb +30 -0
  14. data/lib/cancan/exceptions.rb +7 -3
  15. data/lib/cancan/matchers.rb +12 -3
  16. data/lib/cancan/model_adapters/abstract_adapter.rb +8 -8
  17. data/lib/cancan/model_adapters/active_record_4_adapter.rb +33 -10
  18. data/lib/cancan/model_adapters/active_record_5_adapter.rb +70 -0
  19. data/lib/cancan/model_adapters/active_record_adapter.rb +41 -81
  20. data/lib/cancan/model_adapters/can_can/model_adapters/active_record_adapter/joins.rb +39 -0
  21. data/lib/cancan/model_adapters/conditions_extractor.rb +75 -0
  22. data/lib/cancan/model_additions.rb +0 -1
  23. data/lib/cancan/rule.rb +36 -92
  24. data/lib/cancan/rules_compressor.rb +20 -0
  25. data/lib/cancan/version.rb +1 -1
  26. data/lib/cancan.rb +5 -12
  27. data/lib/generators/cancan/ability/ability_generator.rb +1 -1
  28. metadata +54 -65
  29. data/.gitignore +0 -15
  30. data/.rspec +0 -1
  31. data/.travis.yml +0 -55
  32. data/Appraisals +0 -136
  33. data/CHANGELOG.rdoc +0 -503
  34. data/CONTRIBUTING.md +0 -23
  35. data/Gemfile +0 -3
  36. data/LICENSE +0 -22
  37. data/README.md +0 -188
  38. data/Rakefile +0 -9
  39. data/gemfiles/activerecord_3.0.gemfile +0 -18
  40. data/gemfiles/activerecord_3.1.gemfile +0 -20
  41. data/gemfiles/activerecord_3.2.gemfile +0 -20
  42. data/gemfiles/activerecord_4.0.gemfile +0 -17
  43. data/gemfiles/activerecord_4.1.gemfile +0 -17
  44. data/gemfiles/activerecord_4.2.gemfile +0 -18
  45. data/gemfiles/datamapper_1.x.gemfile +0 -14
  46. data/gemfiles/mongoid_2.x.gemfile +0 -20
  47. data/gemfiles/sequel_3.x.gemfile +0 -20
  48. data/lib/cancan/inherited_resource.rb +0 -20
  49. data/lib/cancan/model_adapters/active_record_3_adapter.rb +0 -47
  50. data/lib/cancan/model_adapters/data_mapper_adapter.rb +0 -34
  51. data/lib/cancan/model_adapters/mongoid_adapter.rb +0 -54
  52. data/lib/cancan/model_adapters/sequel_adapter.rb +0 -87
  53. data/spec/README.rdoc +0 -27
  54. data/spec/cancan/ability_spec.rb +0 -487
  55. data/spec/cancan/controller_additions_spec.rb +0 -141
  56. data/spec/cancan/controller_resource_spec.rb +0 -632
  57. data/spec/cancan/exceptions_spec.rb +0 -58
  58. data/spec/cancan/inherited_resource_spec.rb +0 -71
  59. data/spec/cancan/matchers_spec.rb +0 -29
  60. data/spec/cancan/model_adapters/active_record_4_adapter_spec.rb +0 -85
  61. data/spec/cancan/model_adapters/active_record_adapter_spec.rb +0 -446
  62. data/spec/cancan/model_adapters/data_mapper_adapter_spec.rb +0 -119
  63. data/spec/cancan/model_adapters/default_adapter_spec.rb +0 -7
  64. data/spec/cancan/model_adapters/mongoid_adapter_spec.rb +0 -227
  65. data/spec/cancan/model_adapters/sequel_adapter_spec.rb +0 -132
  66. data/spec/cancan/rule_spec.rb +0 -52
  67. data/spec/matchers.rb +0 -13
  68. data/spec/spec.opts +0 -2
  69. data/spec/spec_helper.rb +0 -28
  70. data/spec/support/ability.rb +0 -7
@@ -1,632 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe CanCan::ControllerResource do
4
- let(:ability) { Ability.new(nil) }
5
- let(:params) { HashWithIndifferentAccess.new(:controller => "models") }
6
- let(:controller_class) { Class.new }
7
- let(:controller) { controller_class.new }
8
-
9
- before(:each) do
10
- class Model
11
- attr_accessor :name
12
-
13
- def initialize(attributes={})
14
- attributes.each do |attribute, value|
15
- send("#{attribute}=", value)
16
- end
17
- end
18
- end
19
-
20
- allow(controller).to receive(:params) { params }
21
- allow(controller).to receive(:current_ability) { ability }
22
- allow(controller_class).to receive(:cancan_skipper) { {:authorize => {}, :load => {}} }
23
- end
24
-
25
- context "on build actions" do
26
- before :each do
27
- params.merge!(:action => "new")
28
- end
29
-
30
- it "builds a new resource with attributes from current ability" do
31
- ability.can(:create, Model, :name => "from conditions")
32
- resource = CanCan::ControllerResource.new(controller)
33
- resource.load_resource
34
- expect(controller.instance_variable_get(:@model).name).to eq("from conditions")
35
- end
36
-
37
- it "overrides initial attributes with params" do
38
- params.merge!(:model => {:name => "from params"})
39
- ability.can(:create, Model, :name => "from conditions")
40
- resource = CanCan::ControllerResource.new(controller)
41
- resource.load_resource
42
- expect(controller.instance_variable_get(:@model).name).to eq("from params")
43
- end
44
-
45
- it "builds a resource when on custom new action even when params[:id] exists" do
46
- params.merge!(:action => "build", :id => "123")
47
- allow(Model).to receive(:new) { :some_model }
48
- resource = CanCan::ControllerResource.new(controller, :new => :build)
49
- resource.load_resource
50
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
51
- end
52
-
53
- it "only authorizes :show action on parent resource" do
54
- model = Model.new
55
- allow(Model).to receive(:find).with("123") { model }
56
-
57
- params.merge!(:model_id => 123)
58
- allow(controller).to receive(:authorize!).with(:show, model) { raise CanCan::AccessDenied }
59
- resource = CanCan::ControllerResource.new(controller, :model, :parent => true)
60
- expect { resource.load_and_authorize_resource }.to raise_error(CanCan::AccessDenied)
61
- end
62
- end
63
-
64
- context "on create actions" do
65
- before :each do
66
- params.merge!(:action => 'create')
67
- end
68
-
69
- # Rails includes namespace in params, see issue #349
70
- it "creates through the namespaced params" do
71
- module MyEngine
72
- class Model < ::Model; end
73
- end
74
-
75
- params.merge!(:controller => "my_engine/models", :my_engine_model => {:name => "foobar"})
76
- resource = CanCan::ControllerResource.new(controller)
77
- resource.load_resource
78
- expect(controller.instance_variable_get(:@model).name).to eq("foobar")
79
- end
80
-
81
- it "builds a new resource with hash if params[:id] is not specified" do
82
- params.merge!(:model => {:name => "foobar"})
83
- resource = CanCan::ControllerResource.new(controller)
84
- resource.load_resource
85
- expect(controller.instance_variable_get(:@model).name).to eq("foobar")
86
- end
87
-
88
- it "builds a new resource for namespaced model with hash if params[:id] is not specified" do
89
- module Sub
90
- class Model < ::Model; end
91
- end
92
-
93
- params.merge!('sub_model' => {:name => "foobar"})
94
- resource = CanCan::ControllerResource.new(controller, :class => ::Sub::Model)
95
- resource.load_resource
96
- expect(controller.instance_variable_get(:@model).name).to eq("foobar")
97
- end
98
-
99
- it "builds a new resource for namespaced controller and namespaced model with hash if params[:id] is not specified" do
100
- params.merge!(:controller => "admin/sub_models", 'sub_model' => {:name => "foobar"})
101
- resource = CanCan::ControllerResource.new(controller, :class => Model)
102
- resource.load_resource
103
- expect(controller.instance_variable_get(:@sub_model).name).to eq("foobar")
104
- end
105
-
106
- it "builds a new resource for namespaced controller given through folder format" do
107
- module Admin
108
- module SubModule
109
- class HiddenModel < ::Model; end
110
- end
111
- end
112
- params.merge!(:controller => "admin/sub_module/hidden_models")
113
- resource = CanCan::ControllerResource.new(controller)
114
- expect { resource.load_resource }.not_to raise_error
115
- end
116
-
117
- it "does not build record through has_one association with :singleton option because it can cause it to delete it in the database" do
118
- category = Class.new
119
- allow_any_instance_of(Model).to receive('category=').with(category)
120
- allow_any_instance_of(Model).to receive('category') { category }
121
-
122
- params.merge!(:model => {:name => "foobar"})
123
-
124
- controller.instance_variable_set(:@category, category)
125
- resource = CanCan::ControllerResource.new(controller, :through => :category, :singleton => true)
126
- resource.load_resource
127
- expect(controller.instance_variable_get(:@model).name).to eq("foobar")
128
- expect(controller.instance_variable_get(:@model).category).to eq(category)
129
- end
130
-
131
- it "builds record through has_one association with :singleton and :shallow options" do
132
- params.merge!(:model => {:name => "foobar"})
133
- resource = CanCan::ControllerResource.new(controller, :through => :category, :singleton => true, :shallow => true)
134
- resource.load_resource
135
- expect(controller.instance_variable_get(:@model).name).to eq("foobar")
136
- end
137
-
138
- context "with a strong parameters method" do
139
- before :each do
140
- params.merge!(:controller => "model", :model => { :name => 'test'})
141
- end
142
-
143
- it "accepts and uses the specified symbol for santitizing input" do
144
- allow(controller).to receive(:resource_params).and_return(:resource => 'params')
145
- allow(controller).to receive(:model_params).and_return(:model => 'params')
146
- allow(controller).to receive(:create_params).and_return(:create => 'params')
147
- allow(controller).to receive(:custom_params).and_return(:custom => 'params')
148
- resource = CanCan::ControllerResource.new(controller, {:param_method => :custom_params})
149
- expect(resource.send("resource_params")).to eq(:custom => 'params')
150
- end
151
-
152
- it "accepts the specified string for sanitizing input" do
153
- resource = CanCan::ControllerResource.new(controller, {:param_method => "{:custom => 'params'}"})
154
- expect(resource.send("resource_params")).to eq(:custom => 'params')
155
- end
156
-
157
- it "accepts the specified proc for sanitizing input" do
158
- resource = CanCan::ControllerResource.new(controller, {:param_method => Proc.new { |c| {:custom => 'params'}}})
159
- expect(resource.send("resource_params")).to eq(:custom => 'params')
160
- end
161
-
162
- it "prefers to use the create_params method for santitizing input" do
163
- allow(controller).to receive(:resource_params).and_return(:resource => 'params')
164
- allow(controller).to receive(:model_params).and_return(:model => 'params')
165
- allow(controller).to receive(:create_params).and_return(:create => 'params')
166
- allow(controller).to receive(:custom_params).and_return(:custom => 'params')
167
- resource = CanCan::ControllerResource.new(controller)
168
- expect(resource.send("resource_params")).to eq(:create => 'params')
169
- end
170
-
171
- it "prefers to use the <model_name>_params method for santitizing input if create is not found" do
172
- allow(controller).to receive(:resource_params).and_return(:resource => 'params')
173
- allow(controller).to receive(:model_params).and_return(:model => 'params')
174
- allow(controller).to receive(:custom_params).and_return(:custom => 'params')
175
- resource = CanCan::ControllerResource.new(controller)
176
- expect(resource.send("resource_params")).to eq(:model => 'params')
177
- end
178
-
179
- it "prefers to use the resource_params method for santitizing input if create or model is not found" do
180
- allow(controller).to receive(:resource_params).and_return(:resource => 'params')
181
- allow(controller).to receive(:custom_params).and_return(:custom => 'params')
182
- resource = CanCan::ControllerResource.new(controller)
183
- expect(resource.send("resource_params")).to eq(:resource => 'params')
184
- end
185
- end
186
- end
187
-
188
- context "on collection actions" do
189
- before :each do
190
- params[:action] = 'index'
191
- end
192
-
193
- it "builds a collection when on index action when class responds to accessible_by" do
194
- allow(Model).to receive(:accessible_by).with(ability, :index) { :found_models }
195
-
196
- resource = CanCan::ControllerResource.new(controller, :model)
197
- resource.load_resource
198
- expect(controller.instance_variable_get(:@model)).to be_nil
199
- expect(controller.instance_variable_get(:@models)).to eq(:found_models)
200
- end
201
-
202
- it "does not build a collection when on index action when class does not respond to accessible_by" do
203
- resource = CanCan::ControllerResource.new(controller)
204
- resource.load_resource
205
- expect(controller.instance_variable_get(:@model)).to be_nil
206
- expect(controller.instance_variable_defined?(:@models)).to be(false)
207
- end
208
-
209
- it "does not use accessible_by when defining abilities through a block" do
210
- allow(Model).to receive(:accessible_by).with(ability) { :found_models }
211
-
212
- ability.can(:read, Model) { |p| false }
213
- resource = CanCan::ControllerResource.new(controller)
214
- resource.load_resource
215
- expect(controller.instance_variable_get(:@model)).to be_nil
216
- expect(controller.instance_variable_defined?(:@models)).to be(false)
217
- end
218
-
219
- it "does not authorize single resource in collection action" do
220
- allow(controller).to receive(:authorize!).with(:index, Model) { raise CanCan::AccessDenied }
221
- resource = CanCan::ControllerResource.new(controller)
222
-
223
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
224
- end
225
-
226
- it "authorizes parent resource in collection action" do
227
- controller.instance_variable_set(:@category, :some_category)
228
- allow(controller).to receive(:authorize!).with(:show, :some_category) { raise CanCan::AccessDenied }
229
-
230
- resource = CanCan::ControllerResource.new(controller, :category, :parent => true)
231
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
232
- end
233
-
234
- it "authorizes with :custom_action for parent collection action" do
235
- controller.instance_variable_set(:@category, :some_category)
236
- allow(controller).to receive(:authorize!).with(:custom_action, :some_category) { raise CanCan::AccessDenied }
237
-
238
- resource = CanCan::ControllerResource.new(controller, :category, :parent => true, :parent_action => :custom_action )
239
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
240
- end
241
-
242
- it "has the specified nested resource_class when using / for namespace" do
243
- module Admin
244
- class Dashboard; end
245
- end
246
- ability.can(:index, "admin/dashboard")
247
- params.merge!(:controller => "admin/dashboard")
248
- resource = CanCan::ControllerResource.new(controller, :authorize => true)
249
- expect(resource.send(:resource_class)).to eq(Admin::Dashboard)
250
- end
251
-
252
- it "does not build a single resource when on custom collection action even with id" do
253
- params.merge!(:action => "sort", :id => "123")
254
-
255
- resource = CanCan::ControllerResource.new(controller, :collection => [:sort, :list])
256
- resource.load_resource
257
- expect(controller.instance_variable_get(:@model)).to be_nil
258
- end
259
-
260
- it "loads a collection resource when on custom action with no id param" do
261
- allow(Model).to receive(:accessible_by).with(ability, :sort) { :found_models }
262
- params[:action] = "sort"
263
- resource = CanCan::ControllerResource.new(controller)
264
- resource.load_resource
265
- expect(controller.instance_variable_get(:@model)).to be_nil
266
- expect(controller.instance_variable_get(:@models)).to eq(:found_models)
267
- end
268
-
269
- it "loads parent resource through proper id parameter" do
270
- model = Model.new
271
- allow(Model).to receive(:find).with("1") { model }
272
-
273
- params.merge!(:controller => "categories", :model_id => 1)
274
- resource = CanCan::ControllerResource.new(controller, :model)
275
- resource.load_resource
276
- expect(controller.instance_variable_get(:@model)).to eq(model)
277
- end
278
-
279
- it "authorizes nested resource through parent association on index action" do
280
- controller.instance_variable_set(:@category, category = double)
281
- allow(controller).to receive(:authorize!).with(:index, category => Model) { raise CanCan::AccessDenied }
282
- resource = CanCan::ControllerResource.new(controller, :through => :category)
283
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
284
- end
285
- end
286
-
287
- context "on instance read actions" do
288
- before :each do
289
- params.merge!(:action => "show", :id => "123")
290
- end
291
-
292
- it "loads the resource into an instance variable if params[:id] is specified" do
293
- model = Model.new
294
- allow(Model).to receive(:find).with("123") { model }
295
-
296
- resource = CanCan::ControllerResource.new(controller)
297
- resource.load_resource
298
- expect(controller.instance_variable_get(:@model)).to eq(model)
299
- end
300
-
301
- it "does not load resource into an instance variable if already set" do
302
- controller.instance_variable_set(:@model, :some_model)
303
- resource = CanCan::ControllerResource.new(controller)
304
- resource.load_resource
305
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
306
- end
307
-
308
- it "loads resource for namespaced controller" do
309
- model = Model.new
310
- allow(Model).to receive(:find).with("123") { model }
311
- params.merge!(:controller => "admin/models")
312
-
313
- resource = CanCan::ControllerResource.new(controller)
314
- resource.load_resource
315
- expect(controller.instance_variable_get(:@model)).to eq(model)
316
- end
317
-
318
- it "performs authorization using controller action and loaded model" do
319
- controller.instance_variable_set(:@model, :some_model)
320
- allow(controller).to receive(:authorize!).with(:show, :some_model) { raise CanCan::AccessDenied }
321
-
322
- resource = CanCan::ControllerResource.new(controller)
323
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
324
- end
325
-
326
- it "performs authorization using controller action and non loaded model" do
327
- allow(controller).to receive(:authorize!).with(:show, Model) { raise CanCan::AccessDenied }
328
- resource = CanCan::ControllerResource.new(controller)
329
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
330
- end
331
-
332
- it "calls load_resource and authorize_resource for load_and_authorize_resource" do
333
- resource = CanCan::ControllerResource.new(controller)
334
- expect(resource).to receive(:load_resource)
335
- expect(resource).to receive(:authorize_resource)
336
- resource.load_and_authorize_resource
337
- end
338
-
339
- it "loads resource through the association of another parent resource using instance variable" do
340
- category = double(:models => {})
341
- controller.instance_variable_set(:@category, category)
342
- allow(category.models).to receive(:find).with("123") { :some_model }
343
- resource = CanCan::ControllerResource.new(controller, :through => :category)
344
- resource.load_resource
345
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
346
- end
347
-
348
- it "loads resource through the custom association name" do
349
- category = double(:custom_models => {})
350
- controller.instance_variable_set(:@category, category)
351
- allow(category.custom_models).to receive(:find).with("123") { :some_model }
352
- resource = CanCan::ControllerResource.new(controller, :through => :category, :through_association => :custom_models)
353
- resource.load_resource
354
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
355
- end
356
-
357
- it "loads resource through the association of another parent resource using method" do
358
- category = double(:models => {})
359
- allow(controller).to receive(:category) { category }
360
- allow(category.models).to receive(:find).with("123") { :some_model }
361
- resource = CanCan::ControllerResource.new(controller, :through => :category)
362
- resource.load_resource
363
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
364
- end
365
-
366
- it "does not load through parent resource if instance isn't loaded when shallow" do
367
- model = Model.new
368
- allow(Model).to receive(:find).with("123") { model }
369
-
370
- resource = CanCan::ControllerResource.new(controller, :through => :category, :shallow => true)
371
- resource.load_resource
372
- expect(controller.instance_variable_get(:@model)).to eq(model)
373
- end
374
-
375
- it "raises AccessDenied when attempting to load resource through nil" do
376
- resource = CanCan::ControllerResource.new(controller, :through => :category)
377
- expect {
378
- resource.load_resource
379
- }.to raise_error(CanCan::AccessDenied) { |exception|
380
- expect(exception.action).to eq(:show)
381
- expect(exception.subject).to eq(Model)
382
- }
383
- expect(controller.instance_variable_get(:@model)).to be_nil
384
- end
385
-
386
- it "loads through first matching if multiple are given" do
387
- category = double(:models => {})
388
- controller.instance_variable_set(:@category, category)
389
- allow(category.models).to receive(:find).with("123") { :some_model }
390
-
391
- resource = CanCan::ControllerResource.new(controller, :through => [:category, :user])
392
- resource.load_resource
393
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
394
- end
395
-
396
- it "finds record through has_one association with :singleton option without id param" do
397
- params.merge!(:id => nil)
398
-
399
- category = double(:model => :some_model)
400
- controller.instance_variable_set(:@category, category)
401
- resource = CanCan::ControllerResource.new(controller, :through => :category, :singleton => true)
402
- resource.load_resource
403
- expect(controller.instance_variable_get(:@model)).to eq(:some_model)
404
- end
405
-
406
- it "does not try to load resource for other action if params[:id] is undefined" do
407
- params.merge!(:action => 'list', :id => nil)
408
- resource = CanCan::ControllerResource.new(controller)
409
- resource.load_resource
410
- expect(controller.instance_variable_get(:@model)).to be_nil
411
- end
412
-
413
- it "finds record through has_one association with :singleton and :shallow options" do
414
- model = Model.new
415
- allow(Model).to receive(:find).with("123") { model }
416
-
417
- resource = CanCan::ControllerResource.new(controller, :through => :category, :singleton => true, :shallow => true)
418
- resource.load_resource
419
- expect(controller.instance_variable_get(:@model)).to eq(model)
420
- end
421
-
422
- it "loads the model using a custom class" do
423
- model = Model.new
424
- allow(Model).to receive(:find).with("123") { model }
425
-
426
- resource = CanCan::ControllerResource.new(controller, :class => Model)
427
- resource.load_resource
428
- expect(controller.instance_variable_get(:@model)).to eq(model)
429
- end
430
-
431
- it "loads the model using a custom namespaced class" do
432
- module Sub
433
- class Model < ::Model; end
434
- end
435
-
436
- model = Sub::Model.new
437
- allow(Sub::Model).to receive(:find).with("123") { model }
438
-
439
- resource = CanCan::ControllerResource.new(controller, :class => ::Sub::Model)
440
- resource.load_resource
441
- expect(controller.instance_variable_get(:@model)).to eq(model)
442
- end
443
-
444
- it "authorizes based on resource name if class is false" do
445
- allow(controller).to receive(:authorize!).with(:show, :model) { raise CanCan::AccessDenied }
446
- resource = CanCan::ControllerResource.new(controller, :class => false)
447
- expect { resource.authorize_resource }.to raise_error(CanCan::AccessDenied)
448
- end
449
-
450
- it "loads and authorize using custom instance name" do
451
- model = Model.new
452
- allow(Model).to receive(:find).with("123") { model }
453
-
454
- allow(controller).to receive(:authorize!).with(:show, model) { raise CanCan::AccessDenied }
455
- resource = CanCan::ControllerResource.new(controller, :instance_name => :custom_model)
456
- expect { resource.load_and_authorize_resource }.to raise_error(CanCan::AccessDenied)
457
- expect(controller.instance_variable_get(:@custom_model)).to eq(model)
458
- end
459
-
460
- it "loads resource using custom ID param" do
461
- model = Model.new
462
- allow(Model).to receive(:find).with("123") { model }
463
-
464
- params.merge!(:the_model => 123)
465
- resource = CanCan::ControllerResource.new(controller, :id_param => :the_model)
466
- resource.load_resource
467
- expect(controller.instance_variable_get(:@model)).to eq(model)
468
- end
469
-
470
- # CVE-2012-5664
471
- it "always converts id param to string" do
472
- params.merge!(:the_model => { :malicious => "I am" })
473
- resource = CanCan::ControllerResource.new(controller, :id_param => :the_model)
474
- expect(resource.send(:id_param).class).to eq(String)
475
- end
476
-
477
- it "should id param return nil if param is nil" do
478
- params.merge!(:the_model => nil)
479
- resource = CanCan::ControllerResource.new(controller, :id_param => :the_model)
480
- expect(resource.send(:id_param)).to be_nil
481
- end
482
-
483
- it "loads resource using custom find_by attribute" do
484
- model = Model.new
485
- allow(Model).to receive(:name).with('foo') { model }
486
-
487
- params.merge!(:action => "show", :id => "foo")
488
- resource = CanCan::ControllerResource.new(controller, :find_by => :name)
489
- resource.load_resource
490
- expect(controller.instance_variable_get(:@model)).to eq(model)
491
- end
492
-
493
- it "allows full find method to be passed into find_by option" do
494
- model = Model.new
495
- allow(Model).to receive(:find_by_name).with('foo') { model }
496
-
497
- params.merge!(:action => "show", :id => "foo")
498
- resource = CanCan::ControllerResource.new(controller, :find_by => :find_by_name)
499
- resource.load_resource
500
- expect(controller.instance_variable_get(:@model)).to eq(model)
501
- end
502
- end
503
-
504
- it "calls the santitizer when the parameter hash matches our object" do
505
- params.merge!(:action => 'create', :model => { :name => 'test' })
506
- allow(controller).to receive(:create_params).and_return({})
507
-
508
- resource = CanCan::ControllerResource.new(controller)
509
- resource.load_resource
510
- expect(controller.instance_variable_get(:@model).name).to eq nil
511
- end
512
-
513
- it "santitizes correctly when the instance name is overriden" do
514
- params.merge!(:action => 'create', :custom_name => {:name => "foobar"})
515
- allow(controller).to receive(:create_params).and_return({})
516
-
517
- resource = CanCan::ControllerResource.new(controller, :instance_name => :custom_name)
518
- resource.load_resource
519
- expect(controller.instance_variable_get(:@custom_name).name).to eq nil
520
- end
521
-
522
- it "calls the santitize method on non-save actions when required" do
523
- params.merge!(:action => 'new', :model => { :name => 'test' })
524
-
525
- allow(controller).to receive(:resource_params).and_return({})
526
- resource = CanCan::ControllerResource.new(controller)
527
- resource.load_resource
528
- expect(controller.instance_variable_get(:@model).name).to eq nil
529
- end
530
-
531
- it "doesn't sanitize parameters on non-save actions when not required" do
532
- params.merge!(:action => 'new', :not_our_model => { :name => 'test' })
533
- allow(controller).to receive(:resource_params).and_raise
534
-
535
- resource = CanCan::ControllerResource.new(controller)
536
- expect {
537
- resource.load_resource
538
- }.to_not raise_error
539
- end
540
-
541
- it "is a parent resource when name is provided which doesn't match controller" do
542
- resource = CanCan::ControllerResource.new(controller, :category)
543
- expect(resource).to be_parent
544
- end
545
-
546
- it "does not be a parent resource when name is provided which matches controller" do
547
- resource = CanCan::ControllerResource.new(controller, :model)
548
- expect(resource).to_not be_parent
549
- end
550
-
551
- it "is parent if specified in options" do
552
- resource = CanCan::ControllerResource.new(controller, :model, {:parent => true})
553
- expect(resource).to be_parent
554
- end
555
-
556
- it "does not be parent if specified in options" do
557
- resource = CanCan::ControllerResource.new(controller, :category, {:parent => false})
558
- expect(resource).to_not be_parent
559
- end
560
-
561
- it "has the specified resource_class if 'name' is passed to load_resource" do
562
- class Section; end
563
- resource = CanCan::ControllerResource.new(controller, :section)
564
- expect(resource.send(:resource_class)).to eq(Section)
565
- end
566
-
567
- it "raises ImplementationRemoved when adding :name option" do
568
- expect {
569
- CanCan::ControllerResource.new(controller, :name => :foo)
570
- }.to raise_error(CanCan::ImplementationRemoved)
571
- end
572
-
573
- it "raises ImplementationRemoved exception when specifying :resource option since it is no longer used" do
574
- expect {
575
- CanCan::ControllerResource.new(controller, :resource => Model)
576
- }.to raise_error(CanCan::ImplementationRemoved)
577
- end
578
-
579
- it "raises ImplementationRemoved exception when passing :nested option" do
580
- expect {
581
- CanCan::ControllerResource.new(controller, :nested => :model)
582
- }.to raise_error(CanCan::ImplementationRemoved)
583
- end
584
-
585
- it "skips resource behavior for :only actions in array" do
586
- allow(controller_class).to receive(:cancan_skipper) { {:load => {nil => {:only => [:index, :show]}}} }
587
- params.merge!(:action => "index")
588
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be(true)
589
- expect(CanCan::ControllerResource.new(controller, :some_resource).skip?(:load)).to be(false)
590
- params.merge!(:action => "show")
591
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be(true)
592
- params.merge!(:action => "other_action")
593
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be_falsey
594
- end
595
-
596
- it "skips resource behavior for :only one action on resource" do
597
- allow(controller_class).to receive(:cancan_skipper) { {:authorize => {:model => {:only => :index}}} }
598
- params.merge!(:action => "index")
599
- expect(CanCan::ControllerResource.new(controller).skip?(:authorize)).to be(false)
600
- expect(CanCan::ControllerResource.new(controller, :model).skip?(:authorize)).to be(true)
601
- params.merge!(:action => "other_action")
602
- expect(CanCan::ControllerResource.new(controller, :model).skip?(:authorize)).to be_falsey
603
- end
604
-
605
- it "skips resource behavior :except actions in array" do
606
- allow(controller_class).to receive(:cancan_skipper) { {:load => {nil => {:except => [:index, :show]}}} }
607
- params.merge!(:action => "index")
608
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be_falsey
609
- params.merge!(:action => "show")
610
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be_falsey
611
- params.merge!(:action => "other_action")
612
- expect(CanCan::ControllerResource.new(controller).skip?(:load)).to be(true)
613
- expect(CanCan::ControllerResource.new(controller, :some_resource).skip?(:load)).to be(false)
614
- end
615
-
616
- it "skips resource behavior :except one action on resource" do
617
- allow(controller_class).to receive(:cancan_skipper) { {:authorize => {:model => {:except => :index}}} }
618
- params.merge!(:action => "index")
619
- expect(CanCan::ControllerResource.new(controller, :model).skip?(:authorize)).to be_falsey
620
- params.merge!(:action => "other_action")
621
- expect(CanCan::ControllerResource.new(controller).skip?(:authorize)).to be(false)
622
- expect(CanCan::ControllerResource.new(controller, :model).skip?(:authorize)).to be(true)
623
- end
624
-
625
- it "skips loading and authorization" do
626
- allow(controller_class).to receive(:cancan_skipper) { {:authorize => {nil => {}}, :load => {nil => {}}} }
627
- params.merge!(:action => "new")
628
- resource = CanCan::ControllerResource.new(controller)
629
- expect { resource.load_and_authorize_resource }.not_to raise_error
630
- expect(controller.instance_variable_get(:@model)).to be_nil
631
- end
632
- end
@@ -1,58 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe CanCan::AccessDenied do
4
- describe "with action and subject" do
5
- before(:each) do
6
- @exception = CanCan::AccessDenied.new(nil, :some_action, :some_subject)
7
- end
8
-
9
- it "has action and subject accessors" do
10
- expect(@exception.action).to eq(:some_action)
11
- expect(@exception.subject).to eq(:some_subject)
12
- end
13
-
14
- it "has a changable default message" do
15
- expect(@exception.message).to eq("You are not authorized to access this page.")
16
- @exception.default_message = "Unauthorized!"
17
- expect(@exception.message).to eq("Unauthorized!")
18
- end
19
- end
20
-
21
- describe "with only a message" do
22
- before(:each) do
23
- @exception = CanCan::AccessDenied.new("Access denied!")
24
- end
25
-
26
- it "has nil action and subject" do
27
- expect(@exception.action).to be_nil
28
- expect(@exception.subject).to be_nil
29
- end
30
-
31
- it "has passed message" do
32
- expect(@exception.message).to eq("Access denied!")
33
- end
34
- end
35
-
36
- describe "i18n in the default message" do
37
- after(:each) do
38
- I18n.backend = nil
39
- end
40
-
41
- it "uses i18n for the default message" do
42
- I18n.backend.store_translations :en, :unauthorized => {:default => "This is a different message"}
43
- @exception = CanCan::AccessDenied.new
44
- expect(@exception.message).to eq("This is a different message")
45
- end
46
-
47
- it "defaults to a nice message" do
48
- @exception = CanCan::AccessDenied.new
49
- expect(@exception.message).to eq("You are not authorized to access this page.")
50
- end
51
-
52
- it "does not use translation if a message is given" do
53
- @exception = CanCan::AccessDenied.new("Hey! You're not welcome here")
54
- expect(@exception.message).to eq("Hey! You're not welcome here")
55
- expect(@exception.message).to_not eq("You are not authorized to access this page.")
56
- end
57
- end
58
- end