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,77 @@
1
+ require 'rails/generators'
2
+ module Authorization
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ include Rails::Generators::Migration
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ argument :name, type: :string, default: "User"
9
+ argument :attributes, type: :array, default: ['name:string'], banner: "field[:type] field[:type]"
10
+ class_option :create_user, type: :boolean, default: false, desc: "Creates the defined User model with attributes given."
11
+ class_option :commit, type: :boolean, default: false, desc: "Performs rake tasks such as migrate and seed."
12
+ class_option :user_belongs_to_role, type: :boolean, default: false, desc: "Users have only one role, which can inherit others roles."
13
+
14
+ def self.next_migration_number dirname
15
+ if ActiveRecord::Base.timestamped_migrations
16
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
17
+ else
18
+ "%.3d" % (current_migration_number(dirname) + 1)
19
+ end
20
+ end
21
+
22
+ def install_decl_auth
23
+ habtm_table_name = "#{name.pluralize}" <= "Roles" ? "#{name.pluralize}Roles" : "Roles#{name.pluralize}" unless options[:user_belongs_to_role]
24
+ habtm_file_glob = "#{name.pluralize}" <= "Roles" ? 'db/migrate/*create_*_roles*' : 'db/migrate/*create_roles_*' unless options[:user_belongs_to_role]
25
+
26
+ generate 'model', "#{name} #{attributes.join(' ')}" if options[:create_user]
27
+ generate 'model', 'Role title:string'
28
+
29
+ if options[:user_belongs_to_role]
30
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", " belongs_to :role\n", after: "ActiveRecord::Base\n"
31
+ generate 'migration', "AddRoleIdTo#{name.camelcase} role_id:integer"
32
+ else
33
+ generate 'migration', "Create#{habtm_table_name} #{name.downcase}:integer role:integer"
34
+ gsub_file Dir.glob(habtm_file_glob).last, 'integer', 'references'
35
+ inject_into_file Dir.glob(habtm_file_glob).last, ", id: false", before: ' do |t|'
36
+ inject_into_file "app/models/role.rb", " has_and_belongs_to_many :#{name.downcase.pluralize}\n", after: "ActiveRecord::Base\n"
37
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", " has_and_belongs_to_many :roles\n", after: "ActiveRecord::Base\n"
38
+ end
39
+
40
+ rake 'db:migrate' if options[:commit]
41
+
42
+ if options[:user_belongs_to_role]
43
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", before: "\nend" do <<-'RUBY'
44
+
45
+
46
+ def role_symbols
47
+ [role.title.to_sym]
48
+ end
49
+ RUBY
50
+ end
51
+ else
52
+ inject_into_file "app/models/#{name.singularize.downcase}.rb", before: "\nend" do <<-'RUBY'
53
+
54
+
55
+ def role_symbols
56
+ (roles || []).map {|r| r.title.to_sym}
57
+ end
58
+ RUBY
59
+ end
60
+ end
61
+
62
+ inject_into_file 'db/seeds.rb', after: ".first)\n" do <<-'RUBY'
63
+
64
+ roles = Role.create([
65
+ {title: 'admin'},
66
+ {title: 'user'}
67
+ ]) if Role.count == 0
68
+ RUBY
69
+ end
70
+
71
+ rake 'db:seed' if options[:commit]
72
+
73
+ generate 'authorization:rules'
74
+ puts "Please run `rake db:migrate` and `rake db:seed` to finish installing." unless options[:commit]
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails/generators'
2
+ module Authorization
3
+ class RulesGenerator < Rails::Generators::Base
4
+
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def copy_auth_rules
8
+
9
+ puts "WARNING - Copying authorization_rules template. Make sure to back up any existing rules before overwriting."
10
+
11
+ copy_file "authorization_rules.rb", "config/authorization_rules.rb"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ authorization do
2
+ role :guest do
3
+ # add permissions for guests here, e.g.
4
+ # has_permission_on :conferences, :to => :read
5
+ end
6
+
7
+ # permissions on other roles, such as
8
+ # role :admin do
9
+ # has_permission_on :conferences, :to => :manage
10
+ # end
11
+ # role :user do
12
+ # has_permission_on :conferences, :to => [:read, :create]
13
+ # has_permission_on :conferences, :to => [:update, :delete] do
14
+ # if_attribute :user_id => is {user.id}
15
+ # end
16
+ # end
17
+ # See the readme or GitHub for more examples
18
+ end
19
+
20
+ privileges do
21
+ # default privilege hierarchies to facilitate RESTful Rails apps
22
+ privilege :manage, :includes => [:create, :read, :update, :delete]
23
+ privilege :read, :includes => [:index, :show]
24
+ privilege :create, :includes => :new
25
+ privilege :update, :includes => :edit
26
+ privilege :delete, :includes => :destroy
27
+ end
@@ -0,0 +1,89 @@
1
+ namespace :auth do
2
+ desc "Lists all privileges used in controllers, views, models"
3
+ task :used_privileges do
4
+ # TODO note where privileges are used
5
+ require File.join(Rails.root, 'config', 'boot.rb')
6
+ require File.join(Rails.root, 'config', 'environment.rb')
7
+ controllers = [ApplicationController]
8
+ Dir.new("#{Rails.root}/app/controllers").entries.each do |controller_file|
9
+ if controller_file =~ /_controller/
10
+ controllers << controller_file.gsub(".rb","").camelize.constantize
11
+ end
12
+ end
13
+ perms = controllers.select {|c| c.send(:class_variable_defined?, :@@permissions)}.
14
+ inject([]) do |all, c|
15
+ contr_context = c.name.sub("Controller", "").tableize.to_sym
16
+ contr_perms = c.send(:class_variable_get, :@@permissions).collect do |cp|
17
+ [cp.privilege, cp.context || contr_context, cp]
18
+ end
19
+ if contr_perms.any? {|cp| cp[0].nil?}
20
+ contr_perms += c.send(:action_methods).collect {|am| am.to_sym}.
21
+ reject {|am| contr_perms.any? {|cp| cp[2].actions.include?(am)}}.
22
+ collect {|am| [am, contr_context]}
23
+ end
24
+ all += contr_perms.reject {|cp| cp[0].nil?}.collect {|cp| cp[0..1]}
25
+ end
26
+
27
+ model_all = `grep -l "Base\.using_access_control" #{Rails.root}/config/*.rb #{Rails.root}/config/initializers/*.rb`.split("\n")
28
+ if model_all.count > 0
29
+ model_files = Dir.glob( "#{Rails.root}/app/models/*.rb").reject do |item|
30
+ item.match(/_observer\.rb/)
31
+ end
32
+ else
33
+ model_files = `grep -l "^[[:space:]]*using_access_control" #{Rails.root}/app/models/*.rb`.split("\n")
34
+ end
35
+ models_with_ac = model_files.collect {|mf| mf.sub(/^.*\//, "").sub(".rb", "").tableize.to_sym}
36
+ model_security_privs = [:create, :read, :update, :delete]
37
+ models_with_ac.each {|m| perms += model_security_privs.collect{|msp| [msp, m]}}
38
+
39
+ grep_file_pattern = "#{Rails.root}/app/models/*.rb #{Rails.root}/app/views/**/* #{Rails.root}/app/controllers/*.rb"
40
+ `grep "permitted_to?" #{grep_file_pattern}`.split("\n").each do |ptu|
41
+ file, grep_match = ptu.split(':', 2)
42
+ context = privilege = nil
43
+ if (match = grep_match.match(/permitted_to\?\(?\s*:(\w+),\s*(:?@?\w+)/))
44
+ privilege = match[1].to_sym
45
+ if match[2][0..0] == ':'
46
+ context = match[2][1..-1].to_sym
47
+ else
48
+ c = (match[2][0..0] == '@' ? match[2][1..-1] : match[2]).pluralize.to_sym
49
+ context = c if perms.any? {|p| p[1] == c}
50
+ end
51
+ end
52
+ if privilege.nil? or context.nil?
53
+ puts "Could not handle: #{ptu}"
54
+ else
55
+ perms << [privilege, context]
56
+ end
57
+ end
58
+
59
+ `grep ".with_permissions_to" #{grep_file_pattern}`.split("\n").each do |wpt|
60
+ file, grep_match = wpt.split(':', 2)
61
+ context = privilege = nil
62
+ if match = grep_match.match(/(\w+\.)?with_permissions_to(\(:\w+)?/)
63
+ c = match[1][0..-2].tableize.to_sym if match[1]
64
+ c ||= File.basename(file, '.rb').tableize.to_sym
65
+ context = c if perms.any? {|p| p[1] == c}
66
+ privilege = match[2] && match[2][(match[2][0..0]=='(' ? 2 : 1)..-1].to_sym
67
+ privilege ||= :read
68
+ end
69
+ if privilege.nil? or context.nil?
70
+ puts "Could not handle: #{wpt}"
71
+ else
72
+ perms << [privilege, context]
73
+ end
74
+ end
75
+
76
+ perms.uniq!
77
+ perm_hash = {}
78
+ perms.each do |cp|
79
+ perm_hash[cp[1]] ||= []
80
+ perm_hash[cp[1]] << cp[0]
81
+ end
82
+
83
+ puts "Privileges currently in use:"
84
+ perm_hash.each do |context, privileges|
85
+ puts " #{context.inspect}:\t#{privileges.collect {|p| p.inspect}.sort * ', '}"
86
+ #privileges.collect {|p| p.inspect}.sort.each {|p| puts " #{p}"}
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,1124 @@
1
+ require 'test_helper'
2
+
3
+ class AuthorizationTest < Test::Unit::TestCase
4
+
5
+ def test_permit
6
+ reader = Authorization::Reader::DSLReader.new
7
+ reader.parse %{
8
+ authorization do
9
+ role :test_role do
10
+ has_permission_on :permissions, :to => :test
11
+ end
12
+ end
13
+ }
14
+ engine = Authorization::Engine.new(reader)
15
+ assert engine.permit?(:test, :context => :permissions,
16
+ :user => MockUser.new(:test_role, :test_role_2))
17
+ assert !engine.permit?(:test_2, :context => :permissions_2,
18
+ :user => MockUser.new(:test_role))
19
+ assert !engine.permit?(:test, :context => :permissions,
20
+ :user => MockUser.new(:test_role_2))
21
+ end
22
+
23
+ def test_permit_context_people
24
+ reader = Authorization::Reader::DSLReader.new
25
+ reader.parse %{
26
+ authorization do
27
+ role :test_role do
28
+ has_permission_on :people, :to => :test
29
+ end
30
+ end
31
+ }
32
+ engine = Authorization::Engine.new(reader)
33
+ assert engine.permit?(:test, :context => :people,
34
+ :user => MockUser.new(:test_role))
35
+ end
36
+
37
+ def test_permit_with_has_omnipotence
38
+ reader = Authorization::Reader::DSLReader.new
39
+ reader.parse %{
40
+ authorization do
41
+ role :admin do
42
+ has_omnipotence
43
+ end
44
+ end
45
+ }
46
+ engine = Authorization::Engine.new(reader)
47
+ assert engine.permit?(:test, :context => :people,
48
+ :user => MockUser.new(:admin))
49
+ end
50
+
51
+ def test_permit_multiple_contexts
52
+ reader = Authorization::Reader::DSLReader.new
53
+ reader.parse %{
54
+ authorization do
55
+ role :test_role do
56
+ has_permission_on [:permissions, :permissions_2], :to => :test
57
+ has_permission_on :permissions_4, :permissions_5, :to => :test
58
+ end
59
+ end
60
+ }
61
+ engine = Authorization::Engine.new(reader)
62
+ assert engine.permit?(:test, :context => :permissions,
63
+ :user => MockUser.new(:test_role))
64
+ assert engine.permit?(:test, :context => :permissions_2,
65
+ :user => MockUser.new(:test_role))
66
+ assert !engine.permit?(:test, :context => :permissions_3,
67
+ :user => MockUser.new(:test_role))
68
+
69
+ assert engine.permit?(:test, :context => :permissions_4, :user => MockUser.new(:test_role))
70
+ assert engine.permit?(:test, :context => :permissions_5, :user => MockUser.new(:test_role))
71
+ end
72
+
73
+ def test_permit_with_frozen_roles
74
+ reader = Authorization::Reader::DSLReader.new
75
+ reader.parse %{
76
+ authorization do
77
+ role :other_role do
78
+ includes :test_role
79
+ end
80
+ role :test_role do
81
+ has_permission_on :permissions, :to => :test
82
+ end
83
+ end
84
+ }
85
+ engine = Authorization::Engine.new(reader)
86
+ roles = [:other_role].freeze
87
+ assert_nothing_raised do
88
+ assert engine.permit?(:test, :context => :permissions,
89
+ :user => MockUser.new(:role_symbols => roles))
90
+ end
91
+ end
92
+
93
+ def test_obligations_without_conditions
94
+ reader = Authorization::Reader::DSLReader.new
95
+ reader.parse %{
96
+ authorization do
97
+ role :test_role do
98
+ has_permission_on :permissions, :to => :test
99
+ end
100
+ end
101
+ }
102
+ engine = Authorization::Engine.new(reader)
103
+ assert_equal [{}], engine.obligations(:test, :context => :permissions,
104
+ :user => MockUser.new(:test_role))
105
+ end
106
+
107
+ def test_obligations_with_conditions
108
+ reader = Authorization::Reader::DSLReader.new
109
+ reader.parse %{
110
+ authorization do
111
+ role :test_role do
112
+ has_permission_on :permissions, :to => :test do
113
+ if_attribute :attr => is { user.attr }
114
+ end
115
+ end
116
+ end
117
+ }
118
+ engine = Authorization::Engine.new(reader)
119
+ assert_equal [{:attr => [:is, 1]}],
120
+ engine.obligations(:test, :context => :permissions,
121
+ :user => MockUser.new(:test_role, :attr => 1))
122
+ end
123
+
124
+ def test_obligations_with_omnipotence
125
+ reader = Authorization::Reader::DSLReader.new
126
+ reader.parse %{
127
+ authorization do
128
+ role :admin do
129
+ has_omnipotence
130
+ end
131
+ role :test_role do
132
+ has_permission_on :permissions, :to => :test do
133
+ if_attribute :attr => is { user.attr }
134
+ end
135
+ end
136
+ end
137
+ }
138
+ engine = Authorization::Engine.new(reader)
139
+ assert_equal [],
140
+ engine.obligations(:test, :context => :permissions,
141
+ :user => MockUser.new(:test_role, :admin, :attr => 1))
142
+ end
143
+
144
+ def test_obligations_with_anded_conditions
145
+ reader = Authorization::Reader::DSLReader.new
146
+ reader.parse %{
147
+ authorization do
148
+ role :test_role do
149
+ has_permission_on :permissions, :to => :test, :join_by => :and do
150
+ if_attribute :attr => is { user.attr }
151
+ if_attribute :attr_2 => is { user.attr_2 }
152
+ end
153
+ end
154
+ end
155
+ }
156
+ engine = Authorization::Engine.new(reader)
157
+ assert_equal [{:attr => [:is, 1], :attr_2 => [:is, 2]}],
158
+ engine.obligations(:test, :context => :permissions,
159
+ :user => MockUser.new(:test_role, :attr => 1, :attr_2 => 2))
160
+ end
161
+
162
+ def test_obligations_with_deep_anded_conditions
163
+ reader = Authorization::Reader::DSLReader.new
164
+ reader.parse %{
165
+ authorization do
166
+ role :test_role do
167
+ has_permission_on :permissions, :to => :test, :join_by => :and do
168
+ if_attribute :attr => { :deeper_attr => is { user.deeper_attr }}
169
+ if_attribute :attr => { :deeper_attr_2 => is { user.deeper_attr_2 }}
170
+ end
171
+ end
172
+ end
173
+ }
174
+ engine = Authorization::Engine.new(reader)
175
+ assert_equal [{:attr => { :deeper_attr => [:is, 1], :deeper_attr_2 => [:is, 2] } }],
176
+ engine.obligations(:test, :context => :permissions,
177
+ :user => MockUser.new(:test_role, :deeper_attr => 1, :deeper_attr_2 => 2))
178
+ end
179
+
180
+ def test_obligations_with_has_many
181
+ reader = Authorization::Reader::DSLReader.new
182
+ reader.parse %{
183
+ authorization do
184
+ role :test_role do
185
+ has_permission_on :permissions, :to => :test do
186
+ if_attribute :attrs => { :deeper_attr => is { user.deeper_attr } }
187
+ end
188
+ end
189
+ end
190
+ }
191
+ engine = Authorization::Engine.new(reader)
192
+ assert_equal [{:attrs => {:deeper_attr => [:is, 1]}}],
193
+ engine.obligations(:test, :context => :permissions,
194
+ :user => MockUser.new(:test_role, :deeper_attr => 1))
195
+ end
196
+
197
+ def test_obligations_with_conditions_and_empty
198
+ reader = Authorization::Reader::DSLReader.new
199
+ reader.parse %{
200
+ authorization do
201
+ role :test_role do
202
+ has_permission_on :permissions, :to => :test
203
+ has_permission_on :permissions, :to => :test do
204
+ if_attribute :attr => is { user.attr }
205
+ end
206
+ end
207
+ end
208
+ }
209
+ engine = Authorization::Engine.new(reader)
210
+ assert_equal [{}, {:attr => [:is, 1]}],
211
+ engine.obligations(:test, :context => :permissions,
212
+ :user => MockUser.new(:test_role, :attr => 1))
213
+ end
214
+
215
+ def test_obligations_with_permissions
216
+ reader = Authorization::Reader::DSLReader.new
217
+ reader.parse %{
218
+ authorization do
219
+ role :test_role do
220
+ has_permission_on :permissions, :to => :test do
221
+ if_attribute :attr => is { user.attr }
222
+ end
223
+ has_permission_on :permission_children, :to => :test do
224
+ if_permitted_to :test, :permission, :context => :permissions
225
+ end
226
+ has_permission_on :permission_children_2, :to => :test do
227
+ if_permitted_to :test, :permission
228
+ end
229
+ has_permission_on :permission_children_children, :to => :test do
230
+ if_permitted_to :test, :permission_child => :permission,
231
+ :context => :permissions
232
+ end
233
+ end
234
+ end
235
+ }
236
+ engine = Authorization::Engine.new(reader)
237
+ assert_equal [{:permission => {:attr => [:is, 1]}}],
238
+ engine.obligations(:test, :context => :permission_children,
239
+ :user => MockUser.new(:test_role, :attr => 1))
240
+ assert_equal [{:permission => {:attr => [:is, 1]}}],
241
+ engine.obligations(:test, :context => :permission_children_2,
242
+ :user => MockUser.new(:test_role, :attr => 1))
243
+ assert_equal [{:permission_child => {:permission => {:attr => [:is, 1]}}}],
244
+ engine.obligations(:test, :context => :permission_children_children,
245
+ :user => MockUser.new(:test_role, :attr => 1))
246
+ end
247
+
248
+ def test_obligations_with_has_many_permissions
249
+ reader = Authorization::Reader::DSLReader.new
250
+ reader.parse %{
251
+ authorization do
252
+ role :test_role do
253
+ has_permission_on :permissions, :to => :test do
254
+ if_attribute :attr => is { user.attr }
255
+ end
256
+ has_permission_on :permission_children, :to => :test do
257
+ if_permitted_to :test, :permissions, :context => :permissions
258
+ end
259
+ has_permission_on :permission_children_2, :to => :test do
260
+ if_permitted_to :test, :permissions
261
+ end
262
+ has_permission_on :permission_children_children, :to => :test do
263
+ if_permitted_to :test, :permission_child => :permissions,
264
+ :context => :permissions
265
+ end
266
+ end
267
+ end
268
+ }
269
+ engine = Authorization::Engine.new(reader)
270
+ assert_equal [{:permissions => {:attr => [:is, 1]}}],
271
+ engine.obligations(:test, :context => :permission_children,
272
+ :user => MockUser.new(:test_role, :attr => 1))
273
+ assert_equal [{:permissions => {:attr => [:is, 1]}}],
274
+ engine.obligations(:test, :context => :permission_children_2,
275
+ :user => MockUser.new(:test_role, :attr => 1))
276
+ assert_equal [{:permission_child => {:permissions => {:attr => [:is, 1]}}}],
277
+ engine.obligations(:test, :context => :permission_children_children,
278
+ :user => MockUser.new(:test_role, :attr => 1))
279
+ end
280
+
281
+ def test_obligations_with_permissions_multiple
282
+ reader = Authorization::Reader::DSLReader.new
283
+ reader.parse %{
284
+ authorization do
285
+ role :test_role do
286
+ has_permission_on :permissions, :to => :test do
287
+ if_attribute :attr => is { 1 }
288
+ if_attribute :attr => is { 2 }
289
+ end
290
+ has_permission_on :permission_children_children, :to => :test do
291
+ if_permitted_to :test, :permission_child => :permission
292
+ end
293
+ end
294
+ end
295
+ }
296
+ engine = Authorization::Engine.new(reader)
297
+ assert_equal [{:permission_child => {:permission => {:attr => [:is, 1]}}},
298
+ {:permission_child => {:permission => {:attr => [:is, 2]}}}],
299
+ engine.obligations(:test, :context => :permission_children_children,
300
+ :user => MockUser.new(:test_role))
301
+ end
302
+
303
+ def test_obligations_with_permissions_and_anded_conditions
304
+ reader = Authorization::Reader::DSLReader.new
305
+ reader.parse %{
306
+ authorization do
307
+ role :test_role do
308
+ has_permission_on :permission_children, :to => :test, :join_by => :and do
309
+ if_permitted_to :test, :permission
310
+ if_attribute :test_attr => 1
311
+ end
312
+ has_permission_on :permissions, :to => :test do
313
+ if_attribute :test_attr => 1
314
+ end
315
+ end
316
+ end
317
+ }
318
+ engine = Authorization::Engine.new(reader)
319
+
320
+ assert_equal [{:test_attr => [:is, 1], :permission => {:test_attr => [:is, 1]}}],
321
+ engine.obligations(:test, :context => :permission_children,
322
+ :user => MockUser.new(:test_role))
323
+ end
324
+
325
+ def test_guest_user
326
+ reader = Authorization::Reader::DSLReader.new
327
+ reader.parse %{
328
+ authorization do
329
+ role :guest do
330
+ has_permission_on :permissions, :to => :test
331
+ end
332
+ end
333
+ }
334
+ engine = Authorization::Engine.new(reader)
335
+ assert engine.permit?(:test, :context => :permissions)
336
+ assert !engine.permit?(:test, :context => :permissions_2)
337
+ end
338
+
339
+ def test_default_role
340
+ previous_default_role = Authorization.default_role
341
+ Authorization.default_role = :anonymous
342
+ reader = Authorization::Reader::DSLReader.new
343
+ reader.parse %{
344
+ authorization do
345
+ role :anonymous do
346
+ has_permission_on :permissions, :to => :test
347
+ end
348
+ end
349
+ }
350
+ engine = Authorization::Engine.new(reader)
351
+ assert engine.permit?(:test, :context => :permissions)
352
+ assert !engine.permit?(:test, :context => :permissions,
353
+ :user => MockUser.new(:guest))
354
+ # reset the default role, so that it does not mess up other tests
355
+ Authorization.default_role = previous_default_role
356
+ end
357
+
358
+ def test_invalid_user_model
359
+ reader = Authorization::Reader::DSLReader.new
360
+ reader.parse %{
361
+ authorization do
362
+ role :guest do
363
+ has_permission_on :permissions, :to => :test
364
+ end
365
+ end
366
+ }
367
+ engine = Authorization::Engine.new(reader)
368
+ assert_raise(Authorization::AuthorizationUsageError) do
369
+ engine.permit?(:test, :context => :permissions, :user => MockUser.new(1, 2))
370
+ end
371
+ assert_raise(Authorization::AuthorizationUsageError) do
372
+ engine.permit?(:test, :context => :permissions, :user => MockDataObject.new)
373
+ end
374
+ end
375
+
376
+ def test_role_hierarchy
377
+ reader = Authorization::Reader::DSLReader.new
378
+ reader.parse %{
379
+ authorization do
380
+ role :test_role do
381
+ includes :lower_role
382
+ has_permission_on :permissions, :to => :test
383
+ end
384
+ role :lower_role do
385
+ has_permission_on :permissions, :to => :lower
386
+ end
387
+ end
388
+ }
389
+ engine = Authorization::Engine.new(reader)
390
+ assert engine.permit?(:lower, :context => :permissions,
391
+ :user => MockUser.new(:test_role))
392
+ end
393
+
394
+ def test_role_hierarchy_infinity
395
+ reader = Authorization::Reader::DSLReader.new
396
+ reader.parse %{
397
+ authorization do
398
+ role :test_role do
399
+ includes :lower_role
400
+ has_permission_on :permissions, :to => :test
401
+ end
402
+ role :lower_role do
403
+ includes :higher_role
404
+ has_permission_on :permissions, :to => :lower
405
+ end
406
+ end
407
+ }
408
+ engine = Authorization::Engine.new(reader)
409
+ assert engine.permit?(:lower, :context => :permissions,
410
+ :user => MockUser.new(:test_role))
411
+ end
412
+
413
+ def test_privilege_hierarchy
414
+ reader = Authorization::Reader::DSLReader.new
415
+ reader.parse %{
416
+ privileges do
417
+ privilege :test, :permissions do
418
+ includes :lower
419
+ end
420
+ end
421
+ authorization do
422
+ role :test_role do
423
+ has_permission_on :permissions, :to => :test
424
+ end
425
+ end
426
+ }
427
+ engine = Authorization::Engine.new(reader)
428
+ assert engine.permit?(:lower, :context => :permissions,
429
+ :user => MockUser.new(:test_role))
430
+ end
431
+
432
+ def test_privilege_hierarchy_without_context
433
+ reader = Authorization::Reader::DSLReader.new
434
+ reader.parse %{
435
+ privileges do
436
+ privilege :read do
437
+ includes :list, :show
438
+ end
439
+ end
440
+ authorization do
441
+ role :test_role do
442
+ has_permission_on :permissions, :to => :read
443
+ end
444
+ end
445
+ }
446
+ engine = Authorization::Engine.new(reader)
447
+ assert engine.permit?(:list, :context => :permissions,
448
+ :user => MockUser.new(:test_role))
449
+ end
450
+
451
+ def test_attribute_is
452
+ reader = Authorization::Reader::DSLReader.new
453
+ reader.parse %|
454
+ authorization do
455
+ role :test_role do
456
+ has_permission_on :permissions, :to => :test do
457
+ if_attribute :test_attr => is { user.test_attr }
458
+ if_attribute :test_attr => 3
459
+ end
460
+ end
461
+ end
462
+ |
463
+ engine = Authorization::Engine.new(reader)
464
+ assert engine.permit?(:test, :context => :permissions,
465
+ :user => MockUser.new(:test_role, :test_attr => 1),
466
+ :object => MockDataObject.new(:test_attr => 1))
467
+ assert engine.permit?(:test, :context => :permissions,
468
+ :user => MockUser.new(:test_role, :test_attr => 2),
469
+ :object => MockDataObject.new(:test_attr => 3))
470
+ assert((not(engine.permit?(:test, :context => :permissions,
471
+ :user => MockUser.new(:test_role, :test_attr => 2),
472
+ :object => MockDataObject.new(:test_attr => 1)))))
473
+ end
474
+
475
+ def test_attribute_is_not
476
+ reader = Authorization::Reader::DSLReader.new
477
+ reader.parse %|
478
+ authorization do
479
+ role :test_role do
480
+ has_permission_on :permissions, :to => :test do
481
+ if_attribute :test_attr => is_not { user.test_attr }
482
+ end
483
+ end
484
+ end
485
+ |
486
+ engine = Authorization::Engine.new(reader)
487
+ assert !engine.permit?(:test, :context => :permissions,
488
+ :user => MockUser.new(:test_role, :test_attr => 1),
489
+ :object => MockDataObject.new(:test_attr => 1))
490
+ assert engine.permit?(:test, :context => :permissions,
491
+ :user => MockUser.new(:test_role, :test_attr => 2),
492
+ :object => MockDataObject.new(:test_attr => 1))
493
+ end
494
+
495
+ def test_attribute_contains
496
+ reader = Authorization::Reader::DSLReader.new
497
+ reader.parse %|
498
+ authorization do
499
+ role :test_role do
500
+ has_permission_on :permissions, :to => :test do
501
+ if_attribute :test_attr => contains { user.test_attr }
502
+ end
503
+ end
504
+ end
505
+ |
506
+ engine = Authorization::Engine.new(reader)
507
+ assert engine.permit?(:test, :context => :permissions,
508
+ :user => MockUser.new(:test_role, :test_attr => 1),
509
+ :object => MockDataObject.new(:test_attr => [1,2]))
510
+ assert !engine.permit?(:test, :context => :permissions,
511
+ :user => MockUser.new(:test_role, :test_attr => 3),
512
+ :object => MockDataObject.new(:test_attr => [1,2]))
513
+ end
514
+
515
+ def test_attribute_does_not_contain
516
+ reader = Authorization::Reader::DSLReader.new
517
+ reader.parse %|
518
+ authorization do
519
+ role :test_role do
520
+ has_permission_on :permissions, :to => :test do
521
+ if_attribute :test_attr => does_not_contain { user.test_attr }
522
+ end
523
+ end
524
+ end
525
+ |
526
+ engine = Authorization::Engine.new(reader)
527
+ assert !engine.permit?(:test, :context => :permissions,
528
+ :user => MockUser.new(:test_role, :test_attr => 1),
529
+ :object => MockDataObject.new(:test_attr => [1,2]))
530
+ assert engine.permit?(:test, :context => :permissions,
531
+ :user => MockUser.new(:test_role, :test_attr => 3),
532
+ :object => MockDataObject.new(:test_attr => [1,2]))
533
+ end
534
+
535
+ def test_attribute_in_array
536
+ reader = Authorization::Reader::DSLReader.new
537
+ reader.parse %|
538
+ authorization do
539
+ role :test_role do
540
+ has_permission_on :permissions, :to => :test do
541
+ if_attribute :test_attr => is_in { [1,2] }
542
+ if_attribute :test_attr => [2,3]
543
+ end
544
+ end
545
+ end
546
+ |
547
+ engine = Authorization::Engine.new(reader)
548
+ assert engine.permit?(:test, :context => :permissions,
549
+ :user => MockUser.new(:test_role),
550
+ :object => MockDataObject.new(:test_attr => 1))
551
+ assert engine.permit?(:test, :context => :permissions,
552
+ :user => MockUser.new(:test_role),
553
+ :object => MockDataObject.new(:test_attr => 3))
554
+ assert !engine.permit?(:test, :context => :permissions,
555
+ :user => MockUser.new(:test_role),
556
+ :object => MockDataObject.new(:test_attr => 4))
557
+ end
558
+
559
+ def test_attribute_not_in_array
560
+ reader = Authorization::Reader::DSLReader.new
561
+ reader.parse %|
562
+ authorization do
563
+ role :test_role do
564
+ has_permission_on :permissions, :to => :test do
565
+ if_attribute :test_attr => is_not_in { [1,2] }
566
+ end
567
+ end
568
+ end
569
+ |
570
+ engine = Authorization::Engine.new(reader)
571
+ assert !engine.permit?(:test, :context => :permissions,
572
+ :user => MockUser.new(:test_role),
573
+ :object => MockDataObject.new(:test_attr => 1))
574
+ assert engine.permit?(:test, :context => :permissions,
575
+ :user => MockUser.new(:test_role),
576
+ :object => MockDataObject.new(:test_attr => 4))
577
+ end
578
+
579
+ def test_attribute_intersects_with
580
+ reader = Authorization::Reader::DSLReader.new
581
+ reader.parse %{
582
+ authorization do
583
+ role :test_role do
584
+ has_permission_on :permissions, :to => :test do
585
+ if_attribute :test_attrs => intersects_with { [1,2] }
586
+ end
587
+ end
588
+ role :test_role_2 do
589
+ has_permission_on :permissions, :to => :test do
590
+ if_attribute :test_attrs => intersects_with { 1 }
591
+ end
592
+ end
593
+ end
594
+ }
595
+
596
+ engine = Authorization::Engine.new(reader)
597
+ assert_raise Authorization::AuthorizationUsageError do
598
+ engine.permit?(:test, :context => :permissions,
599
+ :user => MockUser.new(:test_role),
600
+ :object => MockDataObject.new(:test_attrs => 1 ))
601
+ end
602
+ assert_raise Authorization::AuthorizationUsageError do
603
+ engine.permit?(:test, :context => :permissions,
604
+ :user => MockUser.new(:test_role_2),
605
+ :object => MockDataObject.new(:test_attrs => [1, 2] ))
606
+ end
607
+ assert engine.permit?(:test, :context => :permissions,
608
+ :user => MockUser.new(:test_role),
609
+ :object => MockDataObject.new(:test_attrs => [1,3] ))
610
+ assert !engine.permit?(:test, :context => :permissions,
611
+ :user => MockUser.new(:test_role),
612
+ :object => MockDataObject.new(:test_attrs => [3,4] ))
613
+ end
614
+
615
+ def test_attribute_lte
616
+ reader = Authorization::Reader::DSLReader.new
617
+ reader.parse %|
618
+ authorization do
619
+ role :test_role do
620
+ has_permission_on :permissions, :to => :test do
621
+ if_attribute :test_attr => lte { user.test_attr }
622
+ if_attribute :test_attr => 3
623
+ end
624
+ end
625
+ end
626
+ |
627
+ engine = Authorization::Engine.new(reader)
628
+ # object < user -> pass
629
+ assert engine.permit?(:test, :context => :permissions,
630
+ :user => MockUser.new(:test_role, :test_attr => 2),
631
+ :object => MockDataObject.new(:test_attr => 1))
632
+ # object > user && object = control -> pass
633
+ assert engine.permit?(:test, :context => :permissions,
634
+ :user => MockUser.new(:test_role, :test_attr => 2),
635
+ :object => MockDataObject.new(:test_attr => 3))
636
+ # object = user -> pass
637
+ assert engine.permit?(:test, :context => :permissions,
638
+ :user => MockUser.new(:test_role, :test_attr => 1),
639
+ :object => MockDataObject.new(:test_attr => 1))
640
+ # object > user -> fail
641
+ assert((not(engine.permit?(:test, :context => :permissions,
642
+ :user => MockUser.new(:test_role, :test_attr => 1),
643
+ :object => MockDataObject.new(:test_attr => 2)))))
644
+ end
645
+
646
+ def test_attribute_gt
647
+ reader = Authorization::Reader::DSLReader.new
648
+ reader.parse %|
649
+ authorization do
650
+ role :test_role do
651
+ has_permission_on :permissions, :to => :test do
652
+ if_attribute :test_attr => gt { user.test_attr }
653
+ if_attribute :test_attr => 3
654
+ end
655
+ end
656
+ end
657
+ |
658
+ engine = Authorization::Engine.new(reader)
659
+ # object > user -> pass
660
+ assert engine.permit?(:test, :context => :permissions,
661
+ :user => MockUser.new(:test_role, :test_attr => 1),
662
+ :object => MockDataObject.new(:test_attr => 2))
663
+ # object < user && object = control -> pass
664
+ assert engine.permit?(:test, :context => :permissions,
665
+ :user => MockUser.new(:test_role, :test_attr => 4),
666
+ :object => MockDataObject.new(:test_attr => 3))
667
+ # object = user -> fail
668
+ assert((not(engine.permit?(:test, :context => :permissions,
669
+ :user => MockUser.new(:test_role, :test_attr => 1),
670
+ :object => MockDataObject.new(:test_attr => 1)))))
671
+ # object < user -> fail
672
+ assert((not(engine.permit?(:test, :context => :permissions,
673
+ :user => MockUser.new(:test_role, :test_attr => 2),
674
+ :object => MockDataObject.new(:test_attr => 1)))))
675
+ end
676
+
677
+ def test_attribute_gte
678
+ reader = Authorization::Reader::DSLReader.new
679
+ reader.parse %|
680
+ authorization do
681
+ role :test_role do
682
+ has_permission_on :permissions, :to => :test do
683
+ if_attribute :test_attr => gte { user.test_attr }
684
+ if_attribute :test_attr => 3
685
+ end
686
+ end
687
+ end
688
+ |
689
+ engine = Authorization::Engine.new(reader)
690
+ # object > user -> pass
691
+ assert engine.permit?(:test, :context => :permissions,
692
+ :user => MockUser.new(:test_role, :test_attr => 1),
693
+ :object => MockDataObject.new(:test_attr => 2))
694
+ # object < user && object = control -> pass
695
+ assert engine.permit?(:test, :context => :permissions,
696
+ :user => MockUser.new(:test_role, :test_attr => 4),
697
+ :object => MockDataObject.new(:test_attr => 3))
698
+ # object = user -> pass
699
+ assert engine.permit?(:test, :context => :permissions,
700
+ :user => MockUser.new(:test_role, :test_attr => 1),
701
+ :object => MockDataObject.new(:test_attr => 1))
702
+ # object < user -> fail
703
+ assert((not(engine.permit?(:test, :context => :permissions,
704
+ :user => MockUser.new(:test_role, :test_attr => 2),
705
+ :object => MockDataObject.new(:test_attr => 1)))))
706
+ end
707
+
708
+ def test_attribute_deep
709
+ reader = Authorization::Reader::DSLReader.new
710
+ reader.parse %|
711
+ authorization do
712
+ role :test_role do
713
+ has_permission_on :permissions, :to => :test do
714
+ if_attribute :test_attr_1 => {:test_attr_2 => contains { 1 }}
715
+ end
716
+ end
717
+ end
718
+ |
719
+ engine = Authorization::Engine.new(reader)
720
+ assert engine.permit?(:test, :context => :permissions,
721
+ :user => MockUser.new(:test_role),
722
+ :object => MockDataObject.new(:test_attr_1 =>
723
+ MockDataObject.new(:test_attr_2 => [1,2])))
724
+ assert !engine.permit?(:test, :context => :permissions,
725
+ :user => MockUser.new(:test_role),
726
+ :object => MockDataObject.new(:test_attr_1 =>
727
+ MockDataObject.new(:test_attr_2 => [3,4])))
728
+ assert_equal [{:test_attr_1 => {:test_attr_2 => [:contains, 1]}}],
729
+ engine.obligations(:test, :context => :permissions,
730
+ :user => MockUser.new(:test_role))
731
+ end
732
+
733
+ def test_attribute_has_many
734
+ reader = Authorization::Reader::DSLReader.new
735
+ reader.parse %|
736
+ authorization do
737
+ role :test_role do
738
+ has_permission_on :companies, :to => :read do
739
+ if_attribute :branches => {:city => is { user.city } }
740
+ end
741
+ end
742
+ end
743
+ |
744
+ engine = Authorization::Engine.new(reader)
745
+
746
+ company = MockDataObject.new(:branches => [
747
+ MockDataObject.new(:city => 'Barcelona'),
748
+ MockDataObject.new(:city => 'Paris')
749
+ ])
750
+ assert engine.permit!(:read, :context => :companies,
751
+ :user => MockUser.new(:test_role, :city => 'Paris'),
752
+ :object => company)
753
+ assert !engine.permit?(:read, :context => :companies,
754
+ :user => MockUser.new(:test_role, :city => 'London'),
755
+ :object => company)
756
+ end
757
+
758
+ def test_attribute_non_block
759
+ reader = Authorization::Reader::DSLReader.new
760
+ reader.parse %|
761
+ authorization do
762
+ role :test_role do
763
+ has_permission_on :permissions, :to => :test do
764
+ if_attribute :test_attr => 1
765
+ end
766
+ end
767
+ end
768
+ |
769
+ engine = Authorization::Engine.new(reader)
770
+ assert engine.permit?(:test, :context => :permissions,
771
+ :user => MockUser.new(:test_role),
772
+ :object => MockDataObject.new(:test_attr => 1))
773
+ assert !engine.permit?(:test, :context => :permissions,
774
+ :user => MockUser.new(:test_role),
775
+ :object => MockDataObject.new(:test_attr => 2))
776
+ end
777
+
778
+ def test_attribute_multiple
779
+ reader = Authorization::Reader::DSLReader.new
780
+ reader.parse %{
781
+ authorization do
782
+ role :test_role do
783
+ has_permission_on :permissions, :to => :test do
784
+ if_attribute :test_attr => 1
785
+ if_attribute :test_attr => 2 # or
786
+ end
787
+ end
788
+ end
789
+ }
790
+ engine = Authorization::Engine.new(reader)
791
+ assert engine.permit?(:test, :context => :permissions,
792
+ :user => MockUser.new(:test_role),
793
+ :object => MockDataObject.new(:test_attr => 1))
794
+ assert engine.permit?(:test, :context => :permissions,
795
+ :user => MockUser.new(:test_role),
796
+ :object => MockDataObject.new(:test_attr => 2))
797
+ end
798
+
799
+ class PermissionMock < MockDataObject
800
+ def self.name
801
+ "Permission"
802
+ end
803
+ end
804
+ def test_attribute_with_permissions
805
+ reader = Authorization::Reader::DSLReader.new
806
+ reader.parse %{
807
+ authorization do
808
+ role :test_role do
809
+ has_permission_on :permissions, :to => :test do
810
+ if_attribute :test_attr => 1
811
+ end
812
+ has_permission_on :permission_children, :to => :test do
813
+ if_permitted_to :test, :permission
814
+ end
815
+ end
816
+ end
817
+ }
818
+ engine = Authorization::Engine.new(reader)
819
+
820
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
821
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
822
+ assert engine.permit?(:test, :context => :permission_children,
823
+ :user => MockUser.new(:test_role),
824
+ :object => MockDataObject.new(:permission => perm_data_attr_1))
825
+ assert !engine.permit?(:test, :context => :permission_children,
826
+ :user => MockUser.new(:test_role),
827
+ :object => MockDataObject.new(:permission => perm_data_attr_2))
828
+ end
829
+
830
+ def test_attribute_with_has_many_permissions
831
+ reader = Authorization::Reader::DSLReader.new
832
+ reader.parse %{
833
+ authorization do
834
+ role :test_role do
835
+ has_permission_on :permissions, :to => :test do
836
+ if_attribute :test_attr => 1
837
+ end
838
+ has_permission_on :permission_children, :to => :test do
839
+ if_permitted_to :test, :permissions
840
+ end
841
+ end
842
+ end
843
+ }
844
+ engine = Authorization::Engine.new(reader)
845
+
846
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
847
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
848
+ assert engine.permit?(:test, :context => :permission_children,
849
+ :user => MockUser.new(:test_role),
850
+ :object => MockDataObject.new(:permissions => [perm_data_attr_1]))
851
+ assert !engine.permit?(:test, :context => :permission_children,
852
+ :user => MockUser.new(:test_role),
853
+ :object => MockDataObject.new(:permissions => [perm_data_attr_2]))
854
+ end
855
+
856
+ def test_attribute_with_deep_permissions
857
+ reader = Authorization::Reader::DSLReader.new
858
+ reader.parse %{
859
+ authorization do
860
+ role :test_role do
861
+ has_permission_on :permissions, :to => :test do
862
+ if_attribute :test_attr => 1
863
+ end
864
+ has_permission_on :permission_children, :to => :test do
865
+ if_permitted_to :test, :shallow_permission => :permission
866
+ end
867
+ end
868
+ end
869
+ }
870
+ engine = Authorization::Engine.new(reader)
871
+
872
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
873
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
874
+ assert engine.permit?(:test, :context => :permission_children,
875
+ :user => MockUser.new(:test_role),
876
+ :object => MockDataObject.new(:shallow_permission =>
877
+ MockDataObject.new(:permission => perm_data_attr_1)))
878
+ assert !engine.permit?(:test, :context => :permission_children,
879
+ :user => MockUser.new(:test_role),
880
+ :object => MockDataObject.new(:shallow_permission =>
881
+ MockDataObject.new(:permission => perm_data_attr_2)))
882
+ end
883
+
884
+ def test_attribute_with_deep_has_many_permissions
885
+ reader = Authorization::Reader::DSLReader.new
886
+ reader.parse %{
887
+ authorization do
888
+ role :test_role do
889
+ has_permission_on :permissions, :to => :test do
890
+ if_attribute :test_attr => 1
891
+ end
892
+ has_permission_on :permission_children, :to => :test do
893
+ if_permitted_to :test, :shallow_permissions => :permission
894
+ end
895
+ end
896
+ end
897
+ }
898
+ engine = Authorization::Engine.new(reader)
899
+
900
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
901
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
902
+ assert engine.permit?(:test, :context => :permission_children,
903
+ :user => MockUser.new(:test_role),
904
+ :object => MockDataObject.new(:shallow_permissions =>
905
+ [MockDataObject.new(:permission => perm_data_attr_1)]))
906
+ assert !engine.permit?(:test, :context => :permission_children,
907
+ :user => MockUser.new(:test_role),
908
+ :object => MockDataObject.new(:shallow_permissions =>
909
+ [MockDataObject.new(:permission => perm_data_attr_2)]))
910
+ end
911
+
912
+ def test_attribute_with_permissions_nil
913
+ reader = Authorization::Reader::DSLReader.new
914
+ reader.parse %{
915
+ authorization do
916
+ role :test_role do
917
+ has_permission_on :permissions, :to => :test do
918
+ if_attribute :test_attr => 1
919
+ end
920
+ has_permission_on :permission_children, :to => :test do
921
+ if_permitted_to :test, :permission
922
+ end
923
+ end
924
+ end
925
+ }
926
+ engine = Authorization::Engine.new(reader)
927
+
928
+ assert_nothing_raised do
929
+ engine.permit?(:test, :context => :permission_children,
930
+ :user => MockUser.new(:test_role),
931
+ :object => MockDataObject.new(:permission => nil))
932
+ end
933
+
934
+ assert !engine.permit?(:test, :context => :permission_children,
935
+ :user => MockUser.new(:test_role),
936
+ :object => MockDataObject.new(:permission => nil))
937
+ end
938
+
939
+ def test_attribute_with_permissions_on_self
940
+ reader = Authorization::Reader::DSLReader.new
941
+ reader.parse %{
942
+ authorization do
943
+ role :test_role do
944
+ has_permission_on :permissions, :to => :test do
945
+ if_attribute :test_attr => 1
946
+ end
947
+ has_permission_on :permissions, :to => :another_test do
948
+ if_permitted_to :test
949
+ end
950
+ end
951
+ end
952
+ }
953
+ engine = Authorization::Engine.new(reader)
954
+
955
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
956
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
957
+ assert engine.permit?(:another_test, :context => :permissions,
958
+ :user => MockUser.new(:test_role),
959
+ :object => perm_data_attr_1)
960
+ assert !engine.permit?(:another_test, :context => :permissions,
961
+ :user => MockUser.new(:test_role),
962
+ :object => perm_data_attr_2)
963
+ end
964
+
965
+ def test_attribute_with_permissions_on_self_with_context
966
+ reader = Authorization::Reader::DSLReader.new
967
+ reader.parse %{
968
+ authorization do
969
+ role :test_role do
970
+ has_permission_on :permissions, :to => :test do
971
+ if_attribute :test_attr => 1
972
+ end
973
+ has_permission_on :permissions, :to => :another_test do
974
+ if_permitted_to :test, :context => :permissions
975
+ end
976
+ end
977
+ end
978
+ }
979
+ engine = Authorization::Engine.new(reader)
980
+
981
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
982
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
983
+ assert engine.permit?(:another_test, :context => :permissions,
984
+ :user => MockUser.new(:test_role),
985
+ :object => perm_data_attr_1)
986
+ assert !engine.permit?(:another_test, :context => :permissions,
987
+ :user => MockUser.new(:test_role),
988
+ :object => perm_data_attr_2)
989
+ end
990
+
991
+ def test_attribute_with_permissions_and_anded_rules
992
+ reader = Authorization::Reader::DSLReader.new
993
+ reader.parse %{
994
+ authorization do
995
+ role :test_role do
996
+ has_permission_on :permissions, :to => :test do
997
+ if_attribute :test_attr => 1
998
+ end
999
+ has_permission_on :permission_children, :to => :test, :join_by => :and do
1000
+ if_permitted_to :test, :permission
1001
+ if_attribute :test_attr => 1
1002
+ end
1003
+ end
1004
+ end
1005
+ }
1006
+ engine = Authorization::Engine.new(reader)
1007
+
1008
+ perm_data_attr_1 = PermissionMock.new({:test_attr => 1})
1009
+ perm_data_attr_2 = PermissionMock.new({:test_attr => 2})
1010
+ assert engine.permit?(:test, :context => :permission_children,
1011
+ :user => MockUser.new(:test_role),
1012
+ :object => MockDataObject.new(:permission => perm_data_attr_1, :test_attr => 1))
1013
+ assert !engine.permit?(:test, :context => :permission_children,
1014
+ :user => MockUser.new(:test_role),
1015
+ :object => MockDataObject.new(:permission => perm_data_attr_2, :test_attr => 1))
1016
+ assert !engine.permit?(:test, :context => :permission_children,
1017
+ :user => MockUser.new(:test_role),
1018
+ :object => MockDataObject.new(:permission => perm_data_attr_1, :test_attr => 2))
1019
+ end
1020
+
1021
+ def test_attribute_with_anded_rules
1022
+ reader = Authorization::Reader::DSLReader.new
1023
+ reader.parse %{
1024
+ authorization do
1025
+ role :test_role do
1026
+ has_permission_on :permissions, :to => :test, :join_by => :and do
1027
+ if_attribute :test_attr => 1
1028
+ if_attribute :test_attr_2 => 2
1029
+ end
1030
+ end
1031
+ end
1032
+ }
1033
+ engine = Authorization::Engine.new(reader)
1034
+
1035
+ assert engine.permit?(:test, :context => :permissions,
1036
+ :user => MockUser.new(:test_role),
1037
+ :object => MockDataObject.new(:test_attr => 1, :test_attr_2 => 2))
1038
+ assert !engine.permit?(:test, :context => :permissions,
1039
+ :user => MockUser.new(:test_role),
1040
+ :object => MockDataObject.new(:test_attr => 1, :test_attr_2 => 3))
1041
+ end
1042
+
1043
+ def test_raise_on_if_attribute_hash_on_collection
1044
+ reader = Authorization::Reader::DSLReader.new
1045
+ reader.parse %{
1046
+ authorization do
1047
+ role :test_role do
1048
+ has_permission_on :permissions, :to => :test do
1049
+ if_attribute :test_attrs => {:attr => is {1}}
1050
+ end
1051
+ end
1052
+ end
1053
+ }
1054
+ engine = Authorization::Engine.new(reader)
1055
+ assert_raise Authorization::AuthorizationUsageError do
1056
+ engine.permit?(:test, :context => :permissions,
1057
+ :user => MockUser.new(:test_role),
1058
+ :object => MockDataObject.new(:test_attrs => [1, 2, 3]))
1059
+ end
1060
+ end
1061
+
1062
+ def test_role_title_description
1063
+ reader = Authorization::Reader::DSLReader.new
1064
+ reader.parse %{
1065
+ authorization do
1066
+ role :test_role, :title => 'Test Role' do
1067
+ description "Test Role Description"
1068
+ end
1069
+ end
1070
+ }
1071
+ engine = Authorization::Engine.new(reader)
1072
+ assert engine.roles.include?(:test_role)
1073
+ assert_equal "Test Role", engine.role_titles[:test_role]
1074
+ assert_equal "Test Role", engine.title_for(:test_role)
1075
+ assert_nil engine.title_for(:test_role_2)
1076
+ assert_equal "Test Role Description", engine.role_descriptions[:test_role]
1077
+ assert_equal "Test Role Description", engine.description_for(:test_role)
1078
+ assert_nil engine.description_for(:test_role_2)
1079
+ end
1080
+
1081
+ def test_multithread
1082
+ reader = Authorization::Reader::DSLReader.new
1083
+ reader.parse %{
1084
+ authorization do
1085
+ role :test_role do
1086
+ has_permission_on :permissions, :to => :test
1087
+ end
1088
+ end
1089
+ }
1090
+
1091
+ engine = Authorization::Engine.new(reader)
1092
+ Authorization.current_user = MockUser.new(:test_role)
1093
+ assert engine.permit?(:test, :context => :permissions)
1094
+ Thread.new do
1095
+ Authorization.current_user = MockUser.new(:test_role2)
1096
+ assert !engine.permit?(:test, :context => :permissions)
1097
+ end
1098
+ assert engine.permit?(:test, :context => :permissions)
1099
+ Authorization.current_user = nil
1100
+ end
1101
+
1102
+ def test_clone
1103
+ reader = Authorization::Reader::DSLReader.new
1104
+ reader.parse %{
1105
+ authorization do
1106
+ role :test_role do
1107
+ has_permission_on :permissions, :to => :test do
1108
+ if_attribute :attr => { :sub_attr => is { user } }
1109
+ if_permitted_to :read, :attr_2 => :attr_3
1110
+ if_permitted_to :read, :attr_2
1111
+ end
1112
+ end
1113
+ end
1114
+ }
1115
+
1116
+ engine = Authorization::Engine.new(reader)
1117
+ cloned_engine = engine.clone
1118
+ assert_not_equal engine.auth_rules.first.contexts.object_id,
1119
+ cloned_engine.auth_rules.first.contexts.object_id
1120
+ assert_not_equal engine.auth_rules.first.attributes.first.send(:instance_variable_get, :@conditions_hash)[:attr].object_id,
1121
+ cloned_engine.auth_rules.first.attributes.first.send(:instance_variable_get, :@conditions_hash)[:attr].object_id
1122
+ end
1123
+ end
1124
+