zeiv-declarative_authorization 1.0.0.pre

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +189 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +632 -0
  5. data/Rakefile +53 -0
  6. data/app/controllers/authorization_rules_controller.rb +258 -0
  7. data/app/controllers/authorization_usages_controller.rb +22 -0
  8. data/app/helpers/authorization_rules_helper.rb +218 -0
  9. data/app/views/authorization_rules/_change.erb +58 -0
  10. data/app/views/authorization_rules/_show_graph.erb +44 -0
  11. data/app/views/authorization_rules/_suggestions.erb +48 -0
  12. data/app/views/authorization_rules/change.html.erb +169 -0
  13. data/app/views/authorization_rules/graph.dot.erb +68 -0
  14. data/app/views/authorization_rules/graph.html.erb +47 -0
  15. data/app/views/authorization_rules/index.html.erb +17 -0
  16. data/app/views/authorization_usages/index.html.erb +36 -0
  17. data/authorization_rules.dist.rb +20 -0
  18. data/config/routes.rb +20 -0
  19. data/garlic_example.rb +20 -0
  20. data/init.rb +5 -0
  21. data/lib/declarative_authorization.rb +19 -0
  22. data/lib/declarative_authorization/adapters/active_record.rb +13 -0
  23. data/lib/declarative_authorization/adapters/active_record/base_extensions.rb +0 -0
  24. data/lib/declarative_authorization/adapters/active_record/obligation_scope_builder.rb +0 -0
  25. data/lib/declarative_authorization/authorization.rb +798 -0
  26. data/lib/declarative_authorization/development_support/analyzer.rb +261 -0
  27. data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
  28. data/lib/declarative_authorization/development_support/change_supporter.rb +620 -0
  29. data/lib/declarative_authorization/development_support/development_support.rb +243 -0
  30. data/lib/declarative_authorization/helper.rb +68 -0
  31. data/lib/declarative_authorization/in_controller.rb +703 -0
  32. data/lib/declarative_authorization/in_model.rb +188 -0
  33. data/lib/declarative_authorization/maintenance.rb +210 -0
  34. data/lib/declarative_authorization/obligation_scope.rb +361 -0
  35. data/lib/declarative_authorization/rails_legacy.rb +22 -0
  36. data/lib/declarative_authorization/railsengine.rb +6 -0
  37. data/lib/declarative_authorization/reader.rb +546 -0
  38. data/lib/generators/authorization/install/install_generator.rb +77 -0
  39. data/lib/generators/authorization/rules/rules_generator.rb +14 -0
  40. data/lib/generators/authorization/rules/templates/authorization_rules.rb +27 -0
  41. data/lib/tasks/authorization_tasks.rake +89 -0
  42. data/test/authorization_test.rb +1124 -0
  43. data/test/controller_filter_resource_access_test.rb +575 -0
  44. data/test/controller_test.rb +480 -0
  45. data/test/database.yml +3 -0
  46. data/test/dsl_reader_test.rb +178 -0
  47. data/test/helper_test.rb +247 -0
  48. data/test/maintenance_test.rb +46 -0
  49. data/test/model_test.rb +2008 -0
  50. data/test/schema.sql +56 -0
  51. data/test/test_helper.rb +255 -0
  52. metadata +95 -0
