SimpleAccessControl =================== Acknowledgements: I give all credit to Ezra and Technoweenie for their two plugins which inspired the interface design and a lot of the code for this one. SimpleAccessControl is a streamlined, intuitive authorisation system. It derives heavily from acl_system2 and has made clear some problems which plagued me when first using it. Some fixes to acl_system2's design: * a normal Rails syntax: access_rule 'admin', :only => :index access_rule '(moderator || admin)', :only => :new * error handling for helper methods (permit? bombed when current_user == nil) * one-line parser, easy to replace or alter * proper before_filter usage, meaning access rules are parsed only when needed * no overrideable default (which I found counter-intuitive in the end) Also, it has two methods, access_control and permit?, for those moving from acl_system2. But, let me stress, everyone likes a slightly different system, so this one may not be your style. I find it synchronises very well with the interface of Acts as Authenticated (even though I have modified it so much that it's now called Authenticated Cookie). INSTALLATION ============ Create the following migration: create_table "roles", :force => true do |t| t.column "title", :string end create_table "roles_users", :id => false, :force => true do |t| t.column "role_id", :integer t.column "user_id", :integer end In your User model, you must have: has_and_belongs_to_many :roles In your Roles model, you must have: has_and_belongs_to_many :users Your controllers must have the following two methods or variants of them: # Returns a User object def current_user @current_user end # Returns true or false if a User object exists for this session def logged_in? @current_user.is_a? User end SPECIAL NEEDS ============= If you want to permit anonymous users without demanding that they are logged in, first you must ensure that logged_in? returns true in all cases, otherwise permission will be denied. The following approach should work: 1. Create the 'guest' and 'user' roles, e.g.: guest = Role.create(:title => 'guest') user = Role.create(:title => 'user') 2. In your registration/user creation area, ensure all real users have the 'user' role, e.g.: @user = User.create(params[:user]) unless @user.roles.any? { |r| r.title == 'user' } @user.roles << Role.find_by_title('user') end @user.save [At this point you have two options: a real or virtual anonymous account] First Approach: Real Anonymous User 3a. Create an anonymous user, e.g.: @anonymous = User.create(:login => 'anonymous', :password => '*', :activated => true) 4a. Add the role to the Anonymous user (in a migration or in script/console), e.g.: anonymous.roles << Role.find_by_title('guest') anonymous.save 5a. In your ApplicationController, set unauthenticated users as 'anonymous', e.g.: before_filter :default_to_guest def default_to_guest self.current_user = User.find_by_login('anonymous', :include => :roles) unless logged_in? end Second Approach: Virtual Anonymous User 3a. In your ApplicationController, create a virtual anonymous account if unauthenticated: before_filter :default_to_virtual_guest def default_to_virtual_guest self.current_user = self.anonymous_user unless logged_in? end def anonymous_user anonymous = User.new(:login => 'anonymous', :name => 'Guest') anonymous.roles << Role.new(:title => 'guest') anonymous.readonly! anonymous end USAGE ===== The plugin is automatically hooked into ActionController::Base. In your controllers, add access rules like so: access_rule 'admin', :only => :destroy access_rule 'user || admin', :only => [:new, :create, :edit, :update] Note the use of Ruby-style operators. These strings are real conditionals and should be treated as such. Every grouping of non-operator characters will be considered a role title. In your views, you can use the following: <% restrict_to 'admin || moderator' do %> <%= link_to "Admin Area", admin_area_url %> <% end %> AND <%= link_to("Admin Area", admin_area_url) if has_permission?('admin || moderator') %> There are also transitional methods which help you move from acl_system2 to this plugin -- I do this not to denegrate acl_system2 but because I did this for myself and decided to include it. The two systems are rather similar. Also, there are two callbacks, permission_granted and permission_denied, which may define in your controllers to customise their response. For example: def permission_granted logger.info("[authentication] Permission granted to %s at %s for %s" % [(logged_in? ? current_user.login : 'guest'), Time.now, request.request_uri]) end def permission_denied logger.info("[authentication] Permission denied to %s at %s for %s" % [(logged_in? ? current_user.login : 'guest'), Time.now, request.request_uri]) end That's it! VARIATION BY MABS29
Project
nbrew-simple_access_control
Simple access controls for use with ActsAsAuthenticated, RestfulAuthentication, etc. A clone of Mathew Abonyi's (mabs29) repo: http://mabs29.googlecode.com/svn/trunk/plugins/simple_access_control
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
Development
Dependencies
Development
>= 0
Project Readme