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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.ruby-version +1 -0
- data/.travis.yml +22 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +114 -0
- data/CONTRIBUTING.md +62 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +141 -0
- data/LICENSE +9 -0
- data/README.md +308 -0
- data/Rakefile +9 -27
- data/acl9.gemspec +29 -0
- data/bin/appraisal +16 -0
- data/bin/bundler +16 -0
- data/bin/cc-tddium-post-worker +16 -0
- data/bin/erubis +16 -0
- data/bin/rackup +16 -0
- data/bin/rails +16 -0
- data/bin/rake +16 -0
- data/bin/sprockets +16 -0
- data/bin/tapout +16 -0
- data/bin/thor +16 -0
- data/bin/tilt +16 -0
- data/bin/yard +16 -0
- data/bin/yardoc +16 -0
- data/bin/yri +16 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/gemfiles/rails_4.1.gemfile +10 -0
- data/gemfiles/rails_4.2.gemfile +10 -0
- data/lib/acl9/controller_extensions/dsl_base.rb +36 -55
- data/lib/acl9/controller_extensions/generators.rb +1 -1
- data/lib/acl9/controller_extensions.rb +1 -1
- 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 +48 -21
- data/lib/acl9/model_extensions.rb +22 -25
- data/lib/acl9/prepositions.rb +18 -0
- data/lib/acl9/version.rb +3 -0
- data/lib/acl9.rb +36 -10
- data/lib/generators/acl9/setup/USAGE +35 -0
- data/lib/generators/acl9/setup/setup_generator.rb +115 -0
- data/lib/generators/acl9/setup/templates/create_role_tables.rb +22 -0
- data/lib/generators/acl9/setup/templates/role.rb +3 -0
- data/test/config_test.rb +55 -0
- data/test/controller_extensions/actions_test.rb +199 -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 +70 -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 +108 -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 +40 -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 +99 -0
- data/test/helpers/helper_test.rb +89 -0
- data/test/models/roles_test.rb +357 -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 +22 -0
- data/test/models/users_roles_and_subjects_with_namespaced_class_names_test.rb +30 -0
- data/test/test_helper.rb +80 -20
- data/test/version_test.rb +7 -0
- metadata +290 -71
- data/CHANGELOG.textile +0 -46
- 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
|
@@ -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
|
data/test/config_test.rb
ADDED
|
@@ -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
|