LoginEngine is aging and was built on top of a quick-and-dirty generator;
even James isn't too happy with it anymore.  acts_as_authenticated is
somewhat cleaner, but is a generator, and as with all generators, there's
no way to keep up with changes to the codebase.  Neither is particularly
modular.  And both of them provide some authorization as well as
authentication, and even a little user management, which further muddies
the waters.

So I'm proposing a new engine: Hark.  It's a pared-down, opinionated engine
that answers only one question: "Who goes there?"

Hark has its roots in both LoginEngine and acts_as_authenticated.  I've
borrowed liberally from each where their code was cleanest, and tried to
incorporate both sets of best practices.

The following features are *not* found in Hark, by design:

* Authorization, such the login_required filter and its magic redirection.
This is best performed by an authorization system such as 
such as Bill Katz's excellent authorization plugin[1].

* Support for extra fields.  LoginEngine expected you to extend its User
model to add your own fields.  Hark prefers that you create your own User
model, and declare that it belongs_to :hark_user.  You can thus create any
fields you want in your own model.

* Support for delayed_delete.  This is already handled by the excellent
acts_as_paranoid plugin[2].

* Configuration options for validation.  There are an infinite number of
ways you might want to validate passwords, logins, etc.; Hark doesn't try
to anticipate them.  There's a great DSL for that already called "Rails".
Instead, just create your own copy of the hark_user.rb model, and use any
validations you like.  The user code is all kept in a library, not in
hark_user.rb, so when you update to a newer version, you won't lose your
customizations.

The following features ARE present:
* Passwords are hashed with a per-user salt value
* "Remember me" cookies
* E-mail verification upon registration (by release)

The following principles guide Hark's development:

* Extension over configuration.  Rather than trying to build in
configuration options for every possible use case, make hark easy to extend
without losing the benefits of shared code.  That means:

* Be modular.  All code, both controller and model, is in a properly
abstracted, verb-based library that takes care of things like cookie
creation, session management, attribute setting, etc.  For instance, the
controller code for login looks like:

  def login

    hs = Hark::Session.get(session, cookies)
    
    unless hs.login(params[:hark])
      flash.now[:warning] = 'Login unsuccessful'
      return
    end   
  end

And this controller code itself is just the default login screen, which
will most likely be overwritten by your own controller.

* Play nice with others.  Hark should be able to take advantage of plugins
like acts_as_paranoid, secure-action-plugin, etc. instead of trying to roll
its own.

* Be paranoid.  An awful lot of Rails code doesn't check its state or
inputs, because the end result is usually nothing worse than an
"Application error".  In login code, we have to be a little more careful.
To the extent that Rails allows, we should watch out for race conditions,
session fixation attacks, etc.

* Be behavior-driven.  All code in Hark is developed using rspec.  I've
attached the current specdoc below.  

* Be correct.  That seems self-evident, but again, because Rails is so easy
to work with, there's a lot of "programming by coincidence".  To the extent
that Rails allows, we should take advantage of locking, transactions, and
update granularity so that things like multiple simultaneous logins are not
an issue on larger systems.

* Be useful.  I see too many posts saying that "AAA/LoginEngine/etc are
great starting points, but I always end up having to rewrite them."  Yes, a
lot of authentication is system-specific - is your back end LDAP, or a
Rails table? - but the basic transaction sequences are usually the same.
Hark should be able to cope with that, while still providing a framework
for extension.  You shouldn't NEED to roll your own; there are too many
common mistakes that we already know how to avoid.

* Stay focused.  Hark should not attempt authorization or user management.
It's purely about authentication and its dependencies, such as registration
and verification.

So... that's the goal.  Right now, it's in its infancy; I've just completed
basic login and remember-me functionality, and I'm starting to work on
registration.  The codebase is at http://svn.jay.fm/public/hark.  It's not
even an engine at the moment, pending some resolution on the engines bug
with Dependencies in Edge Rails.  I'd love to have someone to work with on
this, especially someone with a systems background who can bring additional
large-scale discipline to the project.  

Interest?  Questions?  

Jay

----
[1]: http://www.writertopia.com/developers/authorization.
[2]: http://svn.techno-weenie.net/projects/plugins/acts_as_paranoid/
----
specdoc:

The HarkController
- should allow Vlad the valid user to log in
- should have no current_user if Vlad provides the wrong password

The HarkController, given Louie the logged-in user
- should set current_user to be Louie
- should redirect Louie to the index page by default
- should redirect Louie back to his previous page if he has one
- should set Louie's token if he asks to be remembered
- should prevent Louie from logging in twice

The HarkController, given Remmie the remembered user
- should log Remmie in automatically

A HarkSession, when Louie logs in
- should update Louie's current last_login_at
- should have Louie as current_user
- should not have set any of Louie's cookies
- should not have remembered Louie
- should prevent Louie from logging in again

A HarkSession, asked to remember Louie at login
- should set Louie's hark_token cookie
- should remember Louie

A HarkUser in general
- should not be able to be created via 'new'

Reggie the registering user
- should have an account created
- should have his e-mail marked as unverified

Reggie, when attempting to register
- should not be able to register without a password (FAILED - 1)

Vlad the valid user
- should be able to authenticate with his password
- should not be able to authenticate with the wrong password
- should be able to login with his password
- should not be able to login with the wrong password
- should be able to login with spaces around his username
- should be able to login with spaces around his password

Louie the logged-in user
- should get a remember_me token back when he asks
- should be able to log in with his token
- should not be able to log in with an expired token

_______________________________________________
engine-users mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-users-rails-engines.org

Reply via email to