On Jul 17, 2006, at 5:49 AM, Josh K. wrote:
thanks for the reply Ezra. for this particular controller, i need
all of
the pages to perform access control. all i have in it now is the code
that is generated when you create a scaffold, plus this:
before_filter :authorize
access_control :DEFAULT => ‘customer | csr’,
:authorize => ‘!guest’
This looks like a problem. the :authorize => ‘!guest’ is not needed.
I think your authorize method might be a slight misnomer as well. I
think you mean authenticate there instead. Authentication is the
process of making sure someone is who they say they are, ie user logs
in with password and is authenticated. Then the access_control
performs authorization, which is what user roles are allowed to
access certain actions. So maybe change your authorize method to be
authenticate instead.
But all that aside, I don’t think you want to put access_control on
your authorize method. Since it is already a private method it cannot
be called from the web so it doesn’t need to be protected with
access_control.
but this was being executed before my authorize method so when the
but even by doing that, my authorize method is not getting called and
the user is not ever being sent to the login screen. if i go
straight to
the login screen and login, everything else works great.
also, on a side note, i wanted to add the current user method to the
base controller file but it’s not pulling up that way. is it
required to
have current_user in every single controller?
Ok I think I see what your issue is. You need to realize that to have
a before_filter halt the chain of before filters it needs to return
false. So we need to rewrite your before_filter method that checks if
a user is logged in. Also I think you need a slight change to your
current_user method to make it work a tad better. Lets try something
like this in the bottom of your application controller class:
protected
I would change this to authenticate instead of authorize to avoid
confusion.
def authorize
unless @current_user = User.find_by_id(session[:user_id])
session[:original_uri] = request.request_uri
flash[:notice] = ‘Please log in’
redirect_to :controller => ‘login’
return false # !! this is what was missing!
end
end
def current_user
@current_user ||= session[:user] ? User.find_by_id(session
[:user]) : nil
end
Try setting these methods like I have shown and then use a before
filter to protect all actions that require a login. This will make
sure that if an action needs a logged in user that it will try to
authenticate, if it fails then it will redirect to the login action
and access_control will never be called. If the user is successful at
login in the current_user will be set and then access_control gets
called next to see if the user has permission to access the action in
question.
so in the controllers that require login:
before_filter :authorize # or authenticate if you change the name.
access_control :DEFAULT => ‘!guest’,
:test_csr => ‘csr’
One thing to realize that might help make this all a bit more clear
for you is to realize that access_control sets up a before_filter
itself, thats how it works. So it must happen after the before
filter has run that logs the user in and sets current_user. If the
user login fails then the access_control is never run because the
user is redirected to the login screen.
Cheers-
-Ezra