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.
- checksums.yaml +7 -0
- data/CHANGELOG +189 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +632 -0
- data/Rakefile +53 -0
- data/app/controllers/authorization_rules_controller.rb +258 -0
- data/app/controllers/authorization_usages_controller.rb +22 -0
- data/app/helpers/authorization_rules_helper.rb +218 -0
- data/app/views/authorization_rules/_change.erb +58 -0
- data/app/views/authorization_rules/_show_graph.erb +44 -0
- data/app/views/authorization_rules/_suggestions.erb +48 -0
- data/app/views/authorization_rules/change.html.erb +169 -0
- data/app/views/authorization_rules/graph.dot.erb +68 -0
- data/app/views/authorization_rules/graph.html.erb +47 -0
- data/app/views/authorization_rules/index.html.erb +17 -0
- data/app/views/authorization_usages/index.html.erb +36 -0
- data/authorization_rules.dist.rb +20 -0
- data/config/routes.rb +20 -0
- data/garlic_example.rb +20 -0
- data/init.rb +5 -0
- data/lib/declarative_authorization.rb +19 -0
- data/lib/declarative_authorization/adapters/active_record.rb +13 -0
- data/lib/declarative_authorization/adapters/active_record/base_extensions.rb +0 -0
- data/lib/declarative_authorization/adapters/active_record/obligation_scope_builder.rb +0 -0
- data/lib/declarative_authorization/authorization.rb +798 -0
- data/lib/declarative_authorization/development_support/analyzer.rb +261 -0
- data/lib/declarative_authorization/development_support/change_analyzer.rb +253 -0
- data/lib/declarative_authorization/development_support/change_supporter.rb +620 -0
- data/lib/declarative_authorization/development_support/development_support.rb +243 -0
- data/lib/declarative_authorization/helper.rb +68 -0
- data/lib/declarative_authorization/in_controller.rb +703 -0
- data/lib/declarative_authorization/in_model.rb +188 -0
- data/lib/declarative_authorization/maintenance.rb +210 -0
- data/lib/declarative_authorization/obligation_scope.rb +361 -0
- data/lib/declarative_authorization/rails_legacy.rb +22 -0
- data/lib/declarative_authorization/railsengine.rb +6 -0
- data/lib/declarative_authorization/reader.rb +546 -0
- data/lib/generators/authorization/install/install_generator.rb +77 -0
- data/lib/generators/authorization/rules/rules_generator.rb +14 -0
- data/lib/generators/authorization/rules/templates/authorization_rules.rb +27 -0
- data/lib/tasks/authorization_tasks.rake +89 -0
- data/test/authorization_test.rb +1124 -0
- data/test/controller_filter_resource_access_test.rb +575 -0
- data/test/controller_test.rb +480 -0
- data/test/database.yml +3 -0
- data/test/dsl_reader_test.rb +178 -0
- data/test/helper_test.rb +247 -0
- data/test/maintenance_test.rb +46 -0
- data/test/model_test.rb +2008 -0
- data/test/schema.sql +56 -0
- data/test/test_helper.rb +255 -0
- 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
|
+
|