Forum: Ruby on Rails Role Based Authorization recipe implementation?

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Ana B. (Guest)
on 2006-04-28 02:44
i got the rails recipes book, i have now an auth system for users
without problems, now i want to made a role based acces for my app, im
following the "Role Based Authorization" recipe of the book but i cant
make it to work even when the tables created and correctly added data
manually definig the roles and rights. als i dont know how to define a
right for use all the actions in a certain controller or define another
that gives right to use a group of controllers.

If someone knows where to find an implementation of this, good
references about this kind of auth system or willing to help with this
will be excellent. :)
Jim M. (Guest)
on 2006-04-28 03:04
(Received via mailing list)
I implemented the RBAC from the recipes book it seems to work fine. I
synchronize_with_controllers  to my rights model, taken from the
user_engine (which is a
great resource to get ideas from), it automatically finds all
controllers and actions
and adds them to the rights table.

Then all you have to do is associate the relevant right with the
relevant role.

I have an example view to do that which I'll try to write up and post

It is also helpful to have an override to get things setup initially,
what I do is allow
any used logged in with the name admin, to get rights to everything.
basically add
something like this to the authorized? method..

        # admin can do everything
        if user.login_name == 'admin'
            return true

# this is the Rights model...

class Right < ActiveRecord::Base
    has_and_belongs_to_many :roles
    validates_presence_of :controller, :action, :name
    validates_uniqueness_of :name

    # Ensure that the table has one entry for each controller/action
    def self.synchronize_with_controllers
        # weird hack. otherwise ActiveRecord has no idea about the
superclass of any
        # ActionController stuff...
        require RAILS_ROOT + "/app/controllers/application"

        # Load all the controller files
        controller_files = Dir[RAILS_ROOT +

        # we need to load all the controllers...
        controller_files.each do |file_name|
            require file_name #if /_controller.rb$/ =~ file_name

        # Find the actions in each of the controllers, and add them to
the database
        subclasses_of(ApplicationController).each do |controller|
            controller.public_instance_methods(false).each do |action|
                next if action =~
           => "#{controller}.#{action}",
:controller =>
controller.controller_path, :action => action).save!
           "added: #{controller} -
Ana B. (Guest)
on 2006-04-28 04:11
I thinks thats far more complicated that what im trying to do, i have
this data:

users         id    username
              15      ana

roles_users  role   user_id
               2       15

roles         id     name
               2    moderator

rights_roles  right_id   role_id
                2           2

rights          id         name          controller       action
                 2      see dashboard     dashboard        list

so it gives permission to the user ana to see the dashboard and its list
action, but when i try to login i get "You are not authorized to view
the page you requested" and shows again the login form.

Note: if i take of the check_authorization action from the controller
the authentication works perfect.

Here is my code:

#admin_controller--------where auth takes place
class Admin::AdminController < ApplicationController
before_filter :check_authentication, :check_authorization,
:except => [:signin_form, :signin]

layout 'admin/login_form'
def index
redirect_to :controller => 'dashboard'
def check_authentication
  unless session[:user]
    flash[:notice] = "caminaste"
    redirect_to :controller => "admin", :action => "signin_form"

def check_authorization
  user = session[:user].id
  unless user.roles.detect{|role|
        right.action == action_name && right.controller ==
    flash[:notice] = "You are not authorized to view the page you
    request.env["HTTP_REFERER"] ? (redirect_to :back) : (redirect_to
:controller => 'dashboard')

    return false

hope im a little more clear :(
Jim M. (Guest)
on 2006-04-28 11:11
(Received via mailing list)
Without knowing what url you are trying to access I can take a guess.

The only controller/action that will not give this error is

Even dashboard/index will give the error, so maybe you are trying to
access the index in
which case it needs to be added as a right too.

Remember that every method that can be called in a controller needs to
have a right
associated with it, and the role needs to be associated with each right
it my need to

But just to be a little clearer what url are you trying to access, and
maybe an excerpt
from the server log would help.
Rob B. (Guest)
on 2006-04-28 14:19
Ana B. wrote:
>i get "You are not authorized to view
> the page you requested" and shows again the login form.
> Note: if i take of the check_authorization action from the controller
> the authentication works perfect.

I had the same problem with that recipe, never solved it so used this
tutorial instead.

Seems to work to some degree but not as good as the recipe would have
been if I could have made it work.
Clélia N. (Guest)
on 2006-06-09 02:07
I have also started to work with this role based implementation, but
when I try to  have a check_authorization,

def check_authorization
	unless user.roles.detect{|role|
			right.action == action_name && right.controller ==

	flash[:notice] = "failed"
	request.env["HTTP_REFERER"] ? (redirect_to :back) : (redirect_to
:action => "home")
return false

I have this message

Mysql::Error: #42000You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'right  INNER JOIN right_role ON =
right_role.right_id WHERE (right_role' at line 1: SELECT * FROM right
INNER JOIN right_role ON = right_role.right_id WHERE
(right_role.role_id = 1 )

And I am sure I have correctly entered the data in the tables and join

I wanted to know if it were the actions that caused trouble but it
actually fails when I just enter :

def check_authorization
	user = User.find(session[:user])

Anyone has an idea of what I did wrong ?
Thanks for the reply
David Andersen (Guest)
on 2006-06-09 04:23
(Received via mailing list)
i think it may have something to do with the fact that you're using the
word 'right'.
considering one can do left and right joins.
try renaming your model.

David Andersen (Guest)
on 2006-06-09 04:27
(Received via mailing list)
that is, rename your table name, this is a mysql thing.
This topic is locked and can not be replied to.