[英]Using declarative_authorization to limit results in the model
我正在使用声明性授权 gem 来获取 rails 项目中的权限,并且我正在尝试根据用户权限从 model 中限制 output。
我的缩写授权文件如下所示:
roles do
role :supervisor
has_permission_on :people, :to => :manage_all
end
role :basic_user
has_permission_on :people, :to => :manage_subordinates
end
end
privileges do
privilege :manage_subordinates do
includes :subordinate_records
end
privilege :manage_all do
includes :all_records
end
end
在我的人 model 中,我有一个 static 方法,我想看起来像这样
def self.supervised_by(user)
if user.permitted_to? :all_records
#return all of the records
elsif user.permitted_to? :subordinate_records
#return some of the records
else
#return none of the records
end
end
使用 with_permissions_to 或 allowed_to 的文档中的 AuthorizationInModel object 似乎对此提供了支持。 我无法根据文档弄清楚如何使用这些功能,或者如何返回当前用户对当前 model 的权限列表。
有任何想法吗?
我找到了使用内置 if-attribute 方法的替代解决方案。 我最初远离它是因为我使用的是非命名空间模型和命名空间控制器和视图。 这个结构是我正在处理的项目的原始版本的一个工件。 我的大部分工作都获得了处理这种结构的声明性授权。
我不清楚的主要信息是如何在部分命名空间的环境中命名权限。 The model expected the model name (:people), the controller expected the namespace and the model (:staff_people), and the views didn't care as long as you picked one. 我选择的解决方案是使用 model 名称并在每个 controller 中显式设置上下文。 如果在 controller 中未设置上下文,则使用 filter_access_to 不起作用,因为它会寻找 staff_people 权限而不是正确的权限 people。
在声明性授权配置文件中,我将完全权限授予管理员,部分权限授予主管。 person.supervised 返回其自身和所有其他受监督人员的数组。
roles do
role :administrator
has_permission_on :people, :to => [:create, :read, :update, :delete]
end
role :supervisor
has_permission_on :people do
to => [:create, :read, :update, :delete]
if_attribute :id => is_in { Person.find_by_user_id(user.id).supervised }
end
end
end
要在命名空间 controller 中访问此信息,我使用的是 filer_resource_access。
module Staff
class PeopleController < ApplicationController
filter_resource_access :context => :people
def index
@people = People.with_permissions_to(:read)
end
我发现使用
filter_access_to :all, :with_attribute => true
不适用于需要使用 with_permissions_to 和 if_attribute 权限的方法。 我不知道为什么这是一个问题
对于不包括获取单个记录的 id 作为 arguments 的一部分的非标准 controller 操作,仍然需要使用 filter_access_to。 例如,如果一个名为 part_timers 的操作返回一个人员列表,那么这个解决方案似乎应该可以工作:
filter_resource_access :context => :people, :additional_member => { :part_timers => :read }
正确的解决方案是保持 filter_resource_access 原样并为该操作添加 filter_access_to
filter_resource_access :context => :people
fitler_access_to :part_timers, :required => :read, :context => people
可能有更好的方法来做到这一点,但如果其他一切设置正确,这应该适用于您的supervised_by
方法。
def self.supervised_by(user)
if Person.new.permitted_to? :all_records, :user=>user
#return all of the records
elsif Person.new.permitted_to? :subordinate_records, :user=>user
#return some of the records
else
#return none of the records
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.