Role_Based_Permissions

21
Role Based Permissions Ruby on Rails way Eric Sun 7/26/2008

description

 

Transcript of Role_Based_Permissions

Page 1: Role_Based_Permissions

Role Based PermissionsRuby on Rails way

Eric Sun7/26/2008

Page 2: Role_Based_Permissions

Why Roles?

Page 3: Role_Based_Permissions

Why Permissions?

Page 4: Role_Based_Permissions

Why Role based ?

John

Manager (Role)

Adan

JamesAdd

Edit

Del

Page 5: Role_Based_Permissions

UML Dialog

Page 6: Role_Based_Permissions

Programming way

>>> Role.new({ :identifier => 'roles.admin' }).save! 

>>> StaticPermission.new({ :identifier => 'permissions.all' }).save!

>>> user = User.new>>> user.save! 

>>> user.roles << Role.find_by_identifier('roles.admin') 

>>> user.has_role?('roles.admin') => true >>> user.has_permission?('permissions.all', 'foo') => true >>> user.has_permission?('foo') => false 

Page 7: Role_Based_Permissions

Trikr Demo

Page 8: Role_Based_Permissions

Step 1: active_rbac plugin

active-rbacRole Base Access Control for Rails (RBAC)

Install active-rbac:

$> cd $RAILS_ROOT$> svn co svn://rubyforge.org/var/svn/active‐rbac/active‐rbac/trunk/plugin \

vendor/plugins/active_rbac

Page 9: Role_Based_Permissions

Step 2.1: Basic Setting – brand new project

$> ./script/generate rbac_bootstrap

create  app/controllers/auth_controller.rbcreate  app/views/auth/login.rhtmlcreate  app/views/auth/logout.rhtmlcreate  test/functional/auth_controller_test.rbcreate  app/models/anonymous_user.rbcreate  test/unit/anonymous_user_test.rbcreate  app/models/user.rbcreate  test/unit/user_test.rbcreate  app/models/role.rbcreate  test/unit/role_test.rbcreate  app/models/static_permission.rbcreate  test/unit/static_permission_test.rbcreate  test/fixtures/users.ymlcreate  test/fixtures/roles.ymlcreate  test/fixtures/static_permissions.ymlcreate  db/migratecreate  db/migrate/001_add_rbac_schema.rbexists  db/migratecreate  db/migrate/002_insert_rbac_records.rb

Page 10: Role_Based_Permissions

Step 2.2.1: Basic Setting – add to your current project

The required table columns:USERS ‐ user model 

none ROLES ‐ role model 

identifier ‐ string STATIC_PERMISSIONS static_permission model 

identifier ‐ string ROLES_USERS ‐ role to user join table 

user_id,role_idROLES_STATIC_PERMISSIONS ‐ role to static permission join table 

role_id,static permission_id

Page 11: Role_Based_Permissions

Step 2.2.2: Basic Setting – add to your current project

The required model setting:class User < ActiveRecord::Baseacts_as_user

end 

class Role < ActiveRecord::Baseacts_as_role

End

class StaticPermission < ActiveRecord::Baseacts_as_static_permission

end

Page 12: Role_Based_Permissions

Step 2.2.3: Basic Setting – add to your current project

Application.rb:require_dependency 'user'require_dependency 'role' require_dependency 'static_permission' class ApplicationController < ActionController::Baseend

Page 13: Role_Based_Permissions

Step 3: Define your permission identifier

Permision identifier:Post new messages in category in project id 723 (Parent)StaticPermission.new({:identifier=>’prj_723_msg_cat_new’})

Post new messages in category id 426StaticPermission.new({:identifier=>’prj_723_msg_cat_426_new’})

Edit messages in category id 426StaticPermission.new({:identifier=>’prj_723_msg_cat_426_edit’})

Delete file in category id 513StaticPermission.new({:identifier=>’prj_723_file_cat_513_del’})

Page 14: Role_Based_Permissions

Step 4: Inherit mechanism

Page 15: Role_Based_Permissions

Step 4: Inherit mechanism Implementation

Add a table no_permissions_inherits:desc no_permission_inherits;+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+| Field      | Type         | Null | Key | Default | Extra       |+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+| id         | int(11)      | NO   | PRI | NULL    | auto_increment | | company_id | int(11)      | YES  | MUL | NULL    |                | | project_id | int(11)      | YES  | MUL | NULL    |                | | identifier | varchar(255) | YES  | MUL | NULL    |             | +‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+Sample records| 525 |       NULL |        747 | prj_747_234_msg_cat  | +‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+

Page 16: Role_Based_Permissions

Step 4: Inherit mechanism Implementation

Add a table no_permissions_inherits:class User > ActiveRecord::Base

def has_permissions?(per)…

if NoPermissionInherit.find_by_identifier(per_inherit)return self.has_static_permission?(per)

# Permission inherit from parentelse

# parent permission labelper_parent_inherit = per_label + "_" + pid + "_" + func_labelif NoPermissionInherit.find_by_identifier(per_parent_inherit)return self.has_static_permission?(per_parent,per)

elseper_parent_parent = per_label + "_" + pid + "_" + "parent" 

+ "_" + per_typereturn self.has_static_permission?(per_parent,per_parent_parent,per)

end end

end

Page 17: Role_Based_Permissions

Step 5: other special roles

class User > ActiveRecord::Basedef has_permissions?(per)

#give all permission to account owner return true if self.account_owner?

#give all permission to Administratorreturn true if self.administrator?

#give no permission to Guest return false if self.role == "Guest"

#give view permission to Global User return true if self.role == "Global User" and pers.last == "view"

#give no permission to Global User except view return false if self.role == "Global User" and pers.last != "view"

#Give all permission to project managerreturn true if task = Task.find(:first,:conditions=>["user_id= ? And

project_id=? ",self.id,pid]) and task.role == "Project Manager"end

end

Page 18: Role_Based_Permissions

Step 6: apply permissions

def show redirect_to nopermission_project_permission_path(@project)  \if @project.use_permissionand (not @cur_user.has_permission? ("prj_" + @message.project.id.to_s + "_" + @message.category_id.to_s+ "_msg_cat_view")) and @message.user_id != @cur_user.id

End

Def index

filter_sql = filter_sql(@project,"msg")@message_pages, @messages= paginate :messages, :per_page => 10,:conditions=>["(project_id = ? and (#{filter_sql})) or (project_id = ? and user_id = #{@cur_user.id})",params[:project_id],params[:project_id]],:order => "id desc"

End

Page 19: Role_Based_Permissions

Step 6: apply permissions

def filter_sql(project,label)uncat_sql = ""

uncat_sql = "category_id is null or category_id = 0" \if @cur_user.has_permission?("prj_#{@project.id}_unc_" \

+ label + "_cat_view")

cids = cats.select{ |c| @cur_user.has_permission?("prj_" + \project.id.to_s + "_" + c.id.to_s + "_" + label +  \"_cat_view")}.collect{|c| c.id}.join(",")

cids_sql = "category_id in (#{cids})" if cids.to_s != ""

if cids_sql == "" and uncat_sql != ""filter_sql = uncat_sqlelsif cids_sql != "" and uncat_sql == ""filter_sql = cids_sqlelsif cids_sql != "" and uncat_sql != ""filter_sql = cids_sql + " or " + uncat_sqlend filter_sql = "false" if filter_sql.nil? 

return filter_sqlend

Page 20: Role_Based_Permissions

Resources:

Ruby forge url:   http://rubyforge.org/projects/active‐rbac/Active‐rbac doc:  http://active‐rbac.rubyforge.org/docs/Project homepage: http://active‐rbac.rubyforge.org/Google group:     http://groups.google.com/group/active‐rbac

Page 21: Role_Based_Permissions

Email:yundong.sun[AT]trikr.com在线项目管理软件 http://www.trikr.com