Skip to content

Latest commit

 

History

History
105 lines (66 loc) · 4.12 KB

README.textile

File metadata and controls

105 lines (66 loc) · 4.12 KB

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.

       Proc.new do |controller|
          user = controller.send :current_user
          user.groups if user
        end

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]
            }
          end
        end

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 = ?", user.id, group.to_s, @locale).nil?
      	end
      end
    end

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 = Proc.new { Session.user }

other authorization libraries

cancan . . .

Guard the Rails3 Controller Actions

info about the actual gem please look into the directory http://github.org/mkristian/ixtlan-guard/gem:gem

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