acl9 0.12.0 → 1.0.0
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/.gitignore +21 -0
- data/.travis.yml +19 -0
- data/Appraisals +8 -0
- data/CONTRIBUTING.md +58 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +103 -0
- data/LICENSE +9 -0
- data/README.md +156 -0
- data/Rakefile +8 -27
- data/acl9.gemspec +29 -0
- data/gemfiles/rails_4.0.gemfile +8 -0
- data/gemfiles/rails_4.1.gemfile +8 -0
- data/lib/acl9/controller_extensions/dsl_base.rb +14 -38
- data/lib/acl9/helpers.rb +12 -5
- data/lib/acl9/model_extensions/for_object.rb +20 -5
- data/lib/acl9/model_extensions/for_subject.rb +25 -20
- data/lib/acl9/model_extensions.rb +8 -23
- data/lib/acl9/version.rb +3 -0
- data/lib/acl9.rb +16 -12
- data/test/controller_extensions/actions_test.rb +167 -0
- data/test/controller_extensions/anon_test.rb +39 -0
- data/test/controller_extensions/base.rb +96 -0
- data/test/controller_extensions/basics_test.rb +44 -0
- data/test/controller_extensions/conditions_test.rb +48 -0
- data/test/controller_extensions/method_test.rb +50 -0
- data/test/controller_extensions/multi_match_test.rb +142 -0
- data/test/controller_extensions/multiple_role_arguments_test.rb +135 -0
- data/test/controller_extensions/prepositions_test.rb +99 -0
- data/test/controller_extensions/pseudo_role_test.rb +26 -0
- data/test/controller_extensions/role_test.rb +75 -0
- data/test/controllers/acl_action_override_test.rb +24 -0
- data/test/controllers/acl_arguments_test.rb +5 -0
- data/test/controllers/acl_block_test.rb +5 -0
- data/test/controllers/acl_boolean_method_test.rb +5 -0
- data/test/controllers/acl_helper_method_test.rb +26 -0
- data/test/controllers/acl_ivars_test.rb +15 -0
- data/test/controllers/acl_method2_test.rb +6 -0
- data/test/controllers/acl_method_test.rb +6 -0
- data/test/controllers/acl_object_hash_test.rb +18 -0
- data/test/controllers/acl_query_method_named_test.rb +9 -0
- data/test/controllers/acl_query_method_test.rb +9 -0
- data/test/controllers/acl_query_method_with_lambda_test.rb +9 -0
- data/test/controllers/acl_query_mixin.rb +51 -0
- data/test/controllers/acl_subject_method_test.rb +15 -0
- data/test/controllers/arguments_checking_test.rb +43 -0
- data/test/dummy/app/controllers/acl_action_override.rb +15 -0
- data/test/dummy/app/controllers/acl_arguments.rb +10 -0
- data/test/dummy/app/controllers/acl_block.rb +6 -0
- data/test/dummy/app/controllers/acl_boolean_method.rb +23 -0
- data/test/dummy/app/controllers/acl_helper_method.rb +11 -0
- data/test/dummy/app/controllers/acl_ivars.rb +17 -0
- data/test/dummy/app/controllers/acl_method.rb +6 -0
- data/test/dummy/app/controllers/acl_method2.rb +6 -0
- data/test/dummy/app/controllers/acl_objects_hash.rb +10 -0
- data/test/dummy/app/controllers/acl_query_method.rb +9 -0
- data/test/dummy/app/controllers/acl_query_method_named.rb +13 -0
- data/test/dummy/app/controllers/acl_query_method_with_lambda.rb +9 -0
- data/test/dummy/app/controllers/acl_subject_method.rb +16 -0
- data/test/dummy/app/controllers/application_controller.rb +7 -0
- data/test/dummy/app/controllers/empty_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/some_helper.rb +8 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/access.rb +3 -0
- data/test/dummy/app/models/account.rb +3 -0
- data/test/dummy/app/models/bar.rb +3 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/models/foo.rb +3 -0
- data/test/dummy/app/models/foo_bar.rb +3 -0
- data/test/dummy/app/models/other/foo.rb +5 -0
- data/test/dummy/app/models/other/role.rb +5 -0
- data/test/dummy/app/models/other/user.rb +5 -0
- data/test/dummy/app/models/role.rb +3 -0
- data/test/dummy/app/models/user.rb +3 -0
- data/test/dummy/app/models/uuid.rb +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +4 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +78 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/secrets.rb +1 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20141117132218_create_tables.rb +102 -0
- data/test/helpers/helper_test.rb +89 -0
- data/test/models/roles_test.rb +251 -0
- data/test/models/roles_with_custom_association_names_test.rb +28 -0
- data/test/models/roles_with_custom_class_names_test.rb +28 -0
- data/test/models/system_roles_test.rb +16 -0
- data/test/models/users_roles_and_subjects_with_namespaced_class_names_test.rb +30 -0
- data/test/test_helper.rb +72 -20
- data/test/version_test.rb +7 -0
- metadata +266 -70
- data/README.textile +0 -903
- data/VERSION.yml +0 -5
- data/lib/acl9/config.rb +0 -11
- data/test/access_control_test.rb +0 -338
- data/test/dsl_base_test.rb +0 -795
- data/test/helpers_test.rb +0 -134
- data/test/roles_test.rb +0 -355
- data/test/support/controllers.rb +0 -207
- data/test/support/models.rb +0 -59
- data/test/support/schema.rb +0 -92
|
@@ -10,7 +10,10 @@ module Acl9
|
|
|
10
10
|
# @param [Subject] subject Subject to add role for
|
|
11
11
|
# @see Acl9::ModelExtensions::Subject#has_role?
|
|
12
12
|
def accepts_role?(role_name, subject)
|
|
13
|
-
subject.
|
|
13
|
+
if not subject.nil?
|
|
14
|
+
return subject.has_role? role_name, self
|
|
15
|
+
end
|
|
16
|
+
false
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
##
|
|
@@ -20,7 +23,10 @@ module Acl9
|
|
|
20
23
|
# @param [Subject] subject Subject to add role for
|
|
21
24
|
# @see Acl9::ModelExtensions::Subject#has_role!
|
|
22
25
|
def accepts_role!(role_name, subject)
|
|
23
|
-
subject.
|
|
26
|
+
if not subject.nil?
|
|
27
|
+
return subject.has_role! role_name, self
|
|
28
|
+
end
|
|
29
|
+
false
|
|
24
30
|
end
|
|
25
31
|
|
|
26
32
|
##
|
|
@@ -30,7 +36,10 @@ module Acl9
|
|
|
30
36
|
# @param [Subject] subject Subject to remove role from
|
|
31
37
|
# @see Acl9::ModelExtensions::Subject#has_no_role!
|
|
32
38
|
def accepts_no_role!(role_name, subject)
|
|
33
|
-
subject.
|
|
39
|
+
if not subject.nil?
|
|
40
|
+
return subject.has_no_role! role_name, self
|
|
41
|
+
end
|
|
42
|
+
false
|
|
34
43
|
end
|
|
35
44
|
|
|
36
45
|
##
|
|
@@ -40,7 +49,10 @@ module Acl9
|
|
|
40
49
|
# @return [Boolean] Returns true if +subject+ has any roles on this object.
|
|
41
50
|
# @see Acl9::ModelExtensions::Subject#has_roles_for?
|
|
42
51
|
def accepts_roles_by?(subject)
|
|
43
|
-
subject.
|
|
52
|
+
if not subject.nil?
|
|
53
|
+
return subject.has_roles_for? self
|
|
54
|
+
end
|
|
55
|
+
false
|
|
44
56
|
end
|
|
45
57
|
|
|
46
58
|
alias :accepts_role_by? :accepts_roles_by?
|
|
@@ -52,7 +64,10 @@ module Acl9
|
|
|
52
64
|
# @param [Subject] subject Subject to query roles
|
|
53
65
|
# @see Acl9::ModelExtensions::Subject#roles_for
|
|
54
66
|
def accepted_roles_by(subject)
|
|
55
|
-
subject.
|
|
67
|
+
if not subject.nil?
|
|
68
|
+
return subject.roles_for self
|
|
69
|
+
end
|
|
70
|
+
false
|
|
56
71
|
end
|
|
57
72
|
end
|
|
58
73
|
end
|
|
@@ -17,7 +17,7 @@ module Acl9
|
|
|
17
17
|
#
|
|
18
18
|
# In this case manager is anyone who "manages" at least one object.
|
|
19
19
|
#
|
|
20
|
-
# However, if protect_global_roles option set to +true+, you'll need to
|
|
20
|
+
# However, if protect_global_roles option set to +true+, you'll need to
|
|
21
21
|
# explicitly grant global role with same name.
|
|
22
22
|
#
|
|
23
23
|
# Acl9.config[:protect_global_roles] = true
|
|
@@ -26,7 +26,7 @@ module Acl9
|
|
|
26
26
|
# user.has_role!(:manager)
|
|
27
27
|
# user.has_role?(:manager) # => true
|
|
28
28
|
#
|
|
29
|
-
# protect_global_roles option is +false+ by default as for now, but this
|
|
29
|
+
# protect_global_roles option is +false+ by default as for now, but this
|
|
30
30
|
# may change in future!
|
|
31
31
|
#
|
|
32
32
|
# @return [Boolean] Whether +self+ has a role +role_name+ on +object+.
|
|
@@ -36,11 +36,11 @@ module Acl9
|
|
|
36
36
|
# @see Acl9::ModelExtensions::Object#accepts_role?
|
|
37
37
|
def has_role?(role_name, object = nil)
|
|
38
38
|
!! if object.nil? && !::Acl9.config[:protect_global_roles]
|
|
39
|
-
self.
|
|
40
|
-
self.
|
|
39
|
+
self._role_objects.find_by_name(role_name.to_s) ||
|
|
40
|
+
self._role_objects.member?(get_role(role_name, nil))
|
|
41
41
|
else
|
|
42
42
|
role = get_role(role_name, object)
|
|
43
|
-
role && self.
|
|
43
|
+
role && self._role_objects.exists?(role.id)
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -63,7 +63,7 @@ module Acl9
|
|
|
63
63
|
role = self._auth_role_class.create(role_attrs)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
self.
|
|
66
|
+
self._role_objects << role if role && !self._role_objects.exists?(role.id)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
##
|
|
@@ -83,7 +83,7 @@ module Acl9
|
|
|
83
83
|
# @return [Boolean] Returns true if +self+ has any roles on +object+.
|
|
84
84
|
# @see Acl9::ModelExtensions::Object#accepts_roles_by?
|
|
85
85
|
def has_roles_for?(object)
|
|
86
|
-
!!self.
|
|
86
|
+
!!self._role_objects.detect(&role_selecting_lambda(object))
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
alias :has_role_for? :has_roles_for?
|
|
@@ -100,7 +100,7 @@ module Acl9
|
|
|
100
100
|
#
|
|
101
101
|
# user.roles_for(product).map(&:name).sort #=> role names in alphabetical order
|
|
102
102
|
def roles_for(object)
|
|
103
|
-
self.
|
|
103
|
+
self._role_objects.select(&role_selecting_lambda(object))
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
##
|
|
@@ -119,7 +119,7 @@ module Acl9
|
|
|
119
119
|
# self.roles.each { |role| delete_role(role) }
|
|
120
120
|
#
|
|
121
121
|
# doesn't work. seems like a bug in ActiveRecord
|
|
122
|
-
self.
|
|
122
|
+
self._role_objects.map(&:id).each do |role_id|
|
|
123
123
|
delete_role self._auth_role_class.find(role_id)
|
|
124
124
|
end
|
|
125
125
|
end
|
|
@@ -134,7 +134,8 @@ module Acl9
|
|
|
134
134
|
lambda { |role| role.authorizable.nil? }
|
|
135
135
|
else
|
|
136
136
|
lambda do |role|
|
|
137
|
-
role.
|
|
137
|
+
auth_id = role.authorizable_id.kind_of?(String) ? object.id.to_s : object.id
|
|
138
|
+
role.authorizable_type == object.class.base_class.to_s && role.authorizable_id == auth_id
|
|
138
139
|
end
|
|
139
140
|
end
|
|
140
141
|
end
|
|
@@ -154,31 +155,35 @@ module Acl9
|
|
|
154
155
|
]
|
|
155
156
|
end
|
|
156
157
|
|
|
157
|
-
self._auth_role_class.
|
|
158
|
+
if self._auth_role_class.respond_to?(:where)
|
|
159
|
+
self._auth_role_class.where(cond).first
|
|
160
|
+
else
|
|
161
|
+
self._auth_role_class.find(:first, :conditions => cond)
|
|
162
|
+
end
|
|
158
163
|
end
|
|
159
164
|
|
|
160
165
|
def delete_role(role)
|
|
161
166
|
if role
|
|
162
|
-
self.
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
self._role_objects.delete role
|
|
168
|
+
if role.send(self._auth_subject_class_name.demodulize.tableize).empty?
|
|
169
|
+
role.destroy unless role.respond_to?(:system?) && role.system?
|
|
170
|
+
end
|
|
165
171
|
end
|
|
166
172
|
end
|
|
167
|
-
|
|
173
|
+
|
|
168
174
|
protected
|
|
169
175
|
|
|
170
176
|
def _auth_role_class
|
|
171
177
|
self.class._auth_role_class_name.constantize
|
|
172
178
|
end
|
|
173
|
-
|
|
179
|
+
|
|
174
180
|
def _auth_role_assoc
|
|
175
|
-
|
|
181
|
+
self.class._auth_role_assoc_name
|
|
176
182
|
end
|
|
177
183
|
|
|
178
|
-
def
|
|
179
|
-
|
|
184
|
+
def _role_objects
|
|
185
|
+
send(self._auth_role_assoc)
|
|
180
186
|
end
|
|
181
|
-
|
|
182
187
|
end
|
|
183
188
|
end
|
|
184
189
|
end
|
|
@@ -33,12 +33,11 @@ module Acl9
|
|
|
33
33
|
# @see Acl9::ModelExtensions::Subject
|
|
34
34
|
#
|
|
35
35
|
def acts_as_authorization_subject(options = {})
|
|
36
|
-
|
|
36
|
+
assoc = options[:association_name] || Acl9::config[:default_association_name]
|
|
37
37
|
role = options[:role_class_name] || Acl9::config[:default_role_class_name]
|
|
38
|
-
join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
|
|
39
|
-
join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(role))
|
|
38
|
+
join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] || self.table_name_prefix + [undecorated_table_name(self.to_s), undecorated_table_name(role)].sort.join("_") + self.table_name_suffix
|
|
40
39
|
|
|
41
|
-
has_and_belongs_to_many assoc, :class_name => role, :join_table => join_table
|
|
40
|
+
has_and_belongs_to_many assoc.to_sym, :class_name => role, :join_table => join_table
|
|
42
41
|
|
|
43
42
|
cattr_accessor :_auth_role_class_name, :_auth_subject_class_name,
|
|
44
43
|
:_auth_role_assoc_name
|
|
@@ -74,28 +73,12 @@ module Acl9
|
|
|
74
73
|
def acts_as_authorization_object(options = {})
|
|
75
74
|
subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
|
|
76
75
|
subj_table = subject.constantize.table_name
|
|
77
|
-
subj_col = subject.underscore
|
|
78
|
-
|
|
79
|
-
role = options[:role_class_name] || Acl9::config[:default_role_class_name]
|
|
80
|
-
role_table = role.constantize.table_name
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
FROM #{subj_table}
|
|
84
|
-
INNER JOIN #{role_table}_#{subj_table} ON #{subj_col}_id = #{subj_table}.id
|
|
85
|
-
INNER JOIN #{role_table} ON #{role_table}.id = #{role.underscore}_id
|
|
86
|
-
EOS
|
|
87
|
-
|
|
88
|
-
sql_where = <<-'EOS'
|
|
89
|
-
WHERE authorizable_type = '#{self.class.base_class.to_s}'
|
|
90
|
-
AND authorizable_id = #{column_for_attribute(self.class.primary_key).text? ? "'#{id}'": id}
|
|
91
|
-
EOS
|
|
77
|
+
role = options[:role_class_name] || Acl9::config[:default_role_class_name]
|
|
92
78
|
|
|
93
79
|
has_many :accepted_roles, :as => :authorizable, :class_name => role, :dependent => :destroy
|
|
94
80
|
|
|
95
|
-
has_many :"#{subj_table}",
|
|
96
|
-
:finder_sql => ("SELECT DISTINCT #{subj_table}.*" + sql_tables + sql_where),
|
|
97
|
-
:counter_sql => ("SELECT COUNT(DISTINCT #{subj_table}.id)" + sql_tables + sql_where),
|
|
98
|
-
:readonly => true
|
|
81
|
+
has_many :"#{subj_table}", -> { distinct.readonly }, through: :accepted_roles
|
|
99
82
|
|
|
100
83
|
include Acl9::ModelExtensions::ForObject
|
|
101
84
|
end
|
|
@@ -126,7 +109,9 @@ module Acl9
|
|
|
126
109
|
def acts_as_authorization_role(options = {})
|
|
127
110
|
subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
|
|
128
111
|
join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
|
|
129
|
-
|
|
112
|
+
self.table_name_prefix + [undecorated_table_name(self.to_s), undecorated_table_name(subject)].sort.join("_") + self.table_name_suffix
|
|
113
|
+
# comment out use deprecated API
|
|
114
|
+
#join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(subject))
|
|
130
115
|
|
|
131
116
|
has_and_belongs_to_many subject.demodulize.tableize.to_sym,
|
|
132
117
|
:class_name => subject,
|
data/lib/acl9/version.rb
ADDED
data/lib/acl9.rb
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'acl9/version'
|
|
2
|
+
require 'acl9/model_extensions'
|
|
3
|
+
require 'acl9/controller_extensions'
|
|
4
|
+
require 'acl9/helpers'
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
module Acl9
|
|
7
|
+
@@config = {
|
|
8
|
+
:default_role_class_name => 'Role',
|
|
9
|
+
:default_subject_class_name => 'User',
|
|
10
|
+
:default_subject_method => :current_user,
|
|
11
|
+
:default_association_name => :role_objects,
|
|
12
|
+
:protect_global_roles => true,
|
|
13
|
+
}
|
|
5
14
|
|
|
6
|
-
|
|
15
|
+
mattr_reader :config
|
|
7
16
|
end
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
require File.join(File.dirname(__FILE__), 'acl9', 'helpers')
|
|
13
|
-
|
|
14
|
-
ActionController::Base.send(:include, Acl9::ControllerExtensions)
|
|
15
|
-
Acl9Helpers = Acl9::Helpers unless defined?(Acl9Helpers)
|
|
16
|
-
end
|
|
18
|
+
ActiveRecord::Base.send(:include, Acl9::ModelExtensions)
|
|
19
|
+
ActionController::Base.send(:include, Acl9::ControllerExtensions)
|
|
20
|
+
Acl9Helpers = Acl9::Helpers unless defined?(Acl9Helpers)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module ControllerExtensions
|
|
4
|
+
class ActionTest < Base
|
|
5
|
+
test "should raise an ArgumentError when actions has no block" do
|
|
6
|
+
assert_raise ArgumentError do
|
|
7
|
+
@tester.acl_block! { actions :foo, :bar }
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test "should raise an ArgumentError when actions has no arguments" do
|
|
12
|
+
assert_raise ArgumentError do
|
|
13
|
+
@tester.acl_block! { actions do end }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "should raise an ArgumentError when actions is called inside actions block" do
|
|
18
|
+
assert_raise ArgumentError do
|
|
19
|
+
@tester.acl_block! do
|
|
20
|
+
actions :foo, :bar do
|
|
21
|
+
actions :foo, :bar do
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "should raise an ArgumentError when default is called inside actions block" do
|
|
29
|
+
assert_raise ArgumentError do
|
|
30
|
+
@tester.acl_block! do
|
|
31
|
+
actions :foo, :bar do
|
|
32
|
+
default :allow
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
[:to, :except].each do |opt|
|
|
39
|
+
test "should raise an ArgumentError when allow is called with #{opt} option" do
|
|
40
|
+
assert_raise ArgumentError do
|
|
41
|
+
@tester.acl_block! do
|
|
42
|
+
actions :foo do
|
|
43
|
+
allow all, opt => :bar
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "should raise an ArgumentError when deny is called with #{opt} option" do
|
|
50
|
+
assert_raise ArgumentError do
|
|
51
|
+
@tester.acl_block! do
|
|
52
|
+
actions :foo do
|
|
53
|
+
deny all, opt => :bar
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
test "empty actions block should do nothing" do
|
|
61
|
+
@tester.acl_block! do
|
|
62
|
+
actions :foo do
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
allow all
|
|
66
|
+
end
|
|
67
|
+
assert_permitted nil
|
|
68
|
+
assert_permitted nil, :foo
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
test "#allow should limit its scope to specified actions" do
|
|
72
|
+
assert ( bee = User.create ).has_role! :bee
|
|
73
|
+
|
|
74
|
+
@tester.acl_block! do
|
|
75
|
+
actions :edit do
|
|
76
|
+
allow :bee
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
assert_permitted bee, :edit
|
|
80
|
+
assert_forbidden bee, :update
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
test "#deny should limit its scope to specified actions" do
|
|
84
|
+
assert ( bee = User.create ).has_role! :bee
|
|
85
|
+
|
|
86
|
+
@tester.acl_block! do
|
|
87
|
+
default :allow
|
|
88
|
+
actions :edit do
|
|
89
|
+
deny :bee
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
assert_forbidden bee, :edit
|
|
93
|
+
assert_permitted bee, :update
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "#allow and #deny should work together inside actions block" do
|
|
97
|
+
assert foo = Foo.create
|
|
98
|
+
|
|
99
|
+
assert ( owner = User.create ).has_role! :owner, foo
|
|
100
|
+
assert ( hacker = User.create ).has_role! :hacker
|
|
101
|
+
assert hacker.has_role! :the_destroyer
|
|
102
|
+
|
|
103
|
+
assert ( another_owner = User.create ).has_role! :owner, foo
|
|
104
|
+
assert another_owner.has_role! :hacker
|
|
105
|
+
|
|
106
|
+
@tester.acl_block! do
|
|
107
|
+
actions :show, :index do
|
|
108
|
+
allow all
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
actions :edit, :new, :create, :update do
|
|
112
|
+
allow :owner, :of => :foo
|
|
113
|
+
deny :hacker
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
actions :destroy do
|
|
117
|
+
allow :owner, :of => :foo
|
|
118
|
+
allow :the_destroyer
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
assert set_all_actions
|
|
123
|
+
permit_some owner, @all_actions, :foo => foo
|
|
124
|
+
permit_some hacker, %w(show index destroy)
|
|
125
|
+
permit_some another_owner, %w(show index destroy), :foo => foo
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def set_all_actions
|
|
129
|
+
@all_actions = %w(index show new edit create update destroy)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
test "should work with anonymous" do
|
|
133
|
+
assert ( superadmin = User.create ).has_role! :superadmin
|
|
134
|
+
|
|
135
|
+
@tester.acl_block! do
|
|
136
|
+
allow :superadmin
|
|
137
|
+
|
|
138
|
+
action :index, :show do
|
|
139
|
+
allow anonymous
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
assert set_all_actions
|
|
144
|
+
permit_some superadmin, @all_actions
|
|
145
|
+
permit_some nil, %w(index show)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
test "should work with anonymous and other role inside" do
|
|
149
|
+
assert ( superadmin = User.create ).has_role! :superadmin
|
|
150
|
+
assert ( member = User.create ).has_role! :member
|
|
151
|
+
|
|
152
|
+
@tester.acl_block! do
|
|
153
|
+
allow :superadmin
|
|
154
|
+
|
|
155
|
+
action :index, :show do
|
|
156
|
+
allow anonymous
|
|
157
|
+
allow :member
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
assert set_all_actions
|
|
162
|
+
permit_some superadmin, @all_actions
|
|
163
|
+
permit_some member, %w(index show)
|
|
164
|
+
permit_some nil, %w(index show)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module ControllerExtensions
|
|
4
|
+
class AnonTest < Base
|
|
5
|
+
test "allow nil permits only nil" do
|
|
6
|
+
@tester.acl_block! { allow nil }
|
|
7
|
+
|
|
8
|
+
assert_permitted nil
|
|
9
|
+
assert_user_types_forbidden
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "allow anon permits only nil" do
|
|
13
|
+
@tester.acl_block! { allow anonymous }
|
|
14
|
+
|
|
15
|
+
assert_permitted nil
|
|
16
|
+
assert_user_types_forbidden
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "default allowed, nil denied" do
|
|
20
|
+
@tester.acl_block! do
|
|
21
|
+
default :allow
|
|
22
|
+
deny nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
assert_forbidden nil
|
|
26
|
+
assert_user_types_permitted
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test "default allowed, anon denied" do
|
|
30
|
+
@tester.acl_block! do
|
|
31
|
+
default :allow
|
|
32
|
+
deny anonymous
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
assert_forbidden nil
|
|
36
|
+
assert_user_types_permitted
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module ControllerExtensions
|
|
4
|
+
class Base < ActiveSupport::TestCase
|
|
5
|
+
setup do
|
|
6
|
+
# TODO - clean this up so we don't need to create such a complex object just for a test
|
|
7
|
+
@tester = Class.new(Acl9::Dsl::Base) do
|
|
8
|
+
def check_allowance(subject, *args)
|
|
9
|
+
@_subject = subject
|
|
10
|
+
@_current_action = (args[0] || 'index').to_s
|
|
11
|
+
@_objects = args.last.is_a?(Hash) ? args.last : {}
|
|
12
|
+
@_callable = @_objects.delete(:call)
|
|
13
|
+
|
|
14
|
+
instance_eval(allowance_expression)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def _subject_ref
|
|
18
|
+
"@_subject"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def _object_ref(object)
|
|
22
|
+
"@_objects[:#{object}]"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def _action_ref
|
|
26
|
+
"@_current_action"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def _method_ref(method)
|
|
30
|
+
"@_callable.send(:#{method})"
|
|
31
|
+
end
|
|
32
|
+
end.new
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def permit_some(user, actions, vars = {})
|
|
36
|
+
actions.each { |act| assert_permitted(user, act, vars) }
|
|
37
|
+
(@all_actions - actions).each { |act| assert_forbidden(user, act, vars) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def assert_permitted *args
|
|
41
|
+
assert @tester.check_allowance *args
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def assert_forbidden *args
|
|
45
|
+
refute @tester.check_allowance *args
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def assert_all_forbidden
|
|
49
|
+
assert_forbidden nil
|
|
50
|
+
assert_user_types_forbidden
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def assert_all_permitted
|
|
54
|
+
assert_permitted nil
|
|
55
|
+
assert_user_types_permitted
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def assert_user_types_forbidden
|
|
59
|
+
assert @user = User.create
|
|
60
|
+
assert_forbidden @user
|
|
61
|
+
assert_admins_forbidden
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def assert_admins_forbidden
|
|
65
|
+
assert @user = User.first_or_create
|
|
66
|
+
|
|
67
|
+
assert @user.has_role! :admin
|
|
68
|
+
assert_forbidden @user
|
|
69
|
+
|
|
70
|
+
assert @user.has_role! :admin, Foo
|
|
71
|
+
assert_forbidden @user
|
|
72
|
+
|
|
73
|
+
assert @user.has_role! :admin, Foo.first_or_create
|
|
74
|
+
assert_forbidden @user
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def assert_user_types_permitted
|
|
78
|
+
assert @user = User.first_or_create
|
|
79
|
+
assert_permitted @user
|
|
80
|
+
assert_admins_permitted
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def assert_admins_permitted
|
|
84
|
+
assert @user = User.first_or_create
|
|
85
|
+
|
|
86
|
+
assert @user.has_role! :admin
|
|
87
|
+
assert_permitted @user
|
|
88
|
+
|
|
89
|
+
assert @user.has_role! :admin, Foo
|
|
90
|
+
assert_permitted @user
|
|
91
|
+
|
|
92
|
+
assert @user.has_role! :admin, Foo.first_or_create
|
|
93
|
+
assert_permitted @user
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module ControllerExtensions
|
|
4
|
+
class BasicsTest < Base
|
|
5
|
+
test "empty default denies" do
|
|
6
|
+
@tester.acl_block! { }
|
|
7
|
+
assert_equal :deny, @tester.default_action
|
|
8
|
+
assert_all_forbidden
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test "deny default denies" do
|
|
12
|
+
@tester.acl_block! { default :deny }
|
|
13
|
+
assert_equal :deny, @tester.default_action
|
|
14
|
+
assert_all_forbidden
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "allow default allows" do
|
|
18
|
+
@tester.acl_block! { default :allow }
|
|
19
|
+
assert_equal :allow, @tester.default_action
|
|
20
|
+
assert_all_permitted
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test "error with bad args" do
|
|
24
|
+
assert_raise ArgumentError do
|
|
25
|
+
@tester.acl_block! { default 123 }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
assert_raise ArgumentError do
|
|
29
|
+
@tester.acl_block! do
|
|
30
|
+
default :deny
|
|
31
|
+
default :deny
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
assert_raise ArgumentError do
|
|
36
|
+
@tester.acl_block! { allow }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
assert_raise ArgumentError do
|
|
40
|
+
@tester.acl_block! { deny }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module ControllerExtensions
|
|
4
|
+
class ConditionsTest < Base
|
|
5
|
+
[:if, :unless].each do |cond|
|
|
6
|
+
test "should raise ArgumentError when #{cond} is not a Symbol" do
|
|
7
|
+
assert_raise ArgumentError do
|
|
8
|
+
@tester.acl_block! { allow nil, cond => 123 }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
test "allow ... :if" do
|
|
14
|
+
@tester.acl_block! do
|
|
15
|
+
allow nil, :if => :meth
|
|
16
|
+
end
|
|
17
|
+
assert_permitted nil, :call => OpenStruct.new(:meth => true)
|
|
18
|
+
assert_forbidden nil, :call => OpenStruct.new(:meth => false)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test "allow ... :unless" do
|
|
22
|
+
@tester.acl_block! do
|
|
23
|
+
allow nil, :unless => :meth
|
|
24
|
+
end
|
|
25
|
+
assert_permitted nil, :call => OpenStruct.new(:meth => false)
|
|
26
|
+
assert_forbidden nil, :call => OpenStruct.new(:meth => true)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test "deny ... :if" do
|
|
30
|
+
@tester.acl_block! do
|
|
31
|
+
default :allow
|
|
32
|
+
deny nil, :if => :meth
|
|
33
|
+
end
|
|
34
|
+
assert_permitted nil, :call => OpenStruct.new(:meth => false)
|
|
35
|
+
assert_forbidden nil, :call => OpenStruct.new(:meth => true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test "deny ... :unless" do
|
|
39
|
+
@tester.acl_block! do
|
|
40
|
+
default :allow
|
|
41
|
+
deny nil, :unless => :meth
|
|
42
|
+
end
|
|
43
|
+
assert_permitted nil, :call => OpenStruct.new(:meth => true)
|
|
44
|
+
assert_forbidden nil, :call => OpenStruct.new(:meth => false)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|