Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Thursday, April 1, 2010

Building your own permission system in ruby on rails.

If you're like me and have a application that's growing into a fairly complex application and certain pages are only accessible to certain users/groups then the best way to keep track of your permissions is to generate a permissions model to store the permissions data. This article is a step by step guide to creating a fully functioning permissions that should suit your applications needs.

Step 1, Create the UserPermission model.

script/generate model UserPermission controller:string action:string id_of_object:integer t.integer person_id:integer

You may or may not want to delete the t.timestamps out of the migration that was created for you in db/migrate (should be your newest migration, eg. 20100401043834_create_user_permissions.rb) as I don't feel timestamps are necessary for this type of data.

In your User model add:

has_many :user_permission

In your UserPermission model add:

belongs_to :person
validates_presence_of :controller
validates_presence_of :action
validates_presence_of :id_of_object
validates_presence_of :person_id


Step 2, Implement your before_filter method
Note you must already have your own method to access the current user to complete this step.
In this code example we access our current user with the @user variable (which in my code this is defined in a before_filter that executes on every page)

In app/controllers/application_controller.rb, write the following. I wrote mine under private.
def require_permission
   p =  = @user.user_permission.first(:conditions => "controller = '%s' and (action = '%s' OR action = '*')" % [params[:controller], params[:action]])
    if params[:id] and p
      unless p.id_of_object == params[:id].to_i or p.id_of_object == 0
        p = false
      end
    end
    unless p
      flash[:notice] = "Permission Denied"
      redirect_to :controller => 'people'
    end
end

Step 3, Implement
Add a before_filter :require_permission anywhere where you want this to execute.

Now lets create some permissions, I do this in my app console with the following code but you may create your own view from here to do this.

script/console production in your app directory to access console for your production environment (remove production for development environment)

Then type this:
p = @user.user_permission.new(:controller => 'posts', :action => '*', :id_of_object => 0); p.save

This will give you access to all objects and all actions for posts. * is a wildcard for :action and 0 is a wildcard for :id_of_objects, you can set this to something specific like :action => 'new' or set the :id_of_object to a specific number.

Anyways hope this helps, if any questions feel free to ask!