Hacking on restful_authentication

I am relatively new to Rails, and I recently installed the
restful_authentication plugin to manage authentication and users for a
site I’m developing. I wanted to change the behaviour of the plugin
so that it returned meaningful error messages to users when a login
failed (ie to tell the user whether the login failed because the user
didn’t exist or because the password didn’t match), but this proved
surprisingly difficult. The problem is that user authentication is
done in a class method, which returns nil to indicate that the login
failed.

def self.authenticate
u = find_by_login(login) # need to get the salt
u && u.authenticated?(password) ? u : nil
end

I tried quite a few things, but they were all hampered by the fact
that (a) the nil value represented both kinds of errors and (b)
returning nil didn’t allow me to use things like virtual attributes to
store and indication of the actual problem. It was made more
difficult by the fact that this authentication happened in the model,
and therefore I was limited in the way that I could communicate back
to the controller (eg the model doesn’t have access to the flash or
the session).

Eventually I decided to use custom exceptions for the two different
types of errors and have the controller separately rescue these to set
the flash message to indicate what actually went wrong, as these
seemed like the way to achieve my aim with minimal disturbance to the
existing system (there seem to be quite a few places that relied on
the existing design).

def self.authenticate(login, password)
u = find_by_login(login) # need to get the salt
raise AuthenticatedSystem::UserNotFoundException if u.nil?
raise AuthenticatedSystem::InvalidPasswordException unless
u.authenticated?(password)
return u
end

I guess what I’m wondering is what would be the best (ie most Rails-
like) way to implement this if you were starting from scratch with
this aim in mind ? Would it be better to move more of the logic into
the controller by changing the authenticate method to an instance
method without the find, doing the find in the controller and then
call authenticate on the returned user model to validate the
password ? Or is there some other more elegant solution that I’m
missing ?