acl9 0.12.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +21 -7
  3. data/.travis.yml +19 -0
  4. data/Appraisals +8 -0
  5. data/CONTRIBUTING.md +58 -0
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +88 -32
  8. data/LICENSE +9 -0
  9. data/README.md +156 -0
  10. data/Rakefile +6 -3
  11. data/acl9.gemspec +10 -13
  12. data/gemfiles/rails_4.0.gemfile +8 -0
  13. data/gemfiles/rails_4.1.gemfile +8 -0
  14. data/lib/acl9/model_extensions/for_subject.rb +5 -1
  15. data/lib/acl9/model_extensions.rb +3 -24
  16. data/lib/acl9/version.rb +1 -1
  17. data/lib/acl9.rb +1 -1
  18. data/test/controller_extensions/actions_test.rb +167 -0
  19. data/test/controller_extensions/anon_test.rb +39 -0
  20. data/test/controller_extensions/base.rb +96 -0
  21. data/test/controller_extensions/basics_test.rb +44 -0
  22. data/test/controller_extensions/conditions_test.rb +48 -0
  23. data/test/controller_extensions/method_test.rb +50 -0
  24. data/test/controller_extensions/multi_match_test.rb +142 -0
  25. data/test/controller_extensions/multiple_role_arguments_test.rb +135 -0
  26. data/test/controller_extensions/prepositions_test.rb +99 -0
  27. data/test/controller_extensions/pseudo_role_test.rb +26 -0
  28. data/test/controller_extensions/role_test.rb +75 -0
  29. data/test/controllers/acl_action_override_test.rb +24 -0
  30. data/test/controllers/acl_arguments_test.rb +5 -0
  31. data/test/controllers/acl_block_test.rb +5 -0
  32. data/test/controllers/acl_boolean_method_test.rb +5 -0
  33. data/test/controllers/acl_helper_method_test.rb +26 -0
  34. data/test/controllers/acl_ivars_test.rb +15 -0
  35. data/test/controllers/acl_method2_test.rb +6 -0
  36. data/test/controllers/acl_method_test.rb +6 -0
  37. data/test/controllers/acl_object_hash_test.rb +18 -0
  38. data/test/controllers/acl_query_method_named_test.rb +9 -0
  39. data/test/controllers/acl_query_method_test.rb +9 -0
  40. data/test/controllers/acl_query_method_with_lambda_test.rb +9 -0
  41. data/test/controllers/acl_query_mixin.rb +51 -0
  42. data/test/controllers/acl_subject_method_test.rb +15 -0
  43. data/test/controllers/arguments_checking_test.rb +43 -0
  44. data/test/dummy/app/controllers/acl_action_override.rb +15 -0
  45. data/test/dummy/app/controllers/acl_arguments.rb +10 -0
  46. data/test/dummy/app/controllers/acl_block.rb +6 -0
  47. data/test/dummy/app/controllers/acl_boolean_method.rb +23 -0
  48. data/test/dummy/app/controllers/acl_helper_method.rb +11 -0
  49. data/test/dummy/app/controllers/acl_ivars.rb +17 -0
  50. data/test/dummy/app/controllers/acl_method.rb +6 -0
  51. data/test/dummy/app/controllers/acl_method2.rb +6 -0
  52. data/test/dummy/app/controllers/acl_objects_hash.rb +10 -0
  53. data/test/dummy/app/controllers/acl_query_method.rb +9 -0
  54. data/test/dummy/app/controllers/acl_query_method_named.rb +13 -0
  55. data/test/dummy/app/controllers/acl_query_method_with_lambda.rb +9 -0
  56. data/test/dummy/app/controllers/acl_subject_method.rb +16 -0
  57. data/test/dummy/app/controllers/application_controller.rb +7 -0
  58. data/test/dummy/app/controllers/empty_controller.rb +5 -0
  59. data/test/dummy/app/helpers/application_helper.rb +2 -0
  60. data/test/dummy/app/helpers/some_helper.rb +8 -0
  61. data/test/dummy/app/models/.keep +0 -0
  62. data/test/dummy/app/models/access.rb +3 -0
  63. data/test/dummy/app/models/account.rb +3 -0
  64. data/test/dummy/app/models/bar.rb +3 -0
  65. data/test/dummy/app/models/concerns/.keep +0 -0
  66. data/test/dummy/app/models/foo.rb +3 -0
  67. data/test/dummy/app/models/foo_bar.rb +3 -0
  68. data/test/dummy/app/models/other/foo.rb +5 -0
  69. data/test/dummy/app/models/other/role.rb +5 -0
  70. data/test/dummy/app/models/other/user.rb +5 -0
  71. data/test/dummy/app/models/role.rb +3 -0
  72. data/test/dummy/app/models/user.rb +3 -0
  73. data/test/dummy/app/models/uuid.rb +4 -0
  74. data/test/dummy/config/application.rb +23 -0
  75. data/test/dummy/config/boot.rb +4 -0
  76. data/test/dummy/config/database.yml +25 -0
  77. data/test/dummy/config/environment.rb +5 -0
  78. data/test/dummy/config/environments/development.rb +37 -0
  79. data/test/dummy/config/environments/production.rb +78 -0
  80. data/test/dummy/config/environments/test.rb +39 -0
  81. data/test/dummy/config/initializers/assets.rb +8 -0
  82. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  83. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  84. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  85. data/test/dummy/config/initializers/inflections.rb +16 -0
  86. data/test/dummy/config/initializers/mime_types.rb +4 -0
  87. data/test/dummy/config/initializers/secrets.rb +1 -0
  88. data/test/dummy/config/initializers/session_store.rb +3 -0
  89. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  90. data/test/dummy/config/locales/en.yml +23 -0
  91. data/test/dummy/config/routes.rb +3 -0
  92. data/test/dummy/config.ru +4 -0
  93. data/test/dummy/db/migrate/20141117132218_create_tables.rb +102 -0
  94. data/test/helpers/helper_test.rb +89 -0
  95. data/test/models/roles_test.rb +251 -0
  96. data/test/models/roles_with_custom_association_names_test.rb +28 -0
  97. data/test/models/roles_with_custom_class_names_test.rb +28 -0
  98. data/test/models/system_roles_test.rb +16 -0
  99. data/test/models/users_roles_and_subjects_with_namespaced_class_names_test.rb +30 -0
  100. data/test/test_helper.rb +76 -23
  101. data/test/version_test.rb +2 -2
  102. metadata +190 -74
  103. data/README.textile +0 -921
  104. data/VERSION.yml +0 -5
  105. data/init.rb +0 -1
  106. data/test/access_control_test.rb +0 -338
  107. data/test/dsl_base_test.rb +0 -795
  108. data/test/helpers_test.rb +0 -133
  109. data/test/roles_test.rb +0 -370
  110. data/test/support/controllers.rb +0 -207
  111. data/test/support/models.rb +0 -59
  112. data/test/support/schema.rb +0 -93