@@ -0,0 +1,575 @@
1
+ require 'test_helper'
2
+
3
+ class BasicResource < MockDataObject
4
+ def self.name
5
+ "BasicResource"
6
+ end
7
+ end
8
+ class BasicResourcesController < MocksController
9
+ filter_resource_access :strong_parameters => false
10
+ define_resource_actions
11
+ end
12
+ class BasicResourcesControllerTest < ActionController::TestCase
13
+ def test_basic_filter_index
14
+ reader = Authorization::Reader::DSLReader.new
15
+ reader.parse %{
16
+ authorization do
17
+ role :allowed_role do
18
+ has_permission_on :basic_resources, :to => :index do
19
+ if_attribute :id => is {"1"}
20
+ end
21
+ end
22
+ end
23
+ }
24
+
25
+ allowed_user = MockUser.new(:allowed_role)
26
+ request!(MockUser.new(:another_role), :index, reader)
27
+ assert !@controller.authorized?
28
+ request!(allowed_user, :index, reader)
29
+ assert @controller.authorized?
30
+ end
31
+
32
+ def test_basic_filter_show_with_id
33
+ reader = Authorization::Reader::DSLReader.new
34
+ reader.parse %{
35
+ authorization do
36
+ role :allowed_role do
37
+ has_permission_on :basic_resources, :to => :show do
38
+ if_attribute :id => is {"1"}
39
+ end
40
+ end
41
+ end
42
+ }
43
+
44
+ allowed_user = MockUser.new(:allowed_role)
45
+ request!(allowed_user, :show, reader, :id => "2")
46
+ assert !@controller.authorized?
47
+ request!(allowed_user, :show, reader, :id => "1", :clear => [:@basic_resource])
48
+ assert @controller.authorized?
49
+ end
50
+
51
+ def test_basic_filter_new_with_params
52
+ reader = Authorization::Reader::DSLReader.new
53
+ reader.parse %{
54
+ authorization do
55
+ role :allowed_role do
56
+ has_permission_on :basic_resources, :to => :new do
57
+ if_attribute :id => is {"1"}
58
+ end
59
+ end
60
+ end
61
+ }
62
+
63
+ allowed_user = MockUser.new(:allowed_role)
64
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "2"})
65
+ assert !@controller.authorized?
66
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "1"},
67
+ :clear => [:@basic_resource])
68
+ assert @controller.authorized?
69
+ end
70
+ end
71
+
72
+
73
+ class NestedResource < MockDataObject
74
+ def initialize (attributes = {})
75
+ if attributes[:id]
76
+ attributes[:parent_mock] ||= ParentMock.new(:id => attributes[:id])
77
+ end
78
+ super(attributes)
79
+ end
80
+ def self.name
81
+ "NestedResource"
82
+ end
83
+ end
84
+
85
+ class ShallowNestedResource < MockDataObject
86
+ def initialize (attributes = {})
87
+ if attributes[:id]
88
+ attributes[:parent_mock] ||= ParentMock.new(:id => attributes[:id])
89
+ end
90
+ super(attributes)
91
+ end
92
+ def self.name
93
+ "ShallowNestedResource"
94
+ end
95
+ end
96
+
97
+ class ParentMock < MockDataObject
98
+ def nested_resources
99
+ Class.new do
100
+ def initialize (parent_mock)
101
+ @parent_mock = parent_mock
102
+ end
103
+ def new (attributes = {})
104
+ NestedResource.new(attributes.merge(:parent_mock => @parent_mock))
105
+ end
106
+ end.new(self)
107
+ end
108
+
109
+ alias :shallow_nested_resources :nested_resources
110
+
111
+ def == (other)
112
+ id == other.id
113
+ end
114
+ def self.name
115
+ "ParentMock"
116
+ end
117
+ end
118
+
119
+ class NestedResourcesController < MocksController
120
+ filter_resource_access :nested_in => :parent_mocks, :strong_parameters => false
121
+ define_resource_actions
122
+ end
123
+ class NestedResourcesControllerTest < ActionController::TestCase
124
+ def test_nested_filter_index
125
+ reader = Authorization::Reader::DSLReader.new
126
+ reader.parse %{
127
+ authorization do
128
+ role :allowed_role do
129
+ has_permission_on :nested_resources, :to => :index do
130
+ if_attribute :parent_mock => is {ParentMock.find("1")}
131
+ end
132
+ end
133
+ end
134
+ }
135
+
136
+ allowed_user = MockUser.new(:allowed_role)
137
+ request!(MockUser.new(:another_role), :index, reader, :parent_mock_id => "2")
138
+ assert !@controller.authorized?
139
+ request!(allowed_user, :index, reader, :parent_mock_id => "2",
140
+ :clear => [:@nested_resource, :@parent_mock])
141
+ assert !@controller.authorized?
142
+ request!(allowed_user, :index, reader, :parent_mock_id => "1",
143
+ :clear => [:@nested_resource, :@parent_mock])
144
+ assert @controller.authorized?
145
+ end
146
+
147
+ def test_nested_filter_show_with_id
148
+ reader = Authorization::Reader::DSLReader.new
149
+ reader.parse %{
150
+ authorization do
151
+ role :allowed_role do
152
+ has_permission_on :nested_resources, :to => :show do
153
+ if_attribute :parent_mock => is {ParentMock.find("1")}
154
+ end
155
+ end
156
+ end
157
+ }
158
+
159
+ allowed_user = MockUser.new(:allowed_role)
160
+ request!(allowed_user, :show, reader, :id => "2", :parent_mock_id => "2")
161
+ assert !@controller.authorized?
162
+ request!(allowed_user, :show, reader, :id => "1", :parent_mock_id => "1",
163
+ :clear => [:@nested_resource, :@parent_mock])
164
+ assert @controller.authorized?
165
+ end
166
+
167
+ def test_nested_filter_new_with_params
168
+ reader = Authorization::Reader::DSLReader.new
169
+ reader.parse %{
170
+ authorization do
171
+ role :allowed_role do
172
+ has_permission_on :nested_resources, :to => :new do
173
+ if_attribute :parent_mock => is {ParentMock.find("1")}
174
+ end
175
+ end
176
+ end
177
+ }
178
+
179
+ allowed_user = MockUser.new(:allowed_role)
180
+ request!(allowed_user, :new, reader, :parent_mock_id => "2",
181
+ :nested_resource => {:id => "2"})
182
+ assert !@controller.authorized?
183
+ request!(allowed_user, :new, reader, :parent_mock_id => "1",
184
+ :nested_resource => {:id => "1"},
185
+ :clear => [:@nested_resource, :@parent_mock])
186
+ assert @controller.authorized?
187
+ end
188
+ end
189
+
190
+ class ShallowNestedResourcesController < MocksController
191
+ filter_resource_access :nested_in => :parent_mocks,
192
+ :shallow => true,
193
+ :additional_member => :additional_member_action,
194
+ :strong_parameters => false
195
+ define_resource_actions
196
+ define_action_methods :additional_member_action
197
+ end
198
+ class ShallowNestedResourcesControllerTest < ActionController::TestCase
199
+ def test_nested_filter_index
200
+ reader = Authorization::Reader::DSLReader.new
201
+ reader.parse %{
202
+ authorization do
203
+ role :allowed_role do
204
+ has_permission_on :shallow_nested_resources, :to => :index do
205
+ if_attribute :parent_mock => is {ParentMock.find("1")}
206
+ end
207
+ end
208
+ end
209
+ }
210
+
211
+ allowed_user = MockUser.new(:allowed_role)
212
+ request!(MockUser.new(:another_role), :index, reader, :parent_mock_id => "2")
213
+ assert !@controller.authorized?
214
+ request!(allowed_user, :index, reader, :parent_mock_id => "2",
215
+ :clear => [:@shallow_nested_resource, :@parent_mock])
216
+ assert !@controller.authorized?
217
+ request!(allowed_user, :index, reader, :parent_mock_id => "1",
218
+ :clear => [:@shallow_nested_resource, :@parent_mock])
219
+ assert assigns(:parent_mock)
220
+ assert @controller.authorized?
221
+ end
222
+
223
+ def test_nested_filter_show_with_id
224
+ reader = Authorization::Reader::DSLReader.new
225
+ reader.parse %{
226
+ authorization do
227
+ role :allowed_role do
228
+ has_permission_on :shallow_nested_resources, :to => :show do
229
+ if_attribute :parent_mock => is {ParentMock.find("1")}
230
+ end
231
+ end
232
+ end
233
+ }
234
+
235
+ allowed_user = MockUser.new(:allowed_role)
236
+ request!(allowed_user, :show, reader, :id => "2", :parent_mock_id => "2")
237
+ assert !@controller.authorized?
238
+ request!(allowed_user, :show, reader, :id => "1",
239
+ :clear => [:@shallow_nested_resource, :@parent_mock])
240
+ assert !assigns(:parent_mock)
241
+ assert assigns(:shallow_nested_resource)
242
+ assert @controller.authorized?
243
+ end
244
+
245
+ def test_nested_filter_new_with_params
246
+ reader = Authorization::Reader::DSLReader.new
247
+ reader.parse %{
248
+ authorization do
249
+ role :allowed_role do
250
+ has_permission_on :shallow_nested_resources, :to => :new do
251
+ if_attribute :parent_mock => is {ParentMock.find("1")}
252
+ end
253
+ end
254
+ end
255
+ }
256
+
257
+ allowed_user = MockUser.new(:allowed_role)
258
+ request!(allowed_user, :new, reader, :parent_mock_id => "2",
259
+ :shallow_nested_resource => {:id => "2"})
260
+ assert !@controller.authorized?
261
+ request!(allowed_user, :new, reader, :parent_mock_id => "1",
262
+ :shallow_nested_resource => {:id => "1"},
263
+ :clear => [:@shallow_nested_resource, :@parent_mock])
264
+ assert assigns(:parent_mock)
265
+ assert assigns(:shallow_nested_resource)
266
+ assert @controller.authorized?
267
+ end
268
+
269
+ def test_nested_filter_additional_member_action_with_id
270
+ reader = Authorization::Reader::DSLReader.new
271
+ reader.parse %{
272
+ authorization do
273
+ role :allowed_role do
274
+ has_permission_on :shallow_nested_resources, :to => :additional_member_action do
275
+ if_attribute :parent_mock => is {ParentMock.find("1")}
276
+ end
277
+ end
278
+ end
279
+ }
280
+
281
+ allowed_user = MockUser.new(:allowed_role)
282
+ request!(allowed_user, :additional_member_action, reader, :id => "2", :parent_mock_id => "2")
283
+ assert !@controller.authorized?
284
+ request!(allowed_user, :additional_member_action, reader, :id => "1",
285
+ :clear => [:@shallow_nested_resource, :@parent_mock])
286
+ assert !assigns(:parent_mock)
287
+ assert assigns(:shallow_nested_resource)
288
+ assert @controller.authorized?
289
+ end
290
+ end
291
+
292
+
293
+ class CustomMembersCollectionsResourceController < MocksController
294
+ def self.controller_name
295
+ "basic_resources"
296
+ end
297
+ filter_resource_access :member => [[:other_show, :read]],
298
+ :collection => {:search => :read}, :new => [:other_new], :strong_parameters => false
299
+ define_action_methods :other_new, :search, :other_show
300
+ end
301
+ class CustomMembersCollectionsResourceControllerTest < ActionController::TestCase
302
+ def test_custom_members_filter_search
303
+ reader = Authorization::Reader::DSLReader.new
304
+ reader.parse %{
305
+ authorization do
306
+ role :allowed_role do
307
+ has_permission_on :basic_resources, :to => :read do
308
+ if_attribute :id => is {"1"}
309
+ end
310
+ end
311
+ end
312
+ }
313
+
314
+ request!(MockUser.new(:another_role), :search, reader)
315
+ assert !@controller.authorized?
316
+ request!(MockUser.new(:allowed_role), :search, reader)
317
+ assert @controller.authorized?
318
+ end
319
+
320
+ def test_custom_members_filter_other_show
321
+ reader = Authorization::Reader::DSLReader.new
322
+ reader.parse %{
323
+ authorization do
324
+ role :allowed_role do
325
+ has_permission_on :basic_resources, :to => :read do
326
+ if_attribute :id => is {"1"}
327
+ end
328
+ end
329
+ end
330
+ }
331
+
332
+ allowed_user = MockUser.new(:allowed_role)
333
+ request!(allowed_user, :other_show, reader, :id => "2")
334
+ assert !@controller.authorized?
335
+ request!(allowed_user, :other_show, reader, :id => "1", :clear => [:@basic_resource])
336
+ assert @controller.authorized?
337
+ end
338
+
339
+ def test_custom_members_filter_other_new
340
+ reader = Authorization::Reader::DSLReader.new
341
+ reader.parse %{
342
+ authorization do
343
+ role :allowed_role do
344
+ has_permission_on :basic_resources, :to => :other_new do
345
+ if_attribute :id => is {"1"}
346
+ end
347
+ end
348
+ end
349
+ }
350
+
351
+ allowed_user = MockUser.new(:allowed_role)
352
+ request!(allowed_user, :other_new, reader, :basic_resource => {:id => "2"})
353
+ assert !@controller.authorized?
354
+ request!(allowed_user, :other_new, reader, :basic_resource => {:id => "1"},
355
+ :clear => [:@basic_resource])
356
+ assert @controller.authorized?
357
+ end
358
+ end
359
+
360
+
361
+ class AdditionalMembersCollectionsResourceController < MocksController
362
+ def self.controller_name
363
+ "basic_resources"
364
+ end
365
+ filter_resource_access :additional_member => :other_show,
366
+ :additional_collection => [:search], :additional_new => {:other_new => :new}, :strong_parameters => false
367
+ define_resource_actions
368
+ define_action_methods :other_new, :search, :other_show
369
+ end
370
+ class AdditionalMembersCollectionsResourceControllerTest < ActionController::TestCase
371
+ def test_additional_members_filter_search_index
372
+ reader = Authorization::Reader::DSLReader.new
373
+ reader.parse %{
374
+ authorization do
375
+ role :allowed_role do
376
+ has_permission_on :basic_resources, :to => [:search, :index] do
377
+ if_attribute :id => is {"1"}
378
+ end
379
+ end
380
+ end
381
+ }
382
+
383
+ request!(MockUser.new(:another_role), :search, reader)
384
+ assert !@controller.authorized?
385
+ request!(MockUser.new(:another_role), :index, reader)
386
+ assert !@controller.authorized?
387
+ request!(MockUser.new(:allowed_role), :search, reader)
388
+ assert @controller.authorized?
389
+ request!(MockUser.new(:allowed_role), :index, reader)
390
+ assert @controller.authorized?
391
+ end
392
+
393
+ def test_additional_members_filter_other_show
394
+ reader = Authorization::Reader::DSLReader.new
395
+ reader.parse %{
396
+ authorization do
397
+ role :allowed_role do
398
+ has_permission_on :basic_resources, :to => [:show, :other_show] do
399
+ if_attribute :id => is {"1"}
400
+ end
401
+ end
402
+ end
403
+ }
404
+
405
+ allowed_user = MockUser.new(:allowed_role)
406
+ request!(allowed_user, :other_show, reader, :id => "2")
407
+ assert !@controller.authorized?
408
+ request!(allowed_user, :show, reader, :id => "2", :clear => [:@basic_resource])
409
+ assert !@controller.authorized?
410
+ request!(allowed_user, :other_show, reader, :id => "1", :clear => [:@basic_resource])
411
+ assert @controller.authorized?
412
+ request!(allowed_user, :show, reader, :id => "1", :clear => [:@basic_resource])
413
+ assert @controller.authorized?
414
+ end
415
+
416
+ def test_additional_members_filter_other_new
417
+ reader = Authorization::Reader::DSLReader.new
418
+ reader.parse %{
419
+ authorization do
420
+ role :allowed_role do
421
+ has_permission_on :basic_resources, :to => :new do
422
+ if_attribute :id => is {"1"}
423
+ end
424
+ end
425
+ end
426
+ }
427
+
428
+ allowed_user = MockUser.new(:allowed_role)
429
+ request!(allowed_user, :other_new, reader, :basic_resource => {:id => "2"})
430
+ assert !@controller.authorized?
431
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "2"},
432
+ :clear => [:@basic_resource])
433
+ assert !@controller.authorized?
434
+
435
+ request!(allowed_user, :other_new, reader, :basic_resource => {:id => "1"},
436
+ :clear => [:@basic_resource])
437
+ assert @controller.authorized?
438
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "1"},
439
+ :clear => [:@basic_resource])
440
+ assert @controller.authorized?
441
+ end
442
+ end
443
+
444
+
445
+ class CustomMethodsResourceController < MocksController
446
+ # not implemented yet
447
+ end
448
+
449
+
450
+ class ExplicitContextResourceController < MocksController
451
+ filter_resource_access :context => :basic_resources, :strong_parameters => false
452
+ define_resource_actions
453
+ end
454
+ class ExplicitContextResourceControllerTest < ActionController::TestCase
455
+ def test_explicit_context_filter_index
456
+ reader = Authorization::Reader::DSLReader.new
457
+ reader.parse %{
458
+ authorization do
459
+ role :allowed_role do
460
+ has_permission_on :basic_resources, :to => :index do
461
+ if_attribute :id => is {"1"}
462
+ end
463
+ end
464
+ end
465
+ }
466
+
467
+ allowed_user = MockUser.new(:allowed_role)
468
+ request!(MockUser.new(:another_role), :index, reader)
469
+ assert !@controller.authorized?
470
+ request!(allowed_user, :index, reader)
471
+ assert @controller.authorized?
472
+ end
473
+
474
+ def test_explicit_context_filter_show_with_id
475
+ reader = Authorization::Reader::DSLReader.new
476
+ reader.parse %{
477
+ authorization do
478
+ role :allowed_role do
479
+ has_permission_on :basic_resources, :to => :show do
480
+ if_attribute :id => is {"1"}
481
+ end
482
+ end
483
+ end
484
+ }
485
+
486
+ allowed_user = MockUser.new(:allowed_role)
487
+ request!(allowed_user, :show, reader, :id => "2")
488
+ assert !@controller.authorized?
489
+ request!(allowed_user, :show, reader, :id => "1", :clear => [:@basic_resource])
490
+ assert @controller.authorized?
491
+ end
492
+
493
+ def test_explicit_context_filter_new_with_params
494
+ reader = Authorization::Reader::DSLReader.new
495
+ reader.parse %{
496
+ authorization do
497
+ role :allowed_role do
498
+ has_permission_on :basic_resources, :to => :new do
499
+ if_attribute :id => is {"1"}
500
+ end
501
+ end
502
+ end
503
+ }
504
+
505
+ allowed_user = MockUser.new(:allowed_role)
506
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "2"})
507
+ assert !@controller.authorized?
508
+ request!(allowed_user, :new, reader, :basic_resource => {:id => "1"},
509
+ :clear => [:@basic_resource])
510
+ assert @controller.authorized?
511
+ end
512
+ end
513
+
514
+ if Rails.version >= '4'
515
+
516
+ class StrongResource < MockDataObject
517
+ def self.name
518
+ "StrongResource"
519
+ end
520
+ end
521
+
522
+ class StrongResourcesController < MocksController
523
+ def self.controller_name
524
+ "strong_resources"
525
+ end
526
+ filter_resource_access :strong_parameters => true
527
+ define_resource_actions
528
+
529
+ private
530
+ def strong_resource_params
531
+ params.require(:strong_resource).permit(:test_param1, :test_param2)
532
+ end
533
+ end
534
+ class StrongResourcesControllerTest < ActionController::TestCase
535
+ def test_still_authorized_with_strong_params
536
+ reader = Authorization::Reader::DSLReader.new
537
+ reader.parse %{
538
+ authorization do
539
+ role :allowed_role do
540
+ has_permission_on :strong_resources, :to => :show do
541
+ if_attribute :id => "1"
542
+ end
543
+ end
544
+ end
545
+ }
546
+
547
+ allowed_user = MockUser.new(:allowed_role)
548
+ request!(allowed_user, :show, reader, :id => "2")
549
+ assert !@controller.authorized?
550
+ request!(allowed_user, :show, reader, :id => "1", :clear => [:@strong_resource])
551
+ assert @controller.authorized?
552
+ end
553
+
554
+ def test_new_strong_resource
555
+ reader = Authorization::Reader::DSLReader.new
556
+ reader.parse %{
557
+ authorization do
558
+ role :allowed_role do
559
+ has_permission_on :strong_resources, :to => :new
560
+ end
561
+ end
562
+ }
563
+
564
+ allowed_user = MockUser.new(:allowed_role)
565
+ request!(allowed_user, :new, reader, :strong_resource => {:id => "1"},
566
+ :clear => [:@strong_resource])
567
+ assert @controller.authorized?
568
+
569
+ # allowed_user = MockUser.new(:allowed_role)
570
+ # request!(allowed_user, :new, reader, :strong_resource => {:id => "1"}, :clear => [:@strong_resource])
571
+ # assert @controller.authorized?
572
+ # assert assigns :strong_resource
573
+ end
574
+ end
575
+ end