Skip to content
simple authorization framework for rails3
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Guard the Rails Controller Actions

installation for rails3

just add

        gem 'ixtlan-guard'

into your Gemfile

how it works

the main idea is like a posix authorization with a user belonging to one or more groups. each rails controller gets a Guard which maps each action of the controller to a set of allowed groups.

the default block which retrieves the logged in user from current_user method of the controller and collect the groups of this user. which makes it compatible with restful_authentication_. in case there are no currentuser the Guard will allow everything assuming there have no authentication and no authorization for this controller. do |controller|
          user = controller.send :current_user
          user.groups if user

you can define a superuser group which default is root and that group is implicit added to all guards.

        class UsersGuard
          def initialize(guard)
            guard.aliases = {:new=>:create, :edit=>:update}
            guard.actions= {
              :index => [:users],
              :show => [:users],
              :create => [:users],
              :update => [:users],
              :destroy => [:users]

restrict the access even further

assume you can translate your web application and have a translator group but you want to restrict each translator to its language. then you can use the guard to enforce this restriction.

let’s add the following to your TranslationsController

before-filter :locale_authorization
    skip-before-filter :authorization
    def locale_authorization
      @locale = Locale.find_by_code(params[:locale])
      authorization do |group| 
        if controller.respond_to? :current_user
          user = self.send :current_user
	  !GroupsLocalesUsers.first(:conditions => ["user_id = ? AND group_name = ? AND locale_name = ?",, group.to_s, @locale).nil?

this you can easily use for other use cases like having different domains. each domain has its own set of users. even allowing users to be associated with more then one domain.

allowed? method in controller/view

both the rails controller as well the view have a methods allowed? to ask the guard if a particular action is allowed by the current_user.

the controller allowed? just needs the action as argument.

the view allowed? needs the resource name and the action to answer the quest.

rails3 generators

per default the scaffold, resource and controller will add a guard for the actions of the generated controller. the views of the scaffold will use allowed? to determine if a link or button leads to an action which is allowed for the current_user

maintanance mode

since the guard is the ideal place to temporary disallow or block some groups, the guard offers some helper methods for this:

  • block_groups(array_of_groups)
  • blocked_groups
  • current_user_restricted?(controller)
    with this you can easily block all groups but the root which remains as it is.

play together with authentication frameworks

the guard plays nicely together with authentication frameworks like restful-authentication, devise or any homegrown authentication which provides a current_user method for all controllers. see demo of that gem.

even if you can not provide current_user method you can use the guard with a custom block. pass in an block on initialization which returns the current user from somewhere. for example add something like this in an confug/initializer:

Rails.configuration.guard.block = { Session.user }

other authorization libraries

cancan . . .

Guard the Rails3 Controller Actions

info about the actual gem please look into the directory

run all the specs, features + integrations-tests in one go

first you need jruby for this ! then you need to install

        jruby -S gem 'ruby-maven'

which allows to run the integration-tests from the demo with jetty.

now you can execute

        rmvn verify
Something went wrong with that request. Please try again.