@@ -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
@@ -0,0 +1,50 @@
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 both :to and :except are specified" do
16
+ assert_raise ArgumentError do
17
+ @tester.acl_block! { allow all, :to => :index, :except => ['show', 'edit'] }
18
+ end
19
+ end
20
+
21
+ test ":to should limit rule scope to specified actions" do
22
+ assert ( @manager = User.create ).has_role! :manager
23
+ assert ( @trusted = User.create ).has_role! :trusted
24
+
25
+ @tester.acl_block! do
26
+ allow all, :to => [:index, :show]
27
+
28
+ allow 'manager', :to => :edit
29
+ allow 'manager', :to => 'update'
30
+ allow 'trusted', :to => %w(edit update delete destroy)
31
+ end
32
+
33
+ run_tests
34
+ end
35
+
36
+ test ":except should limit rule scope to all actions except specified" do
37
+ assert ( @manager = User.create ).has_role! :manager
38
+ assert ( @trusted = User.create ).has_role! :trusted
39
+
40
+ @tester.acl_block! do
41
+ allow all, :except => %w(edit update delete destroy)
42
+
43
+ allow 'manager', :except => %w(delete destroy)
44
+ allow 'trusted'
45
+ end
46
+
47
+ run_tests
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,142 @@
1
+ require_relative 'base'
2
+
3
+ module ControllerExtensions
4
+ class MultiMatchTest < Base
5
+ test "default when nothing else matches" do
6
+ @tester.acl_block! do
7
+ default :allow
8
+ allow :blah
9
+ deny :bzz
10
+ end
11
+
12
+ assert_equal :allow, @tester.default_action
13
+ assert_all_permitted
14
+ end
15
+
16
+ test "should deny when deny is matched, but allow is not" do
17
+ @tester.acl_block! do
18
+ default :allow
19
+ deny all
20
+ allow :blah
21
+ end
22
+
23
+ assert_all_forbidden
24
+ end
25
+
26
+ test "allow allowed and deny denied and default for unmatched" do
27
+ assert ( cool_user = User.create ).has_role! :cool
28
+ assert ( jerk_user = User.create ).has_role! :jerk
29
+
30
+ @tester.acl_block! do
31
+ default :allow
32
+ deny :jerk
33
+ allow :cool
34
+ end
35
+
36
+ assert_forbidden jerk_user
37
+ assert_permitted cool_user
38
+ assert_all_permitted
39
+ end
40
+
41
+ test "allowed by default when both match" do
42
+ assert ( cool_user = User.create ).has_role! :cool
43
+ assert ( jerk_user = User.create ).has_role! :jerk
44
+
45
+ @tester.acl_block! do
46
+ default :allow
47
+ deny :cool
48
+ allow :cool
49
+ end
50
+
51
+ assert_permitted cool_user
52
+ assert_permitted jerk_user
53
+ assert_all_permitted
54
+ end
55
+
56
+ test "allowed by default when both all" do
57
+ assert ( cool_user = User.create ).has_role! :cool
58
+ assert ( jerk_user = User.create ).has_role! :jerk
59
+
60
+ @tester.acl_block! do
61
+ default :allow
62
+ deny all
63
+ allow all
64
+ end
65
+
66
+ assert_permitted cool_user
67
+ assert_permitted jerk_user
68
+ assert_all_permitted
69
+ end
70
+
71
+ test "allow logged_in allows user not anon" do
72
+ @tester.acl_block! do
73
+ allow logged_in
74
+ end
75
+
76
+ assert_forbidden nil
77
+ assert_user_types_permitted
78
+ end
79
+
80
+ test "deny logged_in denies user not anon" do
81
+ @tester.acl_block! do
82
+ default :allow
83
+ deny logged_in
84
+ end
85
+
86
+ assert_permitted nil
87
+ assert_user_types_forbidden
88
+ end
89
+
90
+ test "denies unmatched when default deny" do
91
+ @tester.acl_block! do
92
+ default :deny
93
+ allow :blah
94
+ deny :bzz
95
+ end
96
+
97
+ assert_all_forbidden
98
+ end
99
+
100
+ test "deny all when allow unmatched" do
101
+ @tester.acl_block! do
102
+ default :allow
103
+ deny all
104
+ allow :blah
105
+ end
106
+
107
+ assert_all_forbidden
108
+ end
109
+
110
+ test "allow when allow matches and deny doesn't" do
111
+ @tester.acl_block! do
112
+ default :deny
113
+ deny nil
114
+ allow :admin
115
+ end
116
+
117
+ assert_admins_permitted
118
+ end
119
+
120
+ test "denied by default when both match" do
121
+ assert ( user = User.create ).has_role! :cool
122
+
123
+ @tester.acl_block! do
124
+ default :deny
125
+ deny :cool
126
+ allow :cool
127
+ end
128
+
129
+ assert_forbidden user
130
+ end
131
+
132
+ test "denied by default when both all" do
133
+ @tester.acl_block! do
134
+ default :deny
135
+ deny all
136
+ allow all
137
+ end
138
+
139
+ assert_all_forbidden
140
+ end
141
+ end
142
+ end