使用 declarative_authorization 限制模型中的结果

发布于 2024-11-04 17:32:54 字数 864 浏览 0 评论 0原文

我在 Rails 项目中使用声明性授权 gem 来获取权限,并尝试根据用户权限限制模型的输出。

我的缩写授权文件如下所示:

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

在我的人员模型中,我有一个静态方法,我希望它看起来像这样

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

看起来使用文档中的 AuthorizationInModel 对象使用 with_permissions_to 或 allowed_to 对此提供支持。我无法根据文档弄清楚如何使用这些函数或如何返回当前模型上当前用户的权限列表。

有什么想法吗?

I am using the declarative authorization gem for permissions in a rails project and I am trying to limit output from the model based on user permissions.

My abbreviated authorization file looks like this:

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

In my people model, I have a static method that I want to look like this

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

It looks like there is support for this using the AuthorizationInModel object in the documentation using with_permissions_to or permitted_to. I haven't been able to figure out how to use those functions based on the documentation or how to return a list of the current user's privileges on the current model.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

当爱已成负担 2024-11-11 17:32:54

我找到了使用内置 if-attribute 方法的替代解决方案。我最初放弃它是因为我使用的是非命名空间模型和命名空间控制器和视图。该结构是我正在从事的项目的原始版本的工件。我的大部分工作都是获得处理这种结构的声明性授权。

我不清楚的主要信息是如何在部分命名空间环境中命名权限。模型需要模型名称 (:people),控制器需要命名空间和模型 (:staff_people),而视图并不关心,只要您选择一个即可。我选择的解决方案是使用模型名称并在每个控制器中显式设置上下文。如果控制器中未设置上下文,则使用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

为了在命名空间控制器中访问此信息,我使用 filer_resource_access。

module Staff
  class PeopleController < ApplicationController
    filter_resource_access :context => :people

    def index
      @people = People.with_permissions_to(:read)
    end

我发现 using

filter_access_to :all, :with_attribute => true

对于需要使用 with_permissions_to 和 if_attribute 权限的方法不起作用。我不确定为什么这是一个问题

对于不包含获取单个记录作为参数一部分的 id 的非标准控制器操作,仍然有必要使用 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

I found an alternative solution using the built in if-attribute method. I originally moved away from it because I was using non-namespaced models and namespaced controllers and views. This structure is an artifact form the original version of the project I am working on. Most of my work has been getting declarative authorization to deal with this structure.

The major piece of information that was not clear to me was how to name the permissions in a partially namespaced environment. 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. The solution I picked was to use the model name and explicitly set the context in every controller. If the context is not set in the controller, using filter_access_to does not work because it would be looking for the staff_people permission rather than the correct permission, people.

In the declarative authorization config file, I am giving full permissions to administration and partial permissions to supervisor. person.supervised returns an array of itself and all other supervised people.

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

To access this information in a Namespaced controller, I am using filer_resource_access.

module Staff
  class PeopleController < ApplicationController
    filter_resource_access :context => :people

    def index
      @people = People.with_permissions_to(:read)
    end

I found that using

filter_access_to :all, :with_attribute => true

did not work for methods that need to use with_permissions_to and an if_attribute permission. I am not sure why this was a problem

It is still necessary to use filter_access_to for nonstandard controller actions that do not include an id fetching a single record as part of the arguments. For example, if an action called part_timers returns a list of people, this solution seems like it should work:

filter_resource_access :context => :people, :additional_member => { :part_timers => :read }

The correct solution is to keep the filter_resource_access as is and add a filter_access_to for that action

filter_resource_access :context => :people
fitler_access_to :part_timers, :required => :read, :context => people
听,心雨的声音 2024-11-11 17:32:54

可能有更好的方法来做到这一点,但如果其他一切设置正确,这应该适用于您的 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

There may be a better way to do this but this should work for your supervised_by method if everything else is setup right.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文