Rails – set restriction and permission on attributes at model level based on role system (using restricted_attributes plugin / gem)

Posted: August 30, 2011 in Jruby, Ruby On Rails
Tags: , , , , , , , , ,

Rails – set restriction and permission on attributes at model level based on role system (using restricted_attributes plugin / gem) – validate params at model level

RestrictedAttributes  Plugin / Gem:

This restricted_attributes plugin provides the capabilities to restrict attributes (fields) of db table’s while add or update a record. It validates your attributes values before your validation stuff.

Features :

  • Provides four different ways of restriction on fields (i.e read_only, create_only, update_only and hidden)
  • Restrict to add/modify values of particular attributes at model level while creating/updating a record.
  • Restrict functionality perform at before validation.
  • Able to set restriction on instance variables also.
  • OPTIONAL: It can also works on the basis of declarative authorization roles system.
  • So, able to set role wise restriction/permission on various users to change the value of an attributes.

More Information and download links :

Plugin :-  https://github.com/gkathare/restricted_attributes

Gem    :- http://rubygems.org/gems/restricted_attributes

Installation and Configuration :

1. Install restricted attributes plugin / gem :

- Install Plugin:

Download restricted_attributes plugin from above plugin link and add it your projects vendor directory.

- Install Gem :

You can install restricted_attributes gem, just add  following line in your project’s gemfile.

     gem “restricted_attributes”

2. Requirements (If you want to use :declarative tag feature) :

 - declarative_authorization plugin/gem.

3.  permissions.yml

Create permissions.yml file in your project/config  folder. like,

Format : /config/permissions.yml
    _____________________________________________________________
    |:default:
    |  :readonly: [:attribute1, :attribute2]
    |  :hiddenonly: [:attribute1, :attribute2]
    |  :createonly: [:attribute1, :attribute2]
    |  :updateonly: [:attribute1, :attribute2]
    |:role_1:
    |  :class_name_1:
    |    :readonly: [:attribute1, :attribute2]
    |    :hiddenonly: [:attribute1, :attribute2]
    |    :createonly: [:attribute1, :attribute2]
    |    :updateonly: [:attribute1, :attribute2]
    |    :permit_to: [:attribute1, :attribute2]
    |  :class_name_2:
    |    :permit_to: [:attribute1, :attribute2]
    |:role_2:
    |  :class_name_1:
    |    :permit_to: [:attribute1, :attribute2]
    |  :class_name_2:
    |    :permit_to: [:attribute1, :attribute2]
    |
    |
    |___________________________________________________________

where :

  •  role_1, role_2 are the roles of user.
  • class_name_1, class_name_2 are the class name or Model name
  • readonly, hiddenonly, createonly, updateonly - To set restriction on specific role.
  • permit_to: [] feature to set permission to change value of added attributes.
  • default: provides common restricted attributes for all classes of all roles like id, create_at, updated_at.

======================= Examples ============================

# Example 1 Simple one (without use of :declarative tag feature)
================================================================

    class Post < ActiveRecord::Base
        has_restricted_attributes :read_only => [:status],
                            :create_only => [:title, :publish],
                            :update_only => [:tags],
			    :hidden_only => [:activated],
                            :read_only_message => "is a read only attribute",
                            :create_only_message => "can't update, its permitted to create only.",
                            :update_only_message => "can't add, its permitted to update only."
    end

So, the restricted attributes will be as shown in following table.

# Post Model :

Can-> Read/Hidden Only):status/:activated (Create Only):title,:publish (Update Only):tags
Create Update Create Update Create Update
 Any User NO NO YES NO NO YES

Console Output :
———————–

    >> post = Post.new(:status => true, :title => "New Title", :tags => "new, topic")
    >> post.save
    => false

    >> post.errors
    => #<OrderedHash {:status => ["is a read only attribute"], :tags=>["can't add, its permitted to update only."]}>

    # for hidden attributes
    >> post = Post.new(:activated => true)
    >> post.save
    => false

    >> post.errors
    => #<OrderedHash {:status => ["is a hidden attribute"]}>
    OR
    >> post.is_restricted?(:read, :activated)  # To check :activated field is restricted to read.
    => true

===============================================================

# Example 2 : (with :declarative => true tag feature)
=====================================================

Step 1 :

    class User < ActiveRecord::Base
        has_restricted_attributes :read_only => [:logged_in],
                            :create_only => [:login, :email],
                            :update_only => [:bio],
                            :declarative => true

    end

    class Post < ActiveRecord::Base
        has_restricted_attributes :read_only => [:status],
                            :create_only => [:title, :publish],
                            :update_only => [:tags],
			    :hidden_only => [:activated],
                            :declarative => true,
                            :read_only_message => "is a read only attribute",
                            :create_only_message => "can't update, its permitted to create only.",
                            :update_only_message => "can't add, its permitted to update only."
    end

Step 2 :
Create permissions.yml file in your project/config/  folder,  and add roles and permissions for the user as shown in following table.

* Here you can set permission to change the value of restricted attributes on the basis of role system.

Example:
    ## /config/permissions.yml
     ___________________________________________________________
    |:default:
    |  :readonly: [:created_at, :updated_at]
    |:global_admin:
    |  :user:
    |    :permit_to: [:logged_in, :login, :email, :bio]
    |  :post:
    |    :permit_to: [:title, :status, :publish, :tags]
    |:member:
    |  :user:
    |    :permit_to: [:email]
    |  :post:
    |    :permit_to: [:publish]
    |
    |
    |
    |
    |___________________________________________________________

asdfasdf

# where in that,

  • :global_admin , :member are the roles of user. [ROLE]
  • :user , :post are the class names [CLASS/MODEL]
  • :permit_to: [] here you can add those attributes which will be permitted for appropriate User [ATTRIBUTES]
  • :default: you can add common attributes to restrict the access for all classes.

Result :
———

So, the permissions on restricted attributes for global_admin and member user will be as shown in following table.

#Post Model :

        Can-> (Read Only)
:status
(Create Only)
:title,:publish
(Update Only)
:tags
Create Update Create Update Create Update

User
(global_admin)

YES YES YES YES YES YES

User
(member)

NO NO YES NO-:title YES-:publish NO YES

Console Output :
———————–

    
    # for member user
    >> Authorization.current_user = User.find_by_login("member")
    >> post = Post.new(:status => true, :title => "New Title", :tags => "new, topic")
    >> post.publish = true
    >> post.save
    => false
    >> post.errors
    => <OrderedHash {:status => ["is a read only attribute"], :tags => ["is a update only attribute"]}>

    >> post = Post.find(123)
    >> post.title = "My new title"
    >> post.publish = false
    >> post.save
    => false

    >> post.errors
    => <OrderedHash {:title => ["is a create only attribute"]}>

    # for hidden attributes
    >> post = Post.new(:activated => true)
    >> post.save
    => false

    >> post.errors
    => #<OrderedHash {:status => ["is a hidden attribute"]}>
    OR
    >> post.is_restricted?(:read, :activated)  # To check :activated field is restricted to read.
    => true

    ### For Global Admin

    >> Authorization.current_user = User.find_by_login("global_admin")
    >> post = Post.new(:status => true, :title => "New Title", :tags => "new, topic")
    >> post.save
    => true

    >> post.errors
    => #<OrderedHash {}>

======================= End Examples ============================

More information & more examples refer in it’s Part 2  (Coming soon)

Cheers!!! :)

Thank you
Ganesh K

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s