Skip to content

Commit

Permalink
added "Lowell's" fantastic documentation for the plugin
Browse files Browse the repository at this point in the history
updated changelog
  • Loading branch information
timcharper committed Dec 12, 2007
1 parent dc4d6ea commit 26aaead
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 57 deletions.
1 change: 1 addition & 0 deletions ChangeLog
@@ -1,5 +1,6 @@
Version 1.3.2 - November 20, 2007
* Brought back test cases (now auto-evals the erb template to test to make sure the template for the generator is valid)
* Increased test coverage
* Automatically added :for and :for_all_except aliases, for more natural expressions

Version 1.3.1 - November 14, 2007
Expand Down
120 changes: 63 additions & 57 deletions README
@@ -1,82 +1,88 @@
== Summary ==
Version 1.1 - July 26, 2007
::Role Requirement Help::
role_requirement first assumes that the controller is accessible to everyone.
Each require_role line serves to add one or more required roles before executing actions within the controller.

There are many role-based security plug-ins out there. Often times, they are very complicated and much more than you need.
require_role "foo" "Require that the current_user must have role foo before executing any action within this controller."

RoleRequirement focuses on a simple approach to role-based authentication. you don't have to learn a new language in order to specify roles. Instead, RoleRequirement leverages the power of Ruby to strike a marvelous balance between simplicity and flexibility.
::"Limiting" Methods::
role_requirement accepts several methods as an options hash of key/value pairs. These methods work like clauses that limit the require_role line.
:only => "Evaluate this role requirement before executing ONLY the following actions in this controller..."
:for => Same as :only

Basic Features:
:for_all_except => "Evaluate this role requirement before executing ALL actions in this controller EXCEPT the following..."
:except => Same as :for_all_except

* Implement role security system using an enum field or a habtm collection (user can have one or many roles)
* Full Test Helpers to make it easy to test your controllers
* Squeaky Clean implementation so you don't have to repeat yourself.
These methods can be thought of as telling role_requirement when to evaluate current_user's roles.
require_role "foo", :for_all_except => :action1
# Means, "Anytime an action is called, require the role foo in order to execute, EXCEPT when action1 is called." So, action1 passes through this require_role line allowing anyone to access it, ALL other actions are evaluated against the specified role(s).

require_role "foo", :only => :action1
# Means, "Evaluate current_user's role(s) ONLY when action1 is called... and require foo in order to execute action1." So, every action except action1 passes through this require_role line, ONLY action1 is evaluated.

== Usage ==
::How require_role Lines Work In Combination::
Each line serves as an additional requirement to any other lines in the controller... like AND... not OR.

Steps to using as easy as 1, 2, 3!
require_role "foo"
require_role "bar"
# This means that role_requirement will look for BOTH roles for EVERY action in the controller, i. e. current_user must have both foo and bar roles to do anything in this controller.

=== 1. Install acts_as_authenticated and role_requirement ===

See install instructions below. You must generate your User model from acts_as_authenticated and include AuthenticatedSystem in your ApplicationController, as usual.
require_role "foo"
require_role "bar", :for_all_except => :action1
# This means that foo can access only action1 and bar can access everything in the controller except action1.
# The controller requires foo for every action AND looks for bar in order to execute every action except action1. (Probably not a very useful configuration!)

=== 2. Add has_role? to your User model ===
require_role "foo"
require_role "bar", :only => :action1
# This means that foo can access the entire controller and bar is required only for action1.
# The controller always requires foo and requires bar only when action1 is called. Useful for allowing only bar to call certain, more restricted, actions, for example.

{{{
class User < ActiveRecord::Base
...
# has_role? simply needs to return true or false whether a user has a role or not.
# It may be a good idea to have "admin" roles return true always
# You can use either a habtm relationship for roles, or a simple enum field.
# This example uses a habtm
def has_role?(role)
@roles ||= self.roles.collect(&:name)
return true if @roles.include?("admin")
(@roles.include?(role.to_s) )
end
...
}}}
::Passing Arrays::
role_requirement accepts arrays of roles and/or actions. When more than one role name or action name is passed, they work like "OR" in the requirement phrase.

=== 3. Require a roles in your controllers ===
require_role ["foo", "bar"]
# current_user can do anything in this controller if they have either role, foo OR bar.

It's easy as pie!
require_role "foo", :for_all_except => [:list, :show]
# The role foo is required to perform all actions in this controller EXCEPT list or show. So, anyone can list and show. Foo can do anything.

{{{
require_role "foo", :only => [:delete, :edit]
# The role foo is required to perform ONLY delete OR edit. Other actions are not evaluated. So, only foo can delete or edit. Others can do anything other than delete or edit.

class Admin::Users < ApplicationController
require_role "admin"
end
::Admin::
role_requirement's generator will automatically add a method to your user model, User#has_role?
This method, by default, always returns true for the role named "admin." This makes it easy to create a role that can access all actions, just name it "admin."

}}}
require_role :finance
require_role :admin, :only => :delete
# This means that finance can access the entire controller (and so can admin because admin always returns true for every role) AND admin is required to execute only the delete action.

Unlimited flexibility without the mess!
If you don't want this behavior, comment out the line that causes admin to always return true:
def has_role?(role_in_question)
@_list ||= self.roles.collect(&:name)
# return true if @_list.include?("admin") #This is the culprit.
(@_list.include?(role_in_question.to_s) )
end
You can also change the name of the "all access" role here. You can use any name that makes sense to you.

{{{
::Syntax::
If you use strings as keys for the options hash, it will throw an error. ie:

class Admin::Listings < ApplicationController
require_role "contractor"
require_role "admin", :only => :destroy # don't allow contractors to destroy
require_role "admin", "only" => "index"
# throws an error

# leverage ruby to prevent contractors from updating listings they don't have access to.
require_role "admin", :only => :update, :unless => "current_user.authorized_for_listing?(params[:id]) "
require_role "admin", :only => "index"
# works just fine

end
RoleRequirement does not care if the values are symbols or strings, regarding action names.

}}}
require_role "admin", :only => "index"
require_role "admin", :only => :index

== Installation ==
Roles are passed to User#has_role? exactly as specified. By default, RoleRequirement generates this method to not care. If you customize User#has_role? in such a way that it does care, then you'll have problems.

script/plugin install http://rolerequirement.googlecode.com/svn/tags/role_requirement/
require_role "admin", :only => :index
# ultimately calls User#has_role?("admin")


== Help ==

Here's how to get help

* Browse the http://code.google.com/p/rolerequirement/wiki/Documentation
* post an issue to the http://code.google.com/p/rolerequirement/issues/list

== Author ==
{{{
Tim C. Harper - irb(main):001:0> ( 'tim_see_harperATgmail._see_om'.gsub('_see_', 'c').gsub('AT', '@') )
}}}
require_role :admin, :only => :index
# ultimately calls User#has_role?(:admin)

0 comments on commit 26aaead

Please sign in to comment.