acl9 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ module Acl9
2
+ module Helpers
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def access_control(method, opts = {}, &block)
9
+ subject_method = opts.delete(:subject_method) || Acl9::config[:default_subject_method]
10
+ raise ArgumentError, "Block must be supplied to access_control" unless block
11
+
12
+ generator = Acl9::Dsl::Generators::HelperMethod.new(subject_method, method)
13
+
14
+ generator.acl_block!(&block)
15
+ generator.install_on(self, opts)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,133 @@
1
+ require File.join(File.dirname(__FILE__), 'model_extensions', 'subject')
2
+ require File.join(File.dirname(__FILE__), 'model_extensions', 'object')
3
+
4
+ module Acl9
5
+ module ModelExtensions #:nodoc:
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ # Add #has_role? and other role methods to the class.
12
+ # Makes a class a auth. subject class.
13
+ #
14
+ # @param [Hash] options the options for tuning
15
+ # @option options [String] :role_class_name (Acl9::config[:default_role_class_name])
16
+ # Class name of the role class (e.g. 'AccountRole')
17
+ # @option options [String] :join_table_name (Acl9::config[:default_join_table_name])
18
+ # Join table name (e.g. 'accounts_account_roles')
19
+ # @example
20
+ # class User < ActiveRecord::Base
21
+ # acts_as_authorization_subject
22
+ # end
23
+ #
24
+ # user = User.new
25
+ # user.roles #=> returns Role objects, associated with the user
26
+ # user.has_role!(...)
27
+ # user.has_no_role!(...)
28
+ #
29
+ # # other functions from Acl9::ModelExtensions::Subject are made available
30
+ #
31
+ # @see Acl9::ModelExtensions::Subject
32
+ #
33
+ def acts_as_authorization_subject(options = {})
34
+ role = options[:role_class_name] || Acl9::config[:default_role_class_name]
35
+ join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
36
+ join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(role))
37
+
38
+ has_and_belongs_to_many :role_objects, :class_name => role, :join_table => join_table
39
+
40
+ cattr_accessor :_auth_role_class_name, :_auth_subject_class_name
41
+ self._auth_role_class_name = role
42
+ self._auth_subject_class_name = self.to_s
43
+
44
+ include Acl9::ModelExtensions::Subject
45
+ end
46
+
47
+ # Add role query and set methods to the class (making it an auth object class).
48
+ #
49
+ # @param [Hash] options the options for tuning
50
+ # @option options [String] :subject_class_name (Acl9::config[:default_subject_class_name])
51
+ # Subject class name (e.g. 'User', or 'Account)
52
+ # @option options [String] :role_class_name (Acl9::config[:default_role_class_name])
53
+ # Role class name (e.g. 'AccountRole')
54
+ # @example
55
+ # class Product < ActiveRecord::Base
56
+ # acts_as_authorization_object
57
+ # end
58
+ #
59
+ # product = Product.new
60
+ # product.accepted_roles #=> returns Role objects, associated with the product
61
+ # product.users #=> returns User objects, associated with the product
62
+ # product.accepts_role!(...)
63
+ # product.accepts_no_role!(...)
64
+ # # other functions from Acl9::ModelExtensions::Object are made available
65
+ #
66
+ # @see Acl9::ModelExtensions::Object
67
+ #
68
+ def acts_as_authorization_object(options = {})
69
+ subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
70
+ subj_table = subject.constantize.table_name
71
+ subj_col = subject.underscore
72
+
73
+ role = options[:role_class_name] || Acl9::config[:default_role_class_name]
74
+ role_table = role.constantize.table_name
75
+
76
+ sql_tables = <<-EOS
77
+ FROM #{subj_table}
78
+ INNER JOIN #{role_table}_#{subj_table} ON #{subj_col}_id = #{subj_table}.id
79
+ INNER JOIN #{role_table} ON #{role_table}.id = #{role.underscore}_id
80
+ EOS
81
+
82
+ sql_where = <<-'EOS'
83
+ WHERE authorizable_type = '#{self.class.base_class.to_s}'
84
+ AND authorizable_id = #{id}
85
+ EOS
86
+
87
+ has_many :accepted_roles, :as => :authorizable, :class_name => role, :dependent => :destroy
88
+
89
+ has_many :"#{subj_table}",
90
+ :finder_sql => ("SELECT DISTINCT #{subj_table}.*" + sql_tables + sql_where),
91
+ :counter_sql => ("SELECT COUNT(DISTINCT #{subj_table}.id)" + sql_tables + sql_where),
92
+ :readonly => true
93
+
94
+ include Acl9::ModelExtensions::Object
95
+ end
96
+
97
+ # Make a class an auth role class.
98
+ #
99
+ # You'll probably never create or use objects of this class directly.
100
+ # Various auth. subject and object methods will do that for you
101
+ # internally.
102
+ #
103
+ # @param [Hash] options the options for tuning
104
+ # @option options [String] :subject_class_name (Acl9::config[:default_subject_class_name])
105
+ # Subject class name (e.g. 'User', or 'Account)
106
+ # @option options [String] :join_table_name (Acl9::config[:default_join_table_name])
107
+ # Join table name (e.g. 'accounts_account_roles')
108
+ #
109
+ # @example
110
+ # class Role < ActiveRecord::Base
111
+ # acts_as_authorization_role
112
+ # end
113
+ #
114
+ # @see Acl9::ModelExtensions::Subject#has_role!
115
+ # @see Acl9::ModelExtensions::Subject#has_role?
116
+ # @see Acl9::ModelExtensions::Subject#has_no_role!
117
+ # @see Acl9::ModelExtensions::Object#accepts_role!
118
+ # @see Acl9::ModelExtensions::Object#accepts_role?
119
+ # @see Acl9::ModelExtensions::Object#accepts_no_role!
120
+ def acts_as_authorization_role(options = {})
121
+ subject = options[:subject_class_name] || Acl9::config[:default_subject_class_name]
122
+ join_table = options[:join_table_name] || Acl9::config[:default_join_table_name] ||
123
+ join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(subject))
124
+
125
+ has_and_belongs_to_many subject.demodulize.tableize.to_sym,
126
+ :class_name => subject,
127
+ :join_table => join_table
128
+
129
+ belongs_to :authorizable, :polymorphic => true
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,59 @@
1
+ module Acl9
2
+ module ModelExtensions
3
+ module Object
4
+ ##
5
+ # Role check.
6
+ #
7
+ # @return [Boolean] Returns true if +subject+ has a role +role_name+ on this object.
8
+ #
9
+ # @param [Symbol,String] role_name Role name
10
+ # @param [Subject] subject Subject to add role for
11
+ # @see Acl9::ModelExtensions::Subject#has_role?
12
+ def accepts_role?(role_name, subject)
13
+ subject.has_role? role_name, self
14
+ end
15
+
16
+ ##
17
+ # Add role on the object to specified subject.
18
+ #
19
+ # @param [Symbol,String] role_name Role name
20
+ # @param [Subject] subject Subject to add role for
21
+ # @see Acl9::ModelExtensions::Subject#has_role!
22
+ def accepts_role!(role_name, subject)
23
+ subject.has_role! role_name, self
24
+ end
25
+
26
+ ##
27
+ # Free specified subject of a role on this object.
28
+ #
29
+ # @param [Symbol,String] role_name Role name
30
+ # @param [Subject] subject Subject to remove role from
31
+ # @see Acl9::ModelExtensions::Subject#has_no_role!
32
+ def accepts_no_role!(role_name, subject)
33
+ subject.has_no_role! role_name, self
34
+ end
35
+
36
+ ##
37
+ # Are there any roles for the specified +subject+ on this object?
38
+ #
39
+ # @param [Subject] subject Subject to query roles
40
+ # @return [Boolean] Returns true if +subject+ has any roles on this object.
41
+ # @see Acl9::ModelExtensions::Subject#has_roles_for?
42
+ def accepts_roles_by?(subject)
43
+ subject.has_roles_for? self
44
+ end
45
+
46
+ alias :accepts_role_by? :accepts_roles_by?
47
+
48
+ ##
49
+ # Which roles does +subject+ have on this object?
50
+ #
51
+ # @return [Array<Role>] Role instances, associated both with +subject+ and +object+
52
+ # @param [Subject] subject Subject to query roles
53
+ # @see Acl9::ModelExtensions::Subject#roles_for
54
+ def accepted_roles_by(subject)
55
+ subject.roles_for self
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,175 @@
1
+ module Acl9
2
+ module ModelExtensions
3
+ module Subject
4
+ ##
5
+ # Role check.
6
+ #
7
+ # There is a global option, +Acl9.config[:protect_global_roles]+, which governs
8
+ # this method behavior.
9
+ #
10
+ # If protect_global_roles is +false+, an object role is automatically counted
11
+ # as global role. E.g.
12
+ #
13
+ # Acl9.config[:protect_global_roles] = false
14
+ # user.has_role!(:manager, @foo)
15
+ # user.has_role?(:manager, @foo) # => true
16
+ # user.has_role?(:manager) # => true
17
+ #
18
+ # In this case manager is anyone who "manages" at least one object.
19
+ #
20
+ # However, if protect_global_roles option set to +true+, you'll need to
21
+ # explicitly grant global role with same name.
22
+ #
23
+ # Acl9.config[:protect_global_roles] = true
24
+ # user.has_role!(:manager, @foo)
25
+ # user.has_role?(:manager) # => false
26
+ # user.has_role!(:manager)
27
+ # user.has_role?(:manager) # => true
28
+ #
29
+ # protect_global_roles option is +false+ by default as for now, but this
30
+ # may change in future!
31
+ #
32
+ # @return [Boolean] Whether +self+ has a role +role_name+ on +object+.
33
+ # @param [Symbol,String] role_name Role name
34
+ # @param [Object] object Object to query a role on
35
+ #
36
+ # @see Acl9::ModelExtensions::Object#accepts_role?
37
+ def has_role?(role_name, object = nil)
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))
41
+ else
42
+ role = get_role(role_name, object)
43
+ role && self.role_objects.exists?(role.id)
44
+ end
45
+ end
46
+
47
+ ##
48
+ # Add specified role on +object+ to +self+.
49
+ #
50
+ # @param [Symbol,String] role_name Role name
51
+ # @param [Object] object Object to add a role for
52
+ # @see Acl9::ModelExtensions::Object#accepts_role!
53
+ def has_role!(role_name, object = nil)
54
+ role = get_role(role_name, object)
55
+
56
+ if role.nil?
57
+ role_attrs = case object
58
+ when Class then { :authorizable_type => object.to_s }
59
+ when nil then {}
60
+ else { :authorizable => object }
61
+ end.merge( { :name => role_name.to_s })
62
+
63
+ role = self._auth_role_class.create(role_attrs)
64
+ end
65
+
66
+ self.role_objects << role if role && !self.role_objects.exists?(role.id)
67
+ end
68
+
69
+ ##
70
+ # Free +self+ from a specified role on +object+.
71
+ #
72
+ # @param [Symbol,String] role_name Role name
73
+ # @param [Object] object Object to remove a role on
74
+ # @see Acl9::ModelExtensions::Object#accepts_no_role!
75
+ def has_no_role!(role_name, object = nil)
76
+ delete_role(get_role(role_name, object))
77
+ end
78
+
79
+ ##
80
+ # Are there any roles for +self+ on +object+?
81
+ #
82
+ # @param [Object] object Object to query roles
83
+ # @return [Boolean] Returns true if +self+ has any roles on +object+.
84
+ # @see Acl9::ModelExtensions::Object#accepts_roles_by?
85
+ def has_roles_for?(object)
86
+ !!self.role_objects.detect(&role_selecting_lambda(object))
87
+ end
88
+
89
+ alias :has_role_for? :has_roles_for?
90
+
91
+ ##
92
+ # Which roles does +self+ have on +object+?
93
+ #
94
+ # @return [Array<Role>] Role instances, associated both with +self+ and +object+
95
+ # @param [Object] object Object to query roles
96
+ # @see Acl9::ModelExtensions::Object#accepted_roles_by
97
+ # @example
98
+ # user = User.find(...)
99
+ # product = Product.find(...)
100
+ #
101
+ # user.roles_for(product).map(&:name).sort #=> role names in alphabetical order
102
+ def roles_for(object)
103
+ self.role_objects.select(&role_selecting_lambda(object))
104
+ end
105
+
106
+ ##
107
+ # Unassign any roles on +object+ from +self+.
108
+ #
109
+ # @param [Object,nil] object Object to unassign roles for. +nil+ means unassign global roles.
110
+ def has_no_roles_for!(object = nil)
111
+ roles_for(object).each { |role| delete_role(role) }
112
+ end
113
+
114
+ ##
115
+ # Unassign all roles from +self+.
116
+ def has_no_roles!
117
+ # for some reason simple
118
+ #
119
+ # self.roles.each { |role| delete_role(role) }
120
+ #
121
+ # doesn't work. seems like a bug in ActiveRecord
122
+ self.role_objects.map(&:id).each do |role_id|
123
+ delete_role self._auth_role_class.find(role_id)
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ def role_selecting_lambda(object)
130
+ case object
131
+ when Class
132
+ lambda { |role| role.authorizable_type == object.to_s }
133
+ when nil
134
+ lambda { |role| role.authorizable.nil? }
135
+ else
136
+ lambda do |role|
137
+ role.authorizable_type == object.class.base_class.to_s && role.authorizable == object
138
+ end
139
+ end
140
+ end
141
+
142
+ def get_role(role_name, object)
143
+ role_name = role_name.to_s
144
+
145
+ cond = case object
146
+ when Class
147
+ [ 'name = ? and authorizable_type = ? and authorizable_id IS NULL', role_name, object.to_s ]
148
+ when nil
149
+ [ 'name = ? and authorizable_type IS NULL and authorizable_id IS NULL', role_name ]
150
+ else
151
+ [
152
+ 'name = ? and authorizable_type = ? and authorizable_id = ?',
153
+ role_name, object.class.base_class.to_s, object.id
154
+ ]
155
+ end
156
+
157
+ self._auth_role_class.first :conditions => cond
158
+ end
159
+
160
+ def delete_role(role)
161
+ if role
162
+ self.role_objects.delete role
163
+
164
+ role.destroy if role.send(self._auth_subject_class_name.demodulize.tableize).empty?
165
+ end
166
+ end
167
+
168
+ protected
169
+
170
+ def _auth_role_class
171
+ self.class._auth_role_class_name.constantize
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,338 @@
1
+ require 'test_helper'
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'acl9')
3
+ require 'support/controllers'
4
+
5
+ #######################################################################
6
+
7
+ class Admin
8
+ def has_role?(role, obj = nil)
9
+ role == "admin"
10
+ end
11
+ end
12
+
13
+ class OwnerOfFoo
14
+ def has_role?(role, obj)
15
+ role == 'owner' && obj == MyDearFoo.instance
16
+ end
17
+ end
18
+
19
+ class Bartender
20
+ def has_role?(role, obj)
21
+ role == 'bartender' && obj == ACLIvars::VenerableBar
22
+ end
23
+ end
24
+
25
+ class TheOnlyUser
26
+ include Singleton
27
+
28
+ def has_role?(role, subj)
29
+ role == "the_only_one"
30
+ end
31
+ end
32
+
33
+ class Beholder
34
+ def initialize(role)
35
+ @role = role.to_s
36
+ end
37
+
38
+ def has_role?(role, obj)
39
+ role.to_s == @role
40
+ end
41
+ end
42
+
43
+ #######################################################################
44
+
45
+ module BaseTests
46
+ # permit anonymous to index and show and admin everywhere else
47
+ def self.included(klass)
48
+ klass.class_eval do
49
+ [:index, :show].each do |act|
50
+ it "should permit anonymous to #{act}" do
51
+ get act
52
+ @response.body.should == 'OK'
53
+ end
54
+ end
55
+
56
+ [:new, :edit, :update, :delete, :destroy].each do |act|
57
+ it "should forbid anonymous to #{act}" do
58
+ get act
59
+ @response.body.should == 'AccessDenied'
60
+ end
61
+ end
62
+
63
+ [:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
64
+ it "should permit admin to #{act}" do
65
+ get act, :user => Admin.new
66
+ @response.body.should == 'OK'
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ module ShouldRespondToAcl
74
+ def self.included(klass)
75
+ klass.class_eval do
76
+ it "should add :acl as a method" do
77
+ @controller.should respond_to(:acl)
78
+ end
79
+
80
+ it "should_not add :acl? as a method" do
81
+ @controller.should_not respond_to(:acl?)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ #######################################################################
88
+
89
+ class ACLBlockTest < ActionController::TestCase
90
+ tests ACLBlock
91
+
92
+ include BaseTests
93
+ end
94
+
95
+ class ACLMethodTest < ActionController::TestCase
96
+ tests ACLMethod
97
+
98
+ include BaseTests
99
+ include ShouldRespondToAcl
100
+ end
101
+
102
+ class ACLMethod2Test < ActionController::TestCase
103
+ tests ACLMethod2
104
+
105
+ include BaseTests
106
+ include ShouldRespondToAcl
107
+ end
108
+
109
+ class ACLArgumentsTest < ActionController::TestCase
110
+ tests ACLArguments
111
+
112
+ include BaseTests
113
+ end
114
+
115
+ class ACLBooleanMethodTest < ActionController::TestCase
116
+ tests ACLBooleanMethod
117
+
118
+ include BaseTests
119
+ end
120
+
121
+ class ACLIvarsTest < ActionController::TestCase
122
+ tests ACLIvars
123
+
124
+ it "should allow owner of foo to destroy" do
125
+ delete :destroy, :user => OwnerOfFoo.new
126
+ @response.body.should == 'OK'
127
+ end
128
+
129
+ it "should allow bartender to destroy" do
130
+ delete :destroy, :user => Bartender.new
131
+ @response.body.should == 'OK'
132
+ end
133
+ end
134
+
135
+ class ACLSubjectMethodTest < ActionController::TestCase
136
+ tests ACLSubjectMethod
137
+
138
+ it "should allow the only user to index" do
139
+ get :index, :user => TheOnlyUser.instance
140
+ @response.body.should == 'OK'
141
+ end
142
+
143
+ it "should deny anonymous to index" do
144
+ get :index
145
+ @response.body.should == 'AccessDenied'
146
+ end
147
+ end
148
+
149
+ class ACLObjectsHashTest < ActionController::TestCase
150
+ tests ACLObjectsHash
151
+
152
+ it "should consider objects hash and prefer it to @ivar" do
153
+ get :allow, :user => OwnerOfFoo.new
154
+ @response.body.should == 'OK'
155
+ end
156
+
157
+ it "should return AccessDenied when not logged in" do
158
+ get :allow
159
+ @response.body.should == 'AccessDenied'
160
+ end
161
+ end
162
+
163
+ class ACLActionOverrideTest < ActionController::TestCase
164
+ tests ACLActionOverride
165
+
166
+ it "should allow index action to anonymous" do
167
+ get :check_allow, :_action => :index
168
+ @response.body.should == 'OK'
169
+ end
170
+
171
+ it "should deny show action to anonymous" do
172
+ get :check_allow, :_action => :show
173
+ @response.body.should == 'AccessDenied'
174
+ end
175
+
176
+ it "should deny edit action to regular user" do
177
+ get :check_allow_with_foo, :_action => :edit, :user => TheOnlyUser.instance
178
+
179
+ @response.body.should == 'AccessDenied'
180
+ end
181
+
182
+ it "should allow edit action to owner of foo" do
183
+ get :check_allow_with_foo, :_action => :edit, :user => OwnerOfFoo.new
184
+
185
+ @response.body.should == 'OK'
186
+ end
187
+ end
188
+
189
+ class ACLHelperMethodTest < ActionController::TestCase
190
+ tests ACLHelperMethod
191
+
192
+ it "should return OK checking helper method" do
193
+ get :allow, :user => OwnerOfFoo.new
194
+ @response.body.should == 'OK'
195
+ end
196
+
197
+ it "should return AccessDenied when not logged in" do
198
+ get :allow
199
+ @response.body.should == 'AccessDenied'
200
+ end
201
+ end
202
+
203
+ #######################################################################
204
+
205
+ module ACLQueryMixin
206
+ def self.included(base)
207
+ base.class_eval do
208
+ describe "#acl_question_mark" do # describe "#acl?" doesn't work
209
+ before do
210
+ @editor = Beholder.new(:editor)
211
+ @viewer = Beholder.new(:viewer)
212
+ @owneroffoo = OwnerOfFoo.new
213
+ end
214
+
215
+ [:edit, :update, :destroy].each do |meth|
216
+ it "should return true for editor/#{meth}" do
217
+ @controller.current_user = @editor
218
+ @controller.acl?(meth).should == true
219
+ @controller.acl?(meth.to_s).should == true
220
+ end
221
+
222
+ it "should return false for viewer/#{meth}" do
223
+ @controller.current_user = @viewer
224
+ @controller.acl?(meth).should == false
225
+ @controller.acl?(meth.to_s).should == false
226
+ end
227
+ end
228
+
229
+ [:index, :show].each do |meth|
230
+ it "should return false for editor/#{meth}" do
231
+ @controller.current_user = @editor
232
+ @controller.acl?(meth).should == false
233
+ @controller.acl?(meth.to_s).should == false
234
+ end
235
+
236
+ it "should return true for viewer/#{meth}" do
237
+ @controller.current_user = @viewer
238
+ @controller.acl?(meth).should == true
239
+ @controller.acl?(meth.to_s).should == true
240
+ end
241
+ end
242
+
243
+ it "should return false for editor/fooize" do
244
+ @controller.current_user = @editor
245
+ @controller.acl?(:fooize).should == false
246
+ end
247
+
248
+ it "should return true for foo owner" do
249
+ @controller.current_user = @owneroffoo
250
+ @controller.acl?(:fooize, :foo => MyDearFoo.instance).should == true
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end
256
+
257
+ class ACLQueryMethodTest < ActionController::TestCase
258
+ tests ACLQueryMethod
259
+
260
+ it "should respond to :acl?" do
261
+ @controller.should respond_to(:acl?)
262
+ end
263
+
264
+ include ACLQueryMixin
265
+ end
266
+
267
+ class ACLQueryMethodWithLambdaTest < ActionController::TestCase
268
+ tests ACLQueryMethodWithLambda
269
+
270
+ it "should respond to :acl?" do
271
+ @controller.should respond_to(:acl?)
272
+ end
273
+
274
+ include ACLQueryMixin
275
+ end
276
+
277
+ #######################################################################
278
+
279
+ class ACLNamedQueryMethodTest < ActionController::TestCase
280
+ tests ACLNamedQueryMethod
281
+
282
+ it "should respond to :allow_ay" do
283
+ @controller.should respond_to(:allow_ay)
284
+ end
285
+
286
+ include ACLQueryMixin
287
+ end
288
+
289
+ #######################################################################
290
+
291
+ class ArgumentsCheckingTest < ActiveSupport::TestCase
292
+ def arg_err(&block)
293
+ lambda do
294
+ block.call
295
+ end.should raise_error(ArgumentError)
296
+ end
297
+
298
+ it "should raise ArgumentError without a block" do
299
+ arg_err do
300
+ class FailureController < ApplicationController
301
+ access_control
302
+ end
303
+ end
304
+ end
305
+
306
+ it "should raise ArgumentError with 1st argument which is not a symbol" do
307
+ arg_err do
308
+ class FailureController < ApplicationController
309
+ access_control 123 do end
310
+ end
311
+ end
312
+ end
313
+
314
+ it "should raise ArgumentError with more than 1 positional argument" do
315
+ arg_err do
316
+ class FailureController < ApplicationController
317
+ access_control :foo, :bar do end
318
+ end
319
+ end
320
+ end
321
+
322
+ it "should raise ArgumentError with :helper => true and no method name" do
323
+ arg_err do
324
+ class FailureController < ApplicationController
325
+ access_control :helper => true do end
326
+ end
327
+ end
328
+ end
329
+
330
+ it "should raise ArgumentError with :helper => :method and a method name" do
331
+ arg_err do
332
+ class FailureController < ApplicationController
333
+ access_control :meth, :helper => :another_meth do end
334
+ end
335
+ end
336
+ end
337
+ end
338
+