I found that scoped_access does not re-evaluate the filters on every
run. If you are filtering access based on parameters, this can be bad.
The scope is set on the first request and then further requests use the
last generated scoping.
The initial part of ScopedAccess::Filter#before looks like this:
@scoping = controller.instance_eval(@scoping.to_s) if
@scoping.is_a?(Symbol)
This makes @scoping not a symbol on the first run and @scoping will
never be evaluated again. This would fail in code which looks like this:
For example:
def silo_filter(klass)
filter = ScopedAccess::ClassScoping.new klass, :silo_id => @silo.id
end
where, @silo is set in a before_filter.
I’ve also added in some code to check if the passed in scoping is a
method. If it is, the method is called with the class as a parameter.
This allows for more DRY code.
I’m new here and do not know if this is the right place to post patches.
Please let me know if it is not.
The patch follows:
— old-vendor/plugins/scoped_access/lib/scoped_access.rb
2006-06-27 19:00:26.755869000 -0700
+++ vendor/plugins/scoped_access/lib/scoped_access.rb 2006-06-27
18:33:57.297418000 -0700
@@ -114,12 +114,20 @@
end
def before (controller)
-
@scoping = controller.instance_eval(@scoping.to_s) if
@scoping.is_a?(Symbol)
-
constrain = self.class.generate_constrain(@klass, @scoping,
:table_name =>@klass.table_name)
-
if @scoping.is_a? Symbol
-
meth = controller.method @scoping
-
if meth.arity.zero?
-
scope = controller.instance_eval(@scoping.to_s)
-
else
-
scope = controller.instance_eval("#{@scoping}(#{@klass})")
-
end
-
end
-
constrain = self.class.generate_constrain(@klass, scope,
:table_name =>@klass.table_name)
@klass.logger.debug(“ScopedAccessFilter#before (called from
%s):\n\t[%s] scope becomes %s” %
[controller.class, @klass,
constrain.inspect])
@klass.instance_eval do
Cheers,
Nikhil.