public
Description: Simple authentication/acl system for rails
Homepage:
Clone URL: git://github.com/andreashappe/blubber.git
name age message
file MIT-LICENSE Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
file README Sat Oct 25 08:07:58 -0700 2008 [chg] documentation [Andreas Happe]
file Rakefile Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
file init.rb Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
file install.rb Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
directory lib/ Wed Oct 22 13:59:12 -0700 2008 [add] rake task for session_controller_generati... [Andreas Happe]
directory tasks/ Wed Oct 22 13:59:12 -0700 2008 [add] rake task for session_controller_generati... [Andreas Happe]
directory test/ Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
file uninstall.rb Wed Oct 22 04:37:19 -0700 2008 [add] initial import&commit Imported the plugi... [Andreas Happe]
README
Blubber
=======

This is the blubber authentication/acl plugin as used by BlackWhale Gmbh[0].
It provides a simple ACL system on top of an existing user management system.
It was written to act as unintrusive as possible.

The plugin works very well for me, if you have any questions or additions
(patches preferred :) )feel free to contact me.

It is roughly based upon Technoweenie's restful_authentication Plugin[1].

Differences to restful_authentication:
 * ACL support
 * does not mix password/user management with security/ACL
 * writte as a plugin, not as a generator so users just have to
   update the plugin and do not have to regenerate their controllers
   and models

ACL System
==========

I use some predefined ACL levels:

 Level        | Meaning
--------------+-----------------------------------------
 :moderator   | admin mode, might do everything
 :friend      | the current user is somehow related
 :user        | logged in user
 :guest       | guest/preview mode, I use it for
              | special try/guest accounts
 :anonymous   | users do not have to be authenticated


Setup
=====

The plugin does not generate a model by itself but extends an existing
User model and ActiveController::Base. The user model _must_ provide
an authenticate(user, password) method that returns the current user
object.

There's also some remember_me code left from Technoweenie's plugin which
will be altered soon. But for now please add the following rows to the
User model:

 * remember_token : text
 * remember_token_expires_at : date
 * activation_code : text
 * activated_at : date

The controller must supply different methods:
 * def role_for(user)
   This must return the role for the user in the current controller.
   Possible return values are :moderator, :friends, :user, :guests,
   :anonymous. The default implementation returns :user.

 * def prepare(user, params)
   user => current user
   params => incoming request parameters

   This is called before each request and might be used to initialize
   common per-request variables.

And the actual ACLs:
 * def acl_friends
 * def acl_user
 * def acl_guests
 * def acl_anonymous

If you want to enable access for a given action just add it to the
corresponding function, e.g.

def acl_user
  [:create, :new, :index]
end

will allow access to the create, new and index action to people that where
identified by role_for as :user. The default for all actions is the :moderator
role: this was choosen to make the ACL system rather strict but safe.

Activating the plugin
=====================

Just add "before_filter :acl_check" to your ApplicationController.

Guest mode
==========

Sometimes you need special user accounts for trial or guest users. For
this I've added the so called guest mode to the plugin. If a controller
should be accessable by a guest just add :guest do acl_guests. A guest
is identified by an appending "guest=<email>" parameter to an incoming
request.

Caching mode
============
By calling Blubber::ControllerSupport.create_access_matrix in your
environment.rb you can calculate the controller access matrix only
once at startup. This should speed up normal operation a bit.

But it is currently broken.

Accessing the current user
==========================
You can always access the current user through the current_user method
within all Observers, Models and Controllers. This might be used to
provide better custom ACL checking in your models.


[0] http://www.blackwhale.at
[1] git://github.com/technoweenie/restful-authentication.git

Example
=======

There's one rake task to generate a simple session_controller. Use rake blubber::create_session_controller and add the 
following to your config/routes.rb:

    map.resource :session
    map.login 'login', :controller => "sessions", :action => "new"

Then create a normal HTML form to submit the login data (e.g. in HAML):

- form_tag :controller => :sessions, :action => "create" do
  %p
    %label{:for => :email} Email
    = text_field_tag :email, nil, :size => 20
  %p
    %label{:for => :password} Kennwort
    = password_field_tag :password, nil, :size => 20
  %p.submit= submit_tag 'Login'

"I want to make UserController#index available to all users.
UserController#new and #create should be available to anyone
to allow them to login. The rest should only be available to
the owner":

in UserController:

  # if someone does a GET request on /users/<id> we will need
  # to know if he is the owner of the viewed resource
  def prepare(user, params)
    @viewed_user = params[:id] if params.include?(:id)
  end

  def acl_anonymous
    [:new, :create]
  end

  def acl_user
    [:index]
  end

  # check if the currently logged in user (current_user) is
  # looking at his own page, if so make him :moderator
  def role_for(user)
    if @viewed_user then
      return :moderator i @viewed_user.id == current_user.id
    end
    return :user
  end

in the User model:

  # for this example just use a simple testing account, real
  # implementations should check the password against a hashed
  # field in the database
  def authenticate(email, password)
    if email == "andy@snikt.net" && password == "fubar" then
      return true
    else
      return false
    end
  end


Copyright (c) 2008 Andreas Happe <andreashappe@snikt.net>
, released under the MIT license