我正在尝试将授权添加到已经存在的相当大的应用程序中,但我必须稍微模糊一些细节。
以下是背景资料:
在我们的应用程序中,我们有一些或多个层次结构的角色,大致如下:
BasicUser -> SuperUser -> Admin -> SuperAdmin
对于授权,每个用户模型实例都有一个与上面对应的属性“role”。
我们有一个在Backoffice下命名空间的RESTful控制器“Users”。所以简而言之就是Backoffice :: UsersController。
class Backoffice::UsersController < ApplicationController
filter_access_to :all
#... RESTful actions + some others
end
所以这就是问题:
我们希望用户能够为用户提供编辑用户的权限,但前提是他们的角色比目前的“小”。我在authorization_rules.rb
中创建了以下内容authorization do
role :basic_user do
has_permission_on :backoffice_users, :to => :index
end
role :super_user do
includes :basic_user
has_permission_on :backoffice_users, :to => :edit do
if_attribute :role => is_in { %w(basic_user) }
end
end
role :admin do
includes :super_user
end
role :super_admin do
includes :admin
end
end
不幸的是,据我所知,规则似乎没有得到应用。
我还尝试了if_attribute上的几个变体:
if_attribute :role => is { 'basic_user' }
if_attribute :role => 'basic_user'
他们也会得到同样的效果。有人有什么建议吗?
答案 0 :(得分:4)
我相信你现在已经解决了这个问题,但我们遇到了类似的问题并找到了可能有所帮助的解决方案。可能无法仅在声明性授权DSL中处理此案例,但您可以利用DSL在模型和视图中执行正确的操作。基本上,我们需要访问角色层次结构图。
线索是declarative_authorization有一个漂亮的控制器,它生成一个显示角色层次结构的图表。使用相同的支持代码,您可以轻松访问任何角色的祖先:
class Role < ActiveRecord::Base
require 'declarative_authorization/development_support/analyzer'
has_many :assignments
has_many :users, :through => :assignments
validates :name, :presence => true
validates :name, :uniqueness => true
def ancestors
Authorization::DevelopmentSupport::AnalyzerEngine::Role.for_sym(self.name.to_sym,
Authorization::Engine.instance).ancestors.map { |r| r.instance_variable_get("@role") }
end
def self_and_ancestors
ancestors << self.name.to_sym
end
end
然后,您可以使用此选项来执行仅在用户编辑器中提供与current_user角色相同或较差的角色选择,并拒绝访问或不允许将模型更改为试图不恰当地提升用户的人。它在声明性授权DSL本身的上下文中没有那么有用,因为它需要首先被解析,创建一种循环引用。
希望这可以帮助那些需要它的人。
答案 1 :(得分:0)
我的应用程序中有以下方法,它可以正常工作
role :super_user do
includes :basic_user
has_permission_on :backoffice_users do
to :edit
if_attribute :role => is {"basic_user"}
end
end