You have a nil object when you didn't expect it
I’m interested in the topic of Rails security and using Security on Rails. I'm on Implementing RBAC /page 142/ and i cannot get past the error in the subject. Here is the code:
module RoleBasedControllerAuthorization
def self.included(base)
base.extend(AuthorizationClassMethods)
end
def authorization_filter
user = User.find(:first,
:conditions => ["id = ?", session[:user_id]])
action_name = request.parameters[:action].to_sym
action_roles = self.class.access_list[action_name]
if action_roles.nil?
logger.error "You must provide a roles declaration\
or add skip_before_filter :authorization_filter to\
the beginning of #{self}."
redirect_to :controller => 'root', :action => 'index'
return false
elsif action_roles.include? user.role.name.to_sym
return true
else
logger.info "#{user.user_name} (role: #{user.role.name}) attempted to access\
#{self.class}##{action_name} without the proper permissions."
flash[:notice] = "Not authorized!"
redirect_to :controller => '开发者_如何学Croot', :action => 'index'
return false
end
end
end
module AuthorizationClassMethods
def self.extended(base)
class << base
@access_list = {}
attr_reader :access_list
end
end
def roles(*roles)
@roles = roles
end
def method_added(method)
logger.debug "#{caller[0].inspect}"
logger.debug "#{method.inspect}"
@access_list[method] = @roles
end
end
And @access_list[method] = @roles line throwing following exception:
ActionController::RoutingError (You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]=):
app/security/role_based_controller_authorization.rb:66:in `method_added'
app/controllers/application_controller.rb:5:in `<class:ApplicationController>'
app/controllers/application_controller.rb:1:in `<top (required)>'
app/controllers/home_controller.rb:1:in `<top (required)>'
I'm using Rails 3.0.3 and Ruby 1.9.2. I'm storing session in database. In finally thank you for every advise.
It seems like you can't access @access_list
in method_added
. I would try
class << base
attr_accessor :access_list
@access_list = {}
end
Might not solve your particular problem, but otherwise you won't be able to call @access_list[method] = @roles
if your access_list attribute is read-only.
I'm not sure if this is the problem, but this looks suspicious:
class << base
@access_list = {}
attr_reader :access_list
end
Shouldn't @access_list
be a class variable @@access_list
?
Your defining @access_list
as a instance variable of the class but your accessing it in as a instance_variable of an instance of the class. The following should probably work:
module AuthorizationClassMethods
def access_list
@access_list ||={}
end
def method_added(method)
logger.debug "#{caller[0].inspect}"
logger.debug "#{method.inspect}"
access_list[method] = @roles
end
end
If you need Auhorization you might want to check out Cancan by Ryan Bates
https://github.com/ryanb/cancan
精彩评论