Role_Based_Permissions
-
Upload
wear -
Category
Technology
-
view
1.520 -
download
0
description
Transcript of Role_Based_Permissions
Role Based PermissionsRuby on Rails way
Eric Sun7/26/2008
Why Roles?
Why Permissions?
Why Role based ?
John
Manager (Role)
Adan
JamesAdd
Edit
Del
UML Dialog
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
Trikr Demo
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
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
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
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
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
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’})
Step 4: Inherit mechanism
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 | +‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
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
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
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
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
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
Email:yundong.sun[AT]trikr.com在线项目管理软件 http://www.trikr.com