acl9 0.12.0 → 2.1.2

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 (141) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +22 -0
  5. data/Appraisals +11 -0
  6. data/CHANGELOG.md +114 -0
  7. data/CONTRIBUTING.md +62 -0
  8. data/Gemfile +9 -0
  9. data/Gemfile.lock +141 -0
  10. data/LICENSE +9 -0
  11. data/README.md +308 -0
  12. data/Rakefile +9 -27
  13. data/acl9.gemspec +29 -0
  14. data/bin/appraisal +16 -0
  15. data/bin/bundler +16 -0
  16. data/bin/cc-tddium-post-worker +16 -0
  17. data/bin/erubis +16 -0
  18. data/bin/rackup +16 -0
  19. data/bin/rails +16 -0
  20. data/bin/rake +16 -0
  21. data/bin/sprockets +16 -0
  22. data/bin/tapout +16 -0
  23. data/bin/thor +16 -0
  24. data/bin/tilt +16 -0
  25. data/bin/yard +16 -0
  26. data/bin/yardoc +16 -0
  27. data/bin/yri +16 -0
  28. data/gemfiles/rails_4.0.gemfile +10 -0
  29. data/gemfiles/rails_4.1.gemfile +10 -0
  30. data/gemfiles/rails_4.2.gemfile +10 -0
  31. data/lib/acl9/controller_extensions/dsl_base.rb +36 -55
  32. data/lib/acl9/controller_extensions/generators.rb +1 -1
  33. data/lib/acl9/controller_extensions.rb +1 -1
  34. data/lib/acl9/helpers.rb +12 -5
  35. data/lib/acl9/model_extensions/for_object.rb +20 -5
  36. data/lib/acl9/model_extensions/for_subject.rb +48 -21
  37. data/lib/acl9/model_extensions.rb +22 -25
  38. data/lib/acl9/prepositions.rb +18 -0
  39. data/lib/acl9/version.rb +3 -0
  40. data/lib/acl9.rb +36 -10
  41. data/lib/generators/acl9/setup/USAGE +35 -0
  42. data/lib/generators/acl9/setup/setup_generator.rb +115 -0
  43. data/lib/generators/acl9/setup/templates/create_role_tables.rb +22 -0
  44. data/lib/generators/acl9/setup/templates/role.rb +3 -0
  45. data/test/config_test.rb +55 -0
  46. data/test/controller_extensions/actions_test.rb +199 -0
  47. data/test/controller_extensions/anon_test.rb +39 -0
  48. data/test/controller_extensions/base.rb +96 -0
  49. data/test/controller_extensions/basics_test.rb +44 -0
  50. data/test/controller_extensions/conditions_test.rb +48 -0
  51. data/test/controller_extensions/method_test.rb +70 -0
  52. data/test/controller_extensions/multi_match_test.rb +142 -0
  53. data/test/controller_extensions/multiple_role_arguments_test.rb +135 -0
  54. data/test/controller_extensions/prepositions_test.rb +108 -0
  55. data/test/controller_extensions/pseudo_role_test.rb +26 -0
  56. data/test/controller_extensions/role_test.rb +75 -0
  57. data/test/controllers/acl_action_override_test.rb +24 -0
  58. data/test/controllers/acl_arguments_test.rb +5 -0
  59. data/test/controllers/acl_block_test.rb +5 -0
  60. data/test/controllers/acl_boolean_method_test.rb +5 -0
  61. data/test/controllers/acl_helper_method_test.rb +26 -0
  62. data/test/controllers/acl_ivars_test.rb +15 -0
  63. data/test/controllers/acl_method2_test.rb +6 -0
  64. data/test/controllers/acl_method_test.rb +6 -0
  65. data/test/controllers/acl_object_hash_test.rb +18 -0
  66. data/test/controllers/acl_query_method_named_test.rb +9 -0
  67. data/test/controllers/acl_query_method_test.rb +9 -0
  68. data/test/controllers/acl_query_method_with_lambda_test.rb +9 -0
  69. data/test/controllers/acl_query_mixin.rb +51 -0
  70. data/test/controllers/acl_subject_method_test.rb +15 -0
  71. data/test/controllers/arguments_checking_test.rb +43 -0
  72. data/test/dummy/app/controllers/acl_action_override.rb +15 -0
  73. data/test/dummy/app/controllers/acl_arguments.rb +10 -0
  74. data/test/dummy/app/controllers/acl_block.rb +6 -0
  75. data/test/dummy/app/controllers/acl_boolean_method.rb +23 -0
  76. data/test/dummy/app/controllers/acl_helper_method.rb +11 -0
  77. data/test/dummy/app/controllers/acl_ivars.rb +17 -0
  78. data/test/dummy/app/controllers/acl_method.rb +6 -0
  79. data/test/dummy/app/controllers/acl_method2.rb +6 -0
  80. data/test/dummy/app/controllers/acl_objects_hash.rb +10 -0
  81. data/test/dummy/app/controllers/acl_query_method.rb +9 -0
  82. data/test/dummy/app/controllers/acl_query_method_named.rb +13 -0
  83. data/test/dummy/app/controllers/acl_query_method_with_lambda.rb +9 -0
  84. data/test/dummy/app/controllers/acl_subject_method.rb +16 -0
  85. data/test/dummy/app/controllers/application_controller.rb +7 -0
  86. data/test/dummy/app/controllers/empty_controller.rb +5 -0
  87. data/test/dummy/app/helpers/application_helper.rb +2 -0
  88. data/test/dummy/app/helpers/some_helper.rb +8 -0
  89. data/test/dummy/app/models/.keep +0 -0
  90. data/test/dummy/app/models/access.rb +3 -0
  91. data/test/dummy/app/models/account.rb +3 -0
  92. data/test/dummy/app/models/bar.rb +3 -0
  93. data/test/dummy/app/models/concerns/.keep +0 -0
  94. data/test/dummy/app/models/foo.rb +3 -0
  95. data/test/dummy/app/models/foo_bar.rb +3 -0
  96. data/test/dummy/app/models/other/foo.rb +5 -0
  97. data/test/dummy/app/models/other/role.rb +5 -0
  98. data/test/dummy/app/models/other/user.rb +5 -0
  99. data/test/dummy/app/models/role.rb +3 -0
  100. data/test/dummy/app/models/user.rb +3 -0
  101. data/test/dummy/app/models/uuid.rb +4 -0
  102. data/test/dummy/config/application.rb +23 -0
  103. data/test/dummy/config/boot.rb +4 -0
  104. data/test/dummy/config/database.yml +25 -0
  105. data/test/dummy/config/environment.rb +5 -0
  106. data/test/dummy/config/environments/development.rb +37 -0
  107. data/test/dummy/config/environments/production.rb +78 -0
  108. data/test/dummy/config/environments/test.rb +40 -0
  109. data/test/dummy/config/initializers/assets.rb +8 -0
  110. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  111. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  112. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  113. data/test/dummy/config/initializers/inflections.rb +16 -0
  114. data/test/dummy/config/initializers/mime_types.rb +4 -0
  115. data/test/dummy/config/initializers/secrets.rb +1 -0
  116. data/test/dummy/config/initializers/session_store.rb +3 -0
  117. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  118. data/test/dummy/config/locales/en.yml +23 -0
  119. data/test/dummy/config/routes.rb +3 -0
  120. data/test/dummy/config.ru +4 -0
  121. data/test/dummy/db/migrate/20141117132218_create_tables.rb +99 -0
  122. data/test/helpers/helper_test.rb +89 -0
  123. data/test/models/roles_test.rb +357 -0
  124. data/test/models/roles_with_custom_association_names_test.rb +28 -0
  125. data/test/models/roles_with_custom_class_names_test.rb +28 -0
  126. data/test/models/system_roles_test.rb +22 -0
  127. data/test/models/users_roles_and_subjects_with_namespaced_class_names_test.rb +30 -0
  128. data/test/test_helper.rb +80 -20
  129. data/test/version_test.rb +7 -0
  130. metadata +290 -71
  131. data/CHANGELOG.textile +0 -46
  132. data/README.textile +0 -903
  133. data/VERSION.yml +0 -5
  134. data/lib/acl9/config.rb +0 -11
  135. data/test/access_control_test.rb +0 -338
  136. data/test/dsl_base_test.rb +0 -795
  137. data/test/helpers_test.rb +0 -134
  138. data/test/roles_test.rb +0 -355
  139. data/test/support/controllers.rb +0 -207
  140. data/test/support/models.rb +0 -59
  141. data/test/support/schema.rb +0 -92
@@ -0,0 +1,115 @@
1
+ require "rails/generators/active_record"
2
+
3
+ module Acl9
4
+ class SetupGenerator < Rails::Generators::Base
5
+ include ActiveRecord::Generators::Migration
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ argument :arg_subject, type: :string, default: 'user', banner: "subject"
10
+ argument :arg_role, type: :string, default: 'role', banner: "role"
11
+ argument :arg_objects, type: :array, default: [], banner: "objects..."
12
+
13
+ def create_migration
14
+ next_migration_number = self.class.next_migration_number( File.expand_path( '../db/migrate', __FILE__))
15
+ template "create_role_tables.rb", "db/migrate/#{next_migration_number}_create_#{role_name}_tables.rb"
16
+ end
17
+
18
+ def create_models
19
+ template "role.rb", "app/models/#{role_name}.rb"
20
+
21
+ objects.each do |object|
22
+ my_inject "app/models/#{object}.rb", object.classify, " #{object_helper}\n"
23
+ end
24
+
25
+ my_inject "app/models/#{subject_name}.rb", subject_class_name, " #{subject_helper}\n"
26
+ end
27
+
28
+ def create_initializer
29
+ initializer "acl9.rb" do
30
+ <<-RUBY.strip_heredoc
31
+ # See https://github.com/be9/acl9#configuration for details
32
+ #
33
+ # Acl9.configure do |c|
34
+ # c.default_role_class_name = 'Role'
35
+ # c.default_subject_class_name = 'User'
36
+ # c.default_subject_method = :current_user
37
+ # c.default_association_name = :role_objects
38
+ # c.default_join_table_name = nil
39
+ # c.protect_global_roles = true
40
+ # c.normalize_role_names = true
41
+ # end
42
+ RUBY
43
+ end
44
+ end
45
+
46
+ private
47
+ def role_name
48
+ arg_role.underscore.singularize
49
+ end
50
+
51
+ def role_table_name
52
+ role_name.tableize
53
+ end
54
+
55
+ def role_class_name
56
+ role_name.classify
57
+ end
58
+
59
+ def habtm_table
60
+ Acl9.config.default_join_table_name || [ subject_name, role_name ].map(&:pluralize).sort.join('_')
61
+ end
62
+
63
+ def subject_helper
64
+ "acts_as_authorization_subject" + ( subject_options ? " #{subject_options}" : '' )
65
+ end
66
+
67
+ def object_helper
68
+ "acts_as_authorization_object" + ( object_options ? " #{object_options}" : '' )
69
+ end
70
+
71
+ def role_helper
72
+ "acts_as_authorization_role" + ( role_options ? " #{role_options}" : '' )
73
+ end
74
+
75
+ def my_inject file_name, class_name, string
76
+ inject_into_class file_name, class_name, string
77
+ rescue Errno::ENOENT
78
+ create_file file_name do
79
+ <<-RUBY.strip_heredoc
80
+ class #{class_name} < ActiveRecord::Base
81
+ #{string}
82
+ end
83
+ RUBY
84
+ end
85
+ end
86
+
87
+ def role_options
88
+ if defined?(Acl9::config) && Acl9::config[:default_subject_class_name].to_s.classify != subject_class_name
89
+ "subject_class_name: #{subject_class_name}"
90
+ end
91
+ end
92
+
93
+ def subject_options
94
+ if defined?(Acl9::config) && Acl9::config[:default_role_class_name].to_s.classify != role_class_name
95
+ "role_class_name: #{role_class_name}"
96
+ end
97
+ end
98
+
99
+ def object_options
100
+ [ role_options, subject_options ].compact.join ', '
101
+ end
102
+
103
+ def subject_name
104
+ @subject_name ||= arg_subject.underscore.singularize
105
+ end
106
+
107
+ def objects
108
+ @objects ||= arg_objects.map{|o|o.underscore.singularize}
109
+ end
110
+
111
+ def subject_class_name
112
+ subject_name.classify
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,22 @@
1
+ class Create<%= role_class_name %>Tables < ActiveRecord::Migration
2
+ def change
3
+ create_table :<%= role_table_name %> do |t|
4
+ t.string :name, null: false
5
+ t.string :authorizable_type, null: true
6
+ t.integer :authorizable_id, null: true
7
+ t.boolean :system, default: false, null: false
8
+ t.timestamps null: false
9
+ end
10
+
11
+ add_index :<%= role_table_name %>, :name
12
+ add_index :<%= role_table_name %>, [:authorizable_type, :authorizable_id]
13
+
14
+ create_table :<%= habtm_table %>, id: false do |t|
15
+ t.references :<%= subject_name %>, null: false
16
+ t.references :<%= role_name %>, null: false
17
+ end
18
+
19
+ add_index :<%= habtm_table %>, :<%= subject_name %>_id
20
+ add_index :<%= habtm_table %>, :<%= role_name %>_id
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ class <%= role_class_name %> < ActiveRecord::Base
2
+ <%= role_helper %>
3
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class ConfigTest < ActiveSupport::TestCase
4
+ teardown do
5
+ Acl9.config.reset!
6
+ end
7
+
8
+ test "configure block API" do
9
+ assert new_method = :fruitcake
10
+ Acl9.configure do |c|
11
+ assert c.default_subject_method = new_method
12
+ end
13
+
14
+ assert_equal new_method, Acl9.config.default_subject_method
15
+ assert_equal new_method, Acl9.config[:default_subject_method]
16
+ assert_equal new_method, Acl9::config[:default_subject_method]
17
+ end
18
+
19
+ test "method API" do
20
+ assert new_method = :seesaw
21
+ Acl9.config.default_subject_method = new_method
22
+
23
+ assert_equal new_method, Acl9.config.default_subject_method
24
+ assert_equal new_method, Acl9.config[:default_subject_method]
25
+ assert_equal new_method, Acl9::config[:default_subject_method]
26
+ end
27
+
28
+ test "hash API" do
29
+ assert new_method = :sandcastle
30
+ assert Acl9.config[:default_subject_method] = new_method
31
+
32
+ assert_equal new_method, Acl9.config.default_subject_method
33
+ assert_equal new_method, Acl9.config[:default_subject_method]
34
+ assert_equal new_method, Acl9::config[:default_subject_method]
35
+ end
36
+
37
+ test "reset!" do
38
+ assert new_method = :bluesky
39
+ assert Acl9.config.default_subject_method = new_method
40
+
41
+ assert Acl9.config.reset!
42
+
43
+ refute_equal new_method, Acl9.config.default_subject_method
44
+ end
45
+
46
+ test "errors when missing option" do
47
+ assert_raises NoMethodError do
48
+ Acl9.config[:does_not_exist] = :foo
49
+ end
50
+
51
+ assert_raises NoMethodError do
52
+ Acl9.config[:does_not_exist]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,199 @@
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, :only, :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
+
167
+ test "multiple allows in an action" do
168
+ assert ( special = User.create ).has_role! :special
169
+ assert ( viewer = User.create ).has_role! :viewer
170
+
171
+ @tester.acl_block! do
172
+ action :show do
173
+ allow all
174
+ allow :viewer
175
+ end
176
+ end
177
+
178
+ assert set_all_actions
179
+ permit_some special, %w(show)
180
+ permit_some viewer, %w(show)
181
+ end
182
+
183
+ test "multiple allows with logged_in" do
184
+ assert ( normal = User.create )
185
+ assert ( viewer = User.create ).has_role! :viewer
186
+
187
+ @tester.acl_block! do
188
+ action :index do
189
+ allow logged_in
190
+ allow :viewer
191
+ end
192
+ end
193
+
194
+ assert set_all_actions
195
+ permit_some normal, %w(index)
196
+ permit_some viewer, %w(index)
197
+ end
198
+ end
199
+ 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
@@ -0,0 +1,70 @@
1
+ require_relative 'base'
2
+
3
+ module ControllerExtensions
4
+ class MethodTest < Base
5
+ def run_tests
6
+ %w(index show).each { |act| assert_permitted nil, act }
7
+ %w(edit update delete destroy).each { |act| assert_forbidden nil, act }
8
+
9
+ %w(index show edit update).each { |act| assert_permitted @manager, act }
10
+ %w(delete destroy).each { |act| assert_forbidden @manager, act }
11
+
12
+ %w(index show edit update delete destroy).each { |act| assert_permitted @trusted, act }
13
+ end
14
+
15
+ test "should raise an ArgumentError when either :to or :only and :except are specified" do
16
+ %i[to only].each do |only|
17
+ assert_raise ArgumentError do
18
+ @tester.acl_block! { allow all, only => :index, :except => ['show', 'edit'] }
19
+ end
20
+ end
21
+ end
22
+
23
+ test ":to and :only should combine in union" do
24
+ assert ( @manager = User.create ).has_role! :manager
25
+ assert ( @trusted = User.create ).has_role! :trusted
26
+
27
+ @tester.acl_block! do
28
+ allow all, :only => :index, :to => :show
29
+
30
+ allow 'manager', :only => :edit, :to => 'edit'
31
+ allow 'manager', :to => 'update', :only => :update
32
+ allow 'trusted', :only => %w(edit update destroy), :to => %w(edit delete)
33
+ end
34
+
35
+ run_tests
36
+ end
37
+
38
+
39
+ test ":to and :only should limit rule scope to specified actions" do
40
+ assert ( @manager = User.create ).has_role! :manager
41
+ assert ( @trusted = User.create ).has_role! :trusted
42
+
43
+ %i[to only].each do |only|
44
+ @tester.acl_block! do
45
+ allow all, only => [:index, :show]
46
+
47
+ allow 'manager', only => :edit
48
+ allow 'manager', only => 'update'
49
+ allow 'trusted', only => %w(edit update delete destroy)
50
+ end
51
+
52
+ run_tests
53
+ end
54
+ end
55
+
56
+ test ":except should limit rule scope to all actions except specified" do
57
+ assert ( @manager = User.create ).has_role! :manager
58
+ assert ( @trusted = User.create ).has_role! :trusted
59
+
60
+ @tester.acl_block! do
61
+ allow all, :except => %w(edit update delete destroy)
62
+
63
+ allow 'manager', :except => %w(delete destroy)
64
+ allow 'trusted'
65
+ end
66
+
67
+ run_tests
68
+ end
69
+ end
70
+ end