Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CanCanCan: authorize/unauthorize specific model attributes

I've been fiddling with CanCanCan gem to limit a regular user's actions, but so far I only managed to limit authorizations to a whole model, and what I really need is to limit access to some of its attributes.

For example, on my User model, besides the user/password/email stuff, I have a boolean for admin, which I use to validate the status of the logged user, in which case if user.admin?, it can access/manage everything, else, it should be able to read all, and can only update its own record if the user.id matches.

I've read the documentation through and through for many times, the closest I got was adding this to app/models/ability.rb

can :update, :users, [:name, :password, :email]

which doesn't do anything .

So,

The problem: The user can either :update the whole model, or just :read it, I can't set it to :update or :read on specific attributes.

What I need: The user to able to :edit only specific attributes.

The question: What is the correct syntax to limit attributes? Is there any other configuration I must set on some other files?

My Ability.rb file:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.admin?
      can :manage, :all
      can :import, [User, Enclosure, Blade, Component]
    else
      can :access, :rails_admin
      can :dashboard
      can :read, :all
      can :history, :all
      # Allows user to only edit an enclosure, if it's allocated to itself, or not allocated at all
      can :update, Enclosure do |enclosure|
        can :update, Enclosure if (enclosure.allocated_to == user.email && enclosure.allocation == true) || enclosure.allocation == false
      end 
    end    
  end
end

Gems I'm using (besides the default Rails 4 gems):

# Administration Panel Gems
gem 'rails_admin'                    # Rails Administration Panel Gem
gem 'rails_admin_history_rollback'   # Enables users to visualize and revert history
gem 'rails_admin_import', "~> 1.0.0" # Enables importing
gem 'devise'                         # Authentication Gem
gem 'cancancan'                      # Authorization Gem
gem 'paper_trail', '~> 4.0.0.rc'     # Auditing Gem (History)

Thank you!

like image 265
Filipe Gorges Reuwsaat Avatar asked Nov 27 '25 10:11

Filipe Gorges Reuwsaat


1 Answers

I think you should use strong parameters. This gem lets you choose which parameters do you want to be updated. If you are using Rails 4, the gem is already installed, otherwise you can install it.

class UsersController < ApplicationController
  load_and_authorize_resource

  def update
    if @user.update_attributes(update_params)
      # hurray
    else
      render :edit
    end
  end

  private

  def update_params
    if current_user.admin?
      params.require(:user).permit(:user, :email, :password, :admin)
    else
      params.require(:user).permit(:user, :email, :password)
    end
  end
end
like image 124
Andrici Cezar Avatar answered Nov 30 '25 00:11

Andrici Cezar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!