Rails 3 ActiveAdmin CanCan。如何设置该用户只能看到属于他的记录?

发布于 2024-12-27 23:38:50 字数 1752 浏览 3 评论 0原文

我设置了属于客户类别的 admin_users (客户是一家公司)。所以客户有很多admin_users。

我正在尝试限制对属于特定客户的发货记录的访问。我不希望客户查看其他客户的数据。所以我设置了这个,但它似乎没有任何作用......

类能力 include CanCan::Ability

  def initialize(user)
    user ||= AdminUser.new       
    if user.role == "administrator"
        can :manage, :all
    else
      cannot :create, :all
      cannot :update, :all
      cannot :destroy, :all
      can :read, Shipment do |shipment|
        shipment.customer == user.customer
      end
    end
  end 
end

我确实在shipments.rb中有这个...

ActiveAdmin.register Shipment do
  menu :if => proc{ can?(:read, Shipment) }, :priority => 1
  controller.authorize_resource

  index do
    column "File #", :sortable => :file_number do |shipment|
      link_to shipment.file_number, admin_shipment_path(shipment)
    end
    [... more columns ...]
    default_actions if can? :manage, Shipment
  end

  show :title => :file_number do
  panel "Shipment Details" do
  attributes_table_for shipment do
    row("File number") {shipment.file_number}
    row("Mode") {shipment.mode}
    row("Ocean Rate") { number_to_currency shipment.ocean_rate}
    row("Customer") { link_to shipment.customer.company_name, admin_customer_path(shipment.customer)}
    row("Shipper") { link_to shipment.shipper.company_name, admin_shipper_path(shipment.shipper)}
    row("Broker") { link_to shipment.broker.company_name, admin_broker_path(shipment.broker)}
  end
end

[...more show action stuff...]

所以在索引页面中,所有货件都会显示,如果我以客户A身份登录并单击客户B的货件我可以看到它,但它是应该阻止我。

更多信息...

shipments_controller.rb
class ShipmentsController < InheritedResources::Base
  before_filter :authenticate_admin_user!
end

I setup admin_users that belongs to a customer class (Customer is a company). So Customer has many admin_users.

I'm trying to restrict access to Shipment records that belongs to a certain customer. I don't want customers watching other customers data. So I set this up but it seems to do nothing...

class Ability
include CanCan::Ability

  def initialize(user)
    user ||= AdminUser.new       
    if user.role == "administrator"
        can :manage, :all
    else
      cannot :create, :all
      cannot :update, :all
      cannot :destroy, :all
      can :read, Shipment do |shipment|
        shipment.customer == user.customer
      end
    end
  end 
end

And I do have this in shipments.rb ...

ActiveAdmin.register Shipment do
  menu :if => proc{ can?(:read, Shipment) }, :priority => 1
  controller.authorize_resource

  index do
    column "File #", :sortable => :file_number do |shipment|
      link_to shipment.file_number, admin_shipment_path(shipment)
    end
    [... more columns ...]
    default_actions if can? :manage, Shipment
  end

  show :title => :file_number do
  panel "Shipment Details" do
  attributes_table_for shipment do
    row("File number") {shipment.file_number}
    row("Mode") {shipment.mode}
    row("Ocean Rate") { number_to_currency shipment.ocean_rate}
    row("Customer") { link_to shipment.customer.company_name, admin_customer_path(shipment.customer)}
    row("Shipper") { link_to shipment.shipper.company_name, admin_shipper_path(shipment.shipper)}
    row("Broker") { link_to shipment.broker.company_name, admin_broker_path(shipment.broker)}
  end
end

[...more show action stuff...]

So in the index page, all shipments get displayed and if I'm logged in as Customer A and click on Customer B's shipment I can see it, but it's supposed to block me.

More info...

shipments_controller.rb
class ShipmentsController < InheritedResources::Base
  before_filter :authenticate_admin_user!
end

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

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

发布评论

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

评论(4

铜锣湾横着走 2025-01-03 23:38:50

Active Admin 有一个内置的处理范围的方法。请参阅此处:http://activeadmin.info/docs/2-resource-customization。 html#scoping_the_queries

Active Admin has a built in method for handling scopes. See here: http://activeadmin.info/docs/2-resource-customization.html#scoping_the_queries

粉红×色少女 2025-01-03 23:38:50

我的应用程序中也有类似的问题。我有超级用户和管理员,其中管理员只能看到其组织中的其他管理员。

应用程序/模型/ability.rb

if user.organization_admin?
  can :manage, User, :organization_id => user.organization_id
end

应用程序/admin/users.rb

controller do load_and_authorize_resource :except => :index
  def scoped_collection
    end_of_association_chain.accessible_by(current_ability)
  end
end

I had a similar problem in my app. I had super_users and admins where the admins could only see other admins in their organization.

app/models/ability.rb

if user.organization_admin?
  can :manage, User, :organization_id => user.organization_id
end

app/admin/users.rb

controller do load_and_authorize_resource :except => :index
  def scoped_collection
    end_of_association_chain.accessible_by(current_ability)
  end
end
我不在是我 2025-01-03 23:38:50

我不知道为什么它不起作用,但是可以吗? :read, Shipment 不会查找 can :read, Shipment do |shipment| 的权限...

要验证此权限,您必须指定 Shipment 的特定实例,例如 can :read, @shipment

您需要找到一种方法来在您的 menu :if =>; 之前获取所访问的货件的实例。 ... 行被调用。


您是否尝试使用 controller.load_and_authorize_resource 而不是仅使用 authorize_resource

I don't know why it's not working, but can? :read, Shipment will not look up the permissions for can :read, Shipment do |shipment| ....

To validate against this permission you would have to specify a specific instance of a Shipment, like this can :read, @shipment.

You'll need to find a way to get the instance of the accessed shipment before your menu :if => ... line is called.


Did you try using controller.load_and_authorize_resource instead of only authorize_resource?

小耗子 2025-01-03 23:38:50

使用范围集合并运行取决于当前登录用户的查询

ActiveAdmin.register Shipment do
  controller do
    def scoped_collection
      my_scope = resource_class.unscoped
      return my_scope if current_admin_user.role == "administrator" # return everything
      my_scope.where(customer_id: current_admin_user.customer_id) # filter by signed in user
    end
  end
end

Use an scoped collection and run a query that depends on the current signed in user

ActiveAdmin.register Shipment do
  controller do
    def scoped_collection
      my_scope = resource_class.unscoped
      return my_scope if current_admin_user.role == "administrator" # return everything
      my_scope.where(customer_id: current_admin_user.customer_id) # filter by signed in user
    end
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文