public
Description: A mature Rails Plugin for role-based authorization (polymorphic on subject and trustee, DSL for auth expressions, model- and controller-level expressions)
Homepage:
Clone URL: git://github.com/cch1/authorize.git
name age message
file .gitignore Tue Aug 05 14:49:13 -0700 2008 Removed debugging log from git. [Chris Hapgood]
file LICENSE Fri May 29 14:03:03 -0700 2009 Added license [Chris Hapgood]
file README Mon Aug 10 07:25:08 -0700 2009 Update README to reflect token-based approach t... [Chris Hapgood]
file Rakefile Sun Feb 11 10:05:43 -0800 2007 First cut at authorization plugin. git-svn-id:... [cch1]
directory generators/ Tue Aug 05 07:55:47 -0700 2008 Cleanup documentation and add migration generat... [Chris Hapgood]
file init.rb Mon Sep 14 12:44:52 -0700 2009 Delegate loading of most dependencies to Rails [Chris Hapgood]
file install.rb Sun Feb 11 10:05:43 -0800 2007 First cut at authorization plugin. git-svn-id:... [cch1]
directory lib/ Mon Sep 14 12:44:52 -0700 2009 Delegate loading of most dependencies to Rails [Chris Hapgood]
directory tasks/ Sun Feb 11 10:05:43 -0800 2007 First cut at authorization plugin. git-svn-id:... [cch1]
directory test/ Mon Sep 14 12:53:50 -0700 2009 Updated default Rails version for testing to 2.3.2 [Chris Hapgood]
file uninstall.rb Sun Feb 11 10:05:43 -0800 2007 First cut at authorization plugin. git-svn-id:... [cch1]
README
Authorize
=========
authorize is a Ruby on Rails plugin providing a sophisticated Role-Based Access Control (RBAC) system.  It started as a 
spinoff of Bill Katz's 
Authorization plugin, but has been substantially tested, debugged and enhanced since then.  Current functionality 
highlights include:

 * Polymorphic association of ActiveRecord models as subjects.
 * Three-level (global, class, instance) authorizations over subjects.
 * Trustee identification via a flexible token system, supporting groups, "public" authorizations and proxies.
 * "Acts" to support a single ActiveRecord model being both a subject and a trustee.
 * Dynamic methods on subjects and trustees support domain-specific syntax: user.is_owner_of(widget)? and 
 widget.is_owned_by?(user)
 * Performance-optimized Domain-Specific Language (DSL) for more sophisticated predicates (available in ActionController 
 at controller and action level).

For more information on the theory of RBAC, see http://en.wikipedia.org/wiki/Role-based_access_control, but note that 
the term "subject" is used where this plugin uses the term "trustee".

----------------

The authorize plugin extends ActionController with the ability to check permissions and react accordingly.  There are 
two approaches:
a simple boolean check (permit?) and a more sophisticated predicated block (permit) with exception handling.  In both 
cases, the method accepts
a permissions description string expressed in a domain-specific language.  The simplest version of this language is just 
the name of the required 
global/generic role.  For example, using the boolean version:

  permit? "adminstrator"

More complex expressions typically involve requiring a particular role over a particular model instance.  For example:

  permit? "owner of :widget"  

Clean hooks are available for identifying the appropriate authorization tokens for the current request.  No "User" class 
is assumed, no "current_user"
method is required.

The authorize plugin extends ActiveRecord with two methods: acts_as_subject and acts_as_trustee.  A given model may 
invoke
either or both, depending on requirements.  The follow narrative shows the methods added to models for management of 
role-based authorization.
 
ActiveRecord-provided associations (see AR documentation for complete list of related methods)
  Trustee (User or Group, for example)
    authorizations
          Returns array of authorizations belonging to trustee
          Deprecated equivalent: roles
    subjected_<subjected_models>   # Note the use of the plural model name
          Returns authorized model objects
          Not yet implemented
  Subject (Widget, for example)
    subjections  # Synonym for authorizations -must be distinct to permit model as both trustee and subject.
          Returns array of authorizations over acts_as_subject objects.
          Deprecated equivalent: accepted_roles
    authorized_<trustee_models>
          Returns array of trustees with an authorization over the acts_as_subject object.
          Not yet implemented
  Authorization
    trustee
          Returns the authorized trustee
    subject
          Returns the object of the authorization
    subjected_<subjected_model>     # Note the use of the singular model name
          Returns subjected model object of named class.  NB: This association is only safe with UUID-keyed models!
          Disabled
    authorized_<authorized_model>      # Note the use of the singular model name
          Returns authorized trustee object of named class.  NB: This association is only safe with UUID-keyed trustees!

                    Disabled
Standard plugin methods:
  Trustee
    authorize <Role>, <Subject Instance or Class>
          Creates an authorization for the trustee as <Role> over the subject Instance or Class.  If neither an instance 
          nor a class is specified,
          the trustee is granted a generic/global authorization.
    unauthorize <Role>, <Subject Instance or Class>
          Removes any authorization for the trustee as <Role> over the subject Instance or Class.  Leave off the 
          instance or class to remove a
          generic authorization.
    authorized? <Role>, <Subject Instance or Class>
          Boolean condition for the trustee being authorized as the <Role> over the subject Instance or Class.  Leave 
          off the instance or class to
          check for a generic/global authorization.
  Subject (Authorizable Class or Instance)
    subject <Role>, <Trustee>
          Subjects the model instance or class to the authority of trustee as the named role.
    unsubject <Role>, <Trustee>
          Removes any authorization for the trustee as the named role over the model instance or class
    subjected? <Role>, <Trustee>
          Boolean condition for the the model Instance or Class being subjected to the authority of trustee as the named 
          role.
Identity Mixin methods:
  Trustee
    is_<Role>_for_what
          Returns array of subjects for which trustee as <Role> is authorized
    is_<Role>_<Preposition>?(<Authorizable object>)
          Boolean condition for trustee as <Role> being authorized for the specified subject.
    is_<Role>[_<Preposition> <Authorizable object>]
          Creates authorization for trustee as <Role> either generically or over the specified subject (model or class)
    is_<Role>
          Creates generic authorization to trustee as <Role>
  Subject
    has_<Role>
          Returns array of trustees having specified role over the subject.
    has_<Role>?
          Boolean conditioned upon at least one trustee having <Role> over the subject.
          
----------------

A Note on Authoriztion Tokens

Authorization Tokens are the key to an authorization.  Consequently, they support a security model based on something 
virtually possessed by the user
rather than simply an attribute of the user.  How a user accumulates authorization tokens is up to you.  Here are some 
ideas:

  1. Create a "Public" token and persist it with the application configuration.  In a before_filter, accumulate this 
  token (probably the first one).
  2. Create a token for each user and persist it in his user model instance.  When he authenticates, accumulate his 
  token.
  3. Allow a user to affiliate with groups that also have a persisted token.  When membership is ascertained, accumulate 
  the group token.
  4. Create a shared secret token on and display it to the "owner".  Provide a page where any user can prove he shares 
  the secret by entering 
     the token, which can be a simple Authorization.find_by_token(), and accumulate the token.  Note that allowing users 
     to grab tokens like this
     can be a security risk if "private" tokens can be guessed.  Resolve the problem by using hashs as tokens.  Shared 
     secret tokens are in fact a
     hash of the true shared secret (which can be a user selected phrase, a bubblebabble, etc.) while private tokens are 
     a hash of a random
     discarded value.  Then, in theory, private tokens can only be accessed by guessing the discarded random value or by 
     looking up the actual
     token on the user model instance.