This example is based on ACLController.
It uses AccessControlListExample database model and assumes you used the LoginGenerator.
It adds Roles such that
Users <-> Roles <-> Permissions
A User’s permissions are added to their session when they authenticate. Permissions are of the form {controller}/{method}. For example:
posts/add posts/edit posts/index #use this if you want to protect "url/posts"
The Controller supports ‘guest perms’ which do not require any permissions. Other methods require the user to have the permission string before the action is performed. If the user is unauthorized, they are returned to the requesting page.
Any other method will require the user to have that permission. Permissions are kept as part of their session. Any changes made to the User’s permissions will not take effect until they login again. The filters added to this controller will be run for all controllers in the application. Likewise all the methods added be available for all controllers.
acl_controller.rb:
require 'action_controller'
require 'application_helper'
require 'user'
class ACLController < ActionController::Base
# This is a secured controller from which others should derive. They are a limited set
# of methods which are callable by anyone. They are defined in the @guest_perms array.
# By default, #list and #show are unsecured.
# Example:
# class PostsController < ACLController
# def initialize
# super
# @guest_perms = [ "posts/summary","posts/show"]
# end
# end
#
include ApplicationHelper
layout "shared/base"
before_filter :authorize
def initialize
@sections ||= %w/Users Roles Permissions/
@pretty_name ||= controller_name
@guest_perms ||= [ "#{@pretty_name.downcase}/list",
"#{@pretty_name.downcase}/show"]
@uri_name = @pretty_name.downcase
@edit_uri = "#{@pretty_name.downcase}/edit"
end
def list
end
def show
end
def new
end
def edit
end
def update
end
def destroy
end
def create
end
protected
# Authorizes the user for an action.
# This works in conjunction with the LoginController.
# The LoginController loads the User object.
def authorize
required_perm = "%s/%s" % [ @params["controller"], @params["action"] ]
unless @guest_perms.include? required_perm
unless @session[:user]
flash['error'] = "Request not permitted unless logged in."
@session[:return_to] = @session["prev_uri"]
#ensure you change "user" to your login controller name
redirect_to(:controller => "user", :action => "login")
return false
end
unless @session[:user].authorized? required_perm
flash['notice'] = "You are not authorized for #{required_perm}."
redirect_to_path @session["prev_uri"].to_s
return false
end
end
@session["prev_uri"] = @request.request_uri
return true
end
end
The User model defines authorized?. It determines if the user has the permission string.
user.rb: (add the new methods under self.authenticate)
# Return true/false if User is authorized for resource.
def authorized?(resource)
return permission_strings.include? resource
end
# Load permission strings
def permission_strings
a = []
self.roles.each{|r| r.permissions.each{|p| a<< p.name }}
a
end
In the controller that’s using the ACL (ie: \PostsController), change:
class PostsController < ApplicationControllerTo:
class PostsController < ACLController
If you want to automatically populate a table (e.g. Permissions) with a list of all controller/actions defined in your app, see DiscoveringControllersAndActions