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.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +19 -0
  4. data/Appraisals +8 -0
  5. data/CONTRIBUTING.md +58 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +103 -0
  8. data/LICENSE +9 -0
  9. data/README.md +156 -0
  10. data/Rakefile +8 -27
  11. data/acl9.gemspec +29 -0
  12. data/gemfiles/rails_4.0.gemfile +8 -0
  13. data/gemfiles/rails_4.1.gemfile +8 -0
  14. data/lib/acl9/controller_extensions/dsl_base.rb +14 -38
  15. data/lib/acl9/helpers.rb +12 -5
  16. data/lib/acl9/model_extensions/for_object.rb +20 -5
  17. data/lib/acl9/model_extensions/for_subject.rb +25 -20
  18. data/lib/acl9/model_extensions.rb +8 -23
  19. data/lib/acl9/version.rb +3 -0
  20. data/lib/acl9.rb +16 -12
  21. data/test/controller_extensions/actions_test.rb +167 -0
  22. data/test/controller_extensions/anon_test.rb +39 -0
  23. data/test/controller_extensions/base.rb +96 -0
  24. data/test/controller_extensions/basics_test.rb +44 -0
  25. data/test/controller_extensions/conditions_test.rb +48 -0
  26. data/test/controller_extensions/method_test.rb +50 -0
  27. data/test/controller_extensions/multi_match_test.rb +142 -0
  28. data/test/controller_extensions/multiple_role_arguments_test.rb +135 -0
  29. data/test/controller_extensions/prepositions_test.rb +99 -0
  30. data/test/controller_extensions/pseudo_role_test.rb +26 -0
  31. data/test/controller_extensions/role_test.rb +75 -0
  32. data/test/controllers/acl_action_override_test.rb +24 -0
  33. data/test/controllers/acl_arguments_test.rb +5 -0
  34. data/test/controllers/acl_block_test.rb +5 -0
  35. data/test/controllers/acl_boolean_method_test.rb +5 -0
  36. data/test/controllers/acl_helper_method_test.rb +26 -0
  37. data/test/controllers/acl_ivars_test.rb +15 -0
  38. data/test/controllers/acl_method2_test.rb +6 -0
  39. data/test/controllers/acl_method_test.rb +6 -0
  40. data/test/controllers/acl_object_hash_test.rb +18 -0
  41. data/test/controllers/acl_query_method_named_test.rb +9 -0
  42. data/test/controllers/acl_query_method_test.rb +9 -0
  43. data/test/controllers/acl_query_method_with_lambda_test.rb +9 -0
  44. data/test/controllers/acl_query_mixin.rb +51 -0
  45. data/test/controllers/acl_subject_method_test.rb +15 -0
  46. data/test/controllers/arguments_checking_test.rb +43 -0
  47. data/test/dummy/app/controllers/acl_action_override.rb +15 -0
  48. data/test/dummy/app/controllers/acl_arguments.rb +10 -0
  49. data/test/dummy/app/controllers/acl_block.rb +6 -0
  50. data/test/dummy/app/controllers/acl_boolean_method.rb +23 -0
  51. data/test/dummy/app/controllers/acl_helper_method.rb +11 -0
  52. data/test/dummy/app/controllers/acl_ivars.rb +17 -0
  53. data/test/dummy/app/controllers/acl_method.rb +6 -0
  54. data/test/dummy/app/controllers/acl_method2.rb +6 -0
  55. data/test/dummy/app/controllers/acl_objects_hash.rb +10 -0
  56. data/test/dummy/app/controllers/acl_query_method.rb +9 -0
  57. data/test/dummy/app/controllers/acl_query_method_named.rb +13 -0
  58. data/test/dummy/app/controllers/acl_query_method_with_lambda.rb +9 -0
  59. data/test/dummy/app/controllers/acl_subject_method.rb +16 -0
  60. data/test/dummy/app/controllers/application_controller.rb +7 -0
  61. data/test/dummy/app/controllers/empty_controller.rb +5 -0
  62. data/test/dummy/app/helpers/application_helper.rb +2 -0
  63. data/test/dummy/app/helpers/some_helper.rb +8 -0
  64. data/test/dummy/app/models/.keep +0 -0
  65. data/test/dummy/app/models/access.rb +3 -0
  66. data/test/dummy/app/models/account.rb +3 -0
  67. data/test/dummy/app/models/bar.rb +3 -0
  68. data/test/dummy/app/models/concerns/.keep +0 -0
  69. data/test/dummy/app/models/foo.rb +3 -0
  70. data/test/dummy/app/models/foo_bar.rb +3 -0
  71. data/test/dummy/app/models/other/foo.rb +5 -0
  72. data/test/dummy/app/models/other/role.rb +5 -0
  73. data/test/dummy/app/models/other/user.rb +5 -0
  74. data/test/dummy/app/models/role.rb +3 -0
  75. data/test/dummy/app/models/user.rb +3 -0
  76. data/test/dummy/app/models/uuid.rb +4 -0
  77. data/test/dummy/config/application.rb +23 -0
  78. data/test/dummy/config/boot.rb +4 -0
  79. data/test/dummy/config/database.yml +25 -0
  80. data/test/dummy/config/environment.rb +5 -0
  81. data/test/dummy/config/environments/development.rb +37 -0
  82. data/test/dummy/config/environments/production.rb +78 -0
  83. data/test/dummy/config/environments/test.rb +39 -0
  84. data/test/dummy/config/initializers/assets.rb +8 -0
  85. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  86. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  87. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  88. data/test/dummy/config/initializers/inflections.rb +16 -0
  89. data/test/dummy/config/initializers/mime_types.rb +4 -0
  90. data/test/dummy/config/initializers/secrets.rb +1 -0
  91. data/test/dummy/config/initializers/session_store.rb +3 -0
  92. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  93. data/test/dummy/config/locales/en.yml +23 -0
  94. data/test/dummy/config/routes.rb +3 -0
  95. data/test/dummy/config.ru +4 -0
  96. data/test/dummy/db/migrate/20141117132218_create_tables.rb +102 -0
  97. data/test/helpers/helper_test.rb +89 -0
  98. data/test/models/roles_test.rb +251 -0
  99. data/test/models/roles_with_custom_association_names_test.rb +28 -0
  100. data/test/models/roles_with_custom_class_names_test.rb +28 -0
  101. data/test/models/system_roles_test.rb +16 -0
  102. data/test/models/users_roles_and_subjects_with_namespaced_class_names_test.rb +30 -0
  103. data/test/test_helper.rb +72 -20
  104. data/test/version_test.rb +7 -0
  105. metadata +266 -70
  106. data/README.textile +0 -903
  107. data/VERSION.yml +0 -5
  108. data/lib/acl9/config.rb +0 -11
  109. data/test/access_control_test.rb +0 -338
  110. data/test/dsl_base_test.rb +0 -795
  111. data/test/helpers_test.rb +0 -134
  112. data/test/roles_test.rb +0 -355
  113. data/test/support/controllers.rb +0 -207
  114. data/test/support/models.rb +0 -59
  115. 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.has_role? role_name, self
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.has_role! role_name, self
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.has_no_role! role_name, self
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.has_roles_for? self
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.roles_for self
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.role_objects.find_by_name(role_name.to_s) ||
40
- self.role_objects.member?(get_role(role_name, nil))
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.role_objects.exists?(role.id)
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.role_objects << role if role && !self.role_objects.exists?(role.id)
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.role_objects.detect(&role_selecting_lambda(object))
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.role_objects.select(&role_selecting_lambda(object))
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.role_objects.map(&:id).each do |role_id|
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.authorizable_type == object.class.base_class.to_s && role.authorizable == object
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.first :conditions => cond
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.role_objects.delete role
163
-
164
- role.destroy if role.send(self._auth_subject_class_name.demodulize.tableize).empty?
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
- self.class._auth_role_assoc_name
181
+ self.class._auth_role_assoc_name
176
182
  end
177
183
 
178
- def role_objects
179
- send(self._auth_role_assoc)
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
- assoc = options[:association_name] || Acl9::config[:default_association_name]
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
- sql_tables = <<-EOS
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
- join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(subject))
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,
@@ -0,0 +1,3 @@
1
+ module Acl9
2
+ VERSION = "1.0.0"
3
+ end
data/lib/acl9.rb CHANGED
@@ -1,16 +1,20 @@
1
- require File.join(File.dirname(__FILE__), 'acl9', 'config')
1
+ require 'acl9/version'
2
+ require 'acl9/model_extensions'
3
+ require 'acl9/controller_extensions'
4
+ require 'acl9/helpers'
2
5
 
3
- if defined? ActiveRecord::Base
4
- require File.join(File.dirname(__FILE__), 'acl9', 'model_extensions')
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
- ActiveRecord::Base.send(:include, Acl9::ModelExtensions)
15
+ mattr_reader :config
7
16
  end
8
17
 
9
-
10
- if defined? ActionController::Base
11
- require File.join(File.dirname(__FILE__), 'acl9', 'controller_extensions')
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