Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 ActiveAdmin CanCan. How to setup that User should only see records that belong to him?

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
like image 806
leonel Avatar asked Jan 20 '12 00:01

leonel


2 Answers

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

like image 194
David Underwood Avatar answered Nov 11 '22 05:11

David Underwood


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
like image 36
Scott Avatar answered Nov 11 '22 03:11

Scott