uhees-declarative_authorization 0.3.1

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 (42) hide show
  1. data/CHANGELOG +77 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +490 -0
  4. data/Rakefile +43 -0
  5. data/app/controllers/authorization_rules_controller.rb +235 -0
  6. data/app/controllers/authorization_usages_controller.rb +23 -0
  7. data/app/helpers/authorization_rules_helper.rb +183 -0
  8. data/app/views/authorization_rules/_change.erb +49 -0
  9. data/app/views/authorization_rules/_show_graph.erb +37 -0
  10. data/app/views/authorization_rules/_suggestion.erb +9 -0
  11. data/app/views/authorization_rules/_suggestions.erb +24 -0
  12. data/app/views/authorization_rules/change.html.erb +124 -0
  13. data/app/views/authorization_rules/graph.dot.erb +68 -0
  14. data/app/views/authorization_rules/graph.html.erb +40 -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 +7 -0
  19. data/garlic_example.rb +20 -0
  20. data/init.rb +5 -0
  21. data/lib/declarative_authorization.rb +15 -0
  22. data/lib/declarative_authorization/authorization.rb +630 -0
  23. data/lib/declarative_authorization/development_support/analyzer.rb +252 -0
  24. data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
  25. data/lib/declarative_authorization/development_support/change_supporter.rb +578 -0
  26. data/lib/declarative_authorization/development_support/development_support.rb +243 -0
  27. data/lib/declarative_authorization/helper.rb +60 -0
  28. data/lib/declarative_authorization/in_controller.rb +367 -0
  29. data/lib/declarative_authorization/in_model.rb +150 -0
  30. data/lib/declarative_authorization/maintenance.rb +188 -0
  31. data/lib/declarative_authorization/obligation_scope.rb +297 -0
  32. data/lib/declarative_authorization/rails_legacy.rb +14 -0
  33. data/lib/declarative_authorization/reader.rb +438 -0
  34. data/test/authorization_test.rb +823 -0
  35. data/test/controller_test.rb +418 -0
  36. data/test/dsl_reader_test.rb +157 -0
  37. data/test/helper_test.rb +154 -0
  38. data/test/maintenance_test.rb +41 -0
  39. data/test/model_test.rb +1171 -0
  40. data/test/schema.sql +53 -0
  41. data/test/test_helper.rb +103 -0
  42. metadata +104 -0
@@ -0,0 +1,418 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+
4
+ class LoadMockObject < MockDataObject
5
+ def self.find(*args)
6
+ new :id => args[0]
7
+ end
8
+ end
9
+
10
+
11
+ ##################
12
+ class SpecificMocksController < MocksController
13
+ filter_access_to :test_action, :require => :test, :context => :permissions
14
+ filter_access_to :test_action_2, :require => :test, :context => :permissions_2
15
+ filter_access_to :show
16
+ filter_access_to :edit, :create, :require => :test, :context => :permissions
17
+ filter_access_to :edit_2, :require => :test, :context => :permissions,
18
+ :attribute_check => true, :model => LoadMockObject
19
+ filter_access_to :new, :require => :test, :context => :permissions
20
+
21
+ filter_access_to [:action_group_action_1, :action_group_action_2]
22
+ define_action_methods :test_action, :test_action_2, :show, :edit, :create,
23
+ :edit_2, :new, :unprotected_action, :action_group_action_1, :action_group_action_2
24
+ end
25
+
26
+ class BasicControllerTest < ActionController::TestCase
27
+ tests SpecificMocksController
28
+
29
+
30
+ def test_filter_access_to_receiving_an_explicit_array
31
+ reader = Authorization::Reader::DSLReader.new
32
+
33
+ reader.parse %{
34
+ authorization do
35
+ role :test_action_group_2 do
36
+ has_permission_on :specific_mocks, :to => :action_group_action_2
37
+ end
38
+ end
39
+ }
40
+
41
+ request!(MockUser.new(:test_action_group_2), "action_group_action_2", reader)
42
+ assert @controller.authorized?
43
+ request!(MockUser.new(:test_action_group_2), "action_group_action_1", reader)
44
+ assert !@controller.authorized?
45
+ request!(nil, "action_group_action_2", reader)
46
+ assert !@controller.authorized?
47
+ end
48
+
49
+ def test_filter_access
50
+ assert !@controller.class.before_filters.empty?
51
+
52
+ reader = Authorization::Reader::DSLReader.new
53
+ reader.parse %{
54
+ authorization do
55
+ role :test_role do
56
+ has_permission_on :permissions, :to => :test
57
+ has_permission_on :specific_mocks, :to => :show
58
+ end
59
+ end
60
+ }
61
+
62
+ request!(MockUser.new(:test_role), "test_action", reader)
63
+ assert @controller.authorized?
64
+
65
+ request!(MockUser.new(:test_role), "test_action_2", reader)
66
+ assert !@controller.authorized?
67
+
68
+ request!(MockUser.new(:test_role_2), "test_action", reader)
69
+ assert_response :forbidden
70
+ assert !@controller.authorized?
71
+
72
+ request!(MockUser.new(:test_role), "show", reader)
73
+ assert @controller.authorized?
74
+ end
75
+
76
+ def test_filter_access_multi_actions
77
+ reader = Authorization::Reader::DSLReader.new
78
+ reader.parse %{
79
+ authorization do
80
+ role :test_role do
81
+ has_permission_on :permissions, :to => :test
82
+ end
83
+ end
84
+ }
85
+ request!(MockUser.new(:test_role), "create", reader)
86
+ assert @controller.authorized?
87
+ end
88
+
89
+ def test_filter_access_unprotected_actions
90
+ reader = Authorization::Reader::DSLReader.new
91
+ reader.parse %{
92
+ authorization do
93
+ role :test_role do
94
+ end
95
+ end
96
+ }
97
+ request!(MockUser.new(:test_role), "unprotected_action", reader)
98
+ assert @controller.authorized?
99
+ end
100
+
101
+ def test_filter_access_priv_hierarchy
102
+ reader = Authorization::Reader::DSLReader.new
103
+ reader.parse %{
104
+ privileges do
105
+ privilege :read do
106
+ includes :list, :show
107
+ end
108
+ end
109
+ authorization do
110
+ role :test_role do
111
+ has_permission_on :specific_mocks, :to => :read
112
+ end
113
+ end
114
+ }
115
+ request!(MockUser.new(:test_role), "show", reader)
116
+ assert @controller.authorized?
117
+ end
118
+
119
+ def test_filter_access_skip_attribute_test
120
+ reader = Authorization::Reader::DSLReader.new
121
+ reader.parse %{
122
+ authorization do
123
+ role :test_role do
124
+ has_permission_on :permissions, :to => :test do
125
+ if_attribute :id => is { user }
126
+ end
127
+ end
128
+ end
129
+ }
130
+ request!(MockUser.new(:test_role), "new", reader)
131
+ assert @controller.authorized?
132
+
133
+ request!(MockUser.new(:test_role), "edit_2", reader)
134
+ assert !@controller.authorized?
135
+ end
136
+
137
+ def test_existing_instance_var_remains_unchanged
138
+ reader = Authorization::Reader::DSLReader.new
139
+ reader.parse %{
140
+ authorization do
141
+ role :test_role do
142
+ has_permission_on :permissions, :to => :test do
143
+ if_attribute :id => is { 5 }
144
+ end
145
+ end
146
+ end
147
+ }
148
+ mock_object = MockDataObject.new(:id => 5)
149
+ @controller.send(:instance_variable_set, :"@load_mock_object",
150
+ mock_object)
151
+ request!(MockUser.new(:test_role), "edit_2", reader)
152
+ assert_equal mock_object,
153
+ @controller.send(:instance_variable_get, :"@load_mock_object")
154
+ assert @controller.authorized?
155
+ end
156
+
157
+ def test_permitted_to_without_context
158
+ reader = Authorization::Reader::DSLReader.new
159
+ reader.parse %{
160
+ authorization do
161
+ role :test_role do
162
+ has_permission_on :specific_mocks, :to => :test
163
+ end
164
+ end
165
+ }
166
+ @controller.current_user = MockUser.new(:test_role)
167
+ @controller.authorization_engine = Authorization::Engine.new(reader)
168
+ assert @controller.permitted_to?(:test)
169
+ end
170
+ end
171
+
172
+
173
+ ##################
174
+ class AllMocksController < MocksController
175
+ filter_access_to :all
176
+ filter_access_to :view, :require => :test, :context => :permissions
177
+ define_action_methods :show, :view
178
+ end
179
+ class AllActionsControllerTest < ActionController::TestCase
180
+ tests AllMocksController
181
+ def test_filter_access_all
182
+ reader = Authorization::Reader::DSLReader.new
183
+ reader.parse %{
184
+ authorization do
185
+ role :test_role do
186
+ has_permission_on :permissions, :to => :test
187
+ has_permission_on :all_mocks, :to => :show
188
+ end
189
+ end
190
+ }
191
+
192
+ request!(MockUser.new(:test_role), "show", reader)
193
+ assert @controller.authorized?
194
+
195
+ request!(MockUser.new(:test_role), "view", reader)
196
+ assert @controller.authorized?
197
+
198
+ request!(MockUser.new(:test_role_2), "show", reader)
199
+ assert !@controller.authorized?
200
+ end
201
+ end
202
+
203
+
204
+ ##################
205
+ class LoadMockObjectsController < MocksController
206
+ filter_access_to :show, :attribute_check => true, :model => LoadMockObject
207
+ filter_access_to :edit, :attribute_check => true
208
+ filter_access_to :update, :delete, :attribute_check => true,
209
+ :load_method => lambda {MockDataObject.new(:test => 1)}
210
+ filter_access_to :create do
211
+ permitted_to! :edit, :load_mock_objects
212
+ end
213
+ filter_access_to :view, :attribute_check => true, :load_method => :load_method
214
+ def load_method
215
+ MockDataObject.new(:test => 2)
216
+ end
217
+ define_action_methods :show, :edit, :update, :delete, :create, :view
218
+ end
219
+ class LoadObjectControllerTest < ActionController::TestCase
220
+ tests LoadMockObjectsController
221
+
222
+ def test_filter_access_with_object_load
223
+ reader = Authorization::Reader::DSLReader.new
224
+ reader.parse %{
225
+ authorization do
226
+ role :test_role do
227
+ has_permission_on :load_mock_objects, :to => [:show, :edit] do
228
+ if_attribute :id => is {"1"}
229
+ end
230
+ end
231
+ end
232
+ }
233
+
234
+ request!(MockUser.new(:test_role), "show", reader, :id => 2)
235
+ assert !@controller.authorized?
236
+
237
+ request!(MockUser.new(:test_role), "show", reader, :id => 1,
238
+ :clear => [:@load_mock_object])
239
+ assert @controller.authorized?
240
+
241
+ request!(MockUser.new(:test_role), "edit", reader, :id => 1,
242
+ :clear => [:@load_mock_object])
243
+ assert @controller.authorized?
244
+ assert @controller.instance_variable_defined?(:@load_mock_object)
245
+ end
246
+
247
+ def test_filter_access_with_object_load_custom
248
+ reader = Authorization::Reader::DSLReader.new
249
+ reader.parse %{
250
+ authorization do
251
+ role :test_role do
252
+ has_permission_on :load_mock_objects, :to => :view do
253
+ if_attribute :test => is {2}
254
+ end
255
+ has_permission_on :load_mock_objects, :to => :update do
256
+ if_attribute :test => is {1}
257
+ end
258
+ has_permission_on :load_mock_objects, :to => :delete do
259
+ if_attribute :test => is {2}
260
+ end
261
+ end
262
+ end
263
+ }
264
+
265
+ request!(MockUser.new(:test_role), "delete", reader)
266
+ assert !@controller.authorized?
267
+
268
+ request!(MockUser.new(:test_role), "view", reader)
269
+ assert @controller.authorized?
270
+
271
+ request!(MockUser.new(:test_role), "update", reader)
272
+ assert @controller.authorized?
273
+ end
274
+
275
+ def test_filter_access_custom
276
+ reader = Authorization::Reader::DSLReader.new
277
+ reader.parse %{
278
+ authorization do
279
+ role :test_role do
280
+ has_permission_on :load_mock_objects, :to => :edit
281
+ end
282
+ role :test_role_2 do
283
+ has_permission_on :load_mock_objects, :to => :create
284
+ end
285
+ end
286
+ }
287
+
288
+ request!(MockUser.new(:test_role), "create", reader)
289
+ assert @controller.authorized?
290
+
291
+ request!(MockUser.new(:test_role_2), "create", reader)
292
+ assert !@controller.authorized?
293
+ end
294
+ end
295
+
296
+
297
+ ##################
298
+ class AccessOverwritesController < MocksController
299
+ filter_access_to :test_action, :test_action_2,
300
+ :require => :test, :context => :permissions_2
301
+ filter_access_to :test_action, :require => :test, :context => :permissions
302
+ define_action_methods :test_action, :test_action_2
303
+ end
304
+ class AccessOverwritesControllerTest < ActionController::TestCase
305
+ def test_filter_access_overwrite
306
+ reader = Authorization::Reader::DSLReader.new
307
+ reader.parse %{
308
+ authorization do
309
+ role :test_role do
310
+ has_permission_on :permissions, :to => :test
311
+ end
312
+ end
313
+ }
314
+ request!(MockUser.new(:test_role), "test_action_2", reader)
315
+ assert !@controller.authorized?
316
+
317
+ request!(MockUser.new(:test_role), "test_action", reader)
318
+ assert @controller.authorized?
319
+ end
320
+ end
321
+
322
+
323
+ ##################
324
+ class PeopleController < MocksController
325
+ filter_access_to :all
326
+ define_action_methods :show
327
+ end
328
+ class PluralizationControllerTest < ActionController::TestCase
329
+ tests PeopleController
330
+
331
+ def test_filter_access_people_controller
332
+ reader = Authorization::Reader::DSLReader.new
333
+ reader.parse %{
334
+ authorization do
335
+ role :test_role do
336
+ has_permission_on :people, :to => :show
337
+ end
338
+ end
339
+ }
340
+ request!(MockUser.new(:test_role), "show", reader)
341
+ assert @controller.authorized?
342
+ end
343
+ end
344
+
345
+
346
+ ##################
347
+ class CommonController < MocksController
348
+ filter_access_to :delete, :context => :common
349
+ filter_access_to :all
350
+ end
351
+ class CommonChild1Controller < CommonController
352
+ filter_access_to :all, :context => :context_1
353
+ end
354
+ class CommonChild2Controller < CommonController
355
+ filter_access_to :delete
356
+ define_action_methods :show
357
+ end
358
+ class HierachicalControllerTest < ActionController::TestCase
359
+ tests CommonChild2Controller
360
+ def test_controller_hierarchy
361
+ reader = Authorization::Reader::DSLReader.new
362
+ reader.parse %{
363
+ authorization do
364
+ role :test_role do
365
+ has_permission_on :mocks, :to => [:delete, :show]
366
+ end
367
+ end
368
+ }
369
+ request!(MockUser.new(:test_role), "show", reader)
370
+ assert !@controller.authorized?
371
+ request!(MockUser.new(:test_role), "delete", reader)
372
+ assert !@controller.authorized?
373
+ end
374
+ end
375
+
376
+ ##################
377
+ module Foo
378
+ class CommonController < MocksController
379
+ filter_access_to :all
380
+ filter_access_to :new
381
+ filter_access_to :show, :namespace => :bar
382
+ filter_access_to :delete, :namespace => true
383
+
384
+ define_action_methods :new, :show, :delete
385
+ end
386
+ end
387
+ class NamespacedControllerTest < ActionController::TestCase
388
+ tests Foo::CommonController
389
+ def test_namespaced_controller
390
+ reader = Authorization::Reader::DSLReader.new
391
+ reader.parse %{
392
+ authorization do
393
+ role :test_role1 do
394
+ has_permission_on :common, :to => [:new, :show, :delete]
395
+ end
396
+ role :test_role2 do
397
+ has_permission_on :common, :to => [:new]
398
+ has_permission_on :bar_common, :to => [:show]
399
+ has_permission_on :foo_common, :to => [:delete]
400
+ end
401
+ end
402
+ }
403
+ request!(MockUser.new(:test_role1), "new", reader)
404
+ assert @controller.authorized?
405
+ request!(MockUser.new(:test_role1), "show", reader)
406
+ assert !@controller.authorized?
407
+ request!(MockUser.new(:test_role1), "delete", reader)
408
+ assert !@controller.authorized?
409
+
410
+ request!(MockUser.new(:test_role2), "new", reader)
411
+ assert @controller.authorized?
412
+ request!(MockUser.new(:test_role2), "show", reader)
413
+ assert @controller.authorized?
414
+ request!(MockUser.new(:test_role2), "delete", reader)
415
+ assert @controller.authorized?
416
+ end
417
+ end
418
+
@@ -0,0 +1,157 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper.rb')
2
+
3
+ class DSLReaderTest < Test::Unit::TestCase
4
+ def test_privileges
5
+ reader = Authorization::Reader::DSLReader.new
6
+ reader.parse %{
7
+ privileges do
8
+ privilege :test_priv do
9
+ includes :lower_priv
10
+ end
11
+ end
12
+ }
13
+ assert_equal 2, reader.privileges_reader.privileges.length
14
+ assert_equal [[:lower_priv, nil]],
15
+ reader.privileges_reader.privilege_hierarchy[:test_priv]
16
+ end
17
+
18
+ def test_privileges_with_context
19
+ reader = Authorization::Reader::DSLReader.new
20
+ reader.parse %{
21
+ privileges do
22
+ privilege :test_priv, :test_context do
23
+ includes :lower_priv
24
+ end
25
+ end
26
+ }
27
+ assert_equal [[:lower_priv, :test_context]],
28
+ reader.privileges_reader.privilege_hierarchy[:test_priv]
29
+ end
30
+
31
+ def test_privileges_one_line
32
+ reader = Authorization::Reader::DSLReader.new
33
+ reader.parse %{
34
+ privileges do
35
+ privilege :test_priv, :test_context, :includes => :lower_priv
36
+ privilege :test_priv_2, :test_context, :includes => [:lower_priv]
37
+ privilege :test_priv_3, :includes => [:lower_priv]
38
+ end
39
+ }
40
+ assert_equal [[:lower_priv, :test_context]],
41
+ reader.privileges_reader.privilege_hierarchy[:test_priv]
42
+ assert_equal [[:lower_priv, :test_context]],
43
+ reader.privileges_reader.privilege_hierarchy[:test_priv_2]
44
+ assert_equal [[:lower_priv, nil]],
45
+ reader.privileges_reader.privilege_hierarchy[:test_priv_3]
46
+ end
47
+
48
+ def test_auth_role
49
+ reader = Authorization::Reader::DSLReader.new
50
+ reader.parse %{
51
+ authorization do
52
+ role :test_role do
53
+ includes :lesser_role
54
+ has_permission_on :items, :to => :read
55
+ end
56
+ end
57
+ }
58
+ assert_equal 1, reader.auth_rules_reader.roles.length
59
+ assert_equal [:lesser_role], reader.auth_rules_reader.role_hierarchy[:test_role]
60
+ assert_equal 1, reader.auth_rules_reader.auth_rules.length
61
+ end
62
+
63
+ def test_auth_role_permit_on
64
+ reader = Authorization::Reader::DSLReader.new
65
+ reader.parse %|
66
+ authorization do
67
+ role :test_role do
68
+ has_permission_on :test_context do
69
+ to :test_perm, :manage
70
+ if_attribute :test_attr => is { user.test_attr }
71
+ end
72
+ end
73
+ end
74
+ |
75
+ assert_equal 1, reader.auth_rules_reader.roles.length
76
+ assert_equal 1, reader.auth_rules_reader.auth_rules.length
77
+ assert reader.auth_rules_reader.auth_rules[0].matches?(:test_role, [:test_perm], :test_context)
78
+ assert reader.auth_rules_reader.auth_rules[0].matches?(:test_role, [:manage], :test_context)
79
+ end
80
+
81
+ def test_permit_block
82
+ reader = Authorization::Reader::DSLReader.new
83
+ reader.parse %|
84
+ authorization do
85
+ role :test_role do
86
+ has_permission_on :perms, :to => :test do
87
+ if_attribute :test_attr => is { user.test_attr }
88
+ if_attribute :test_attr_2 => is_not { user.test_attr }
89
+ if_attribute :test_attr_3 => contains { user.test_attr }
90
+ if_attribute :test_attr_4 => does_not_contain { user.test_attr }
91
+ if_attribute :test_attr_5 => is_in { user.test_attr }
92
+ if_attribute :test_attr_5 => is_not_in { user.test_attr }
93
+ end
94
+ end
95
+ end
96
+ |
97
+ assert_equal 1, reader.auth_rules_reader.roles.length
98
+ assert_equal 1, reader.auth_rules_reader.auth_rules.length
99
+ assert reader.auth_rules_reader.auth_rules[0].matches?(:test_role, [:test], :perms)
100
+ end
101
+
102
+ def test_has_permission_to_with_context
103
+ reader = Authorization::Reader::DSLReader.new
104
+ reader.parse %|
105
+ authorization do
106
+ role :test_role do
107
+ has_permission_on :perms, :to => :test
108
+ end
109
+ end
110
+ |
111
+ assert_equal 1, reader.auth_rules_reader.roles.length
112
+ assert_equal 1, reader.auth_rules_reader.auth_rules.length
113
+ assert reader.auth_rules_reader.auth_rules[0].matches?(:test_role, [:test], :perms)
114
+ end
115
+
116
+ def test_context
117
+ reader = Authorization::Reader::DSLReader.new
118
+ reader.parse %{
119
+ contexts do
120
+ context :high_level_context do
121
+ includes :low_level_context_1, :low_level_context_2
122
+ end
123
+ end
124
+ }
125
+ end
126
+
127
+ def test_dsl_error
128
+ reader = Authorization::Reader::DSLReader.new
129
+ assert_raise(Authorization::Reader::DSLError) do
130
+ reader.parse %{
131
+ authorization do
132
+ includes :lesser_role
133
+ end
134
+ }
135
+ end
136
+ end
137
+
138
+ def test_syntax_error
139
+ reader = Authorization::Reader::DSLReader.new
140
+ assert_raise(Authorization::Reader::DSLSyntaxError) do
141
+ reader.parse %{
142
+ authorizations do
143
+ end
144
+ }
145
+ end
146
+ end
147
+
148
+ def test_syntax_error_2
149
+ reader = Authorization::Reader::DSLReader.new
150
+ assert_raise(Authorization::Reader::DSLSyntaxError) do
151
+ reader.parse %{
152
+ authorizations
153
+ end
154
+ }
155
+ end
156
+ end
157
+ end