Devise + CanCan simply prevents others from editing objects

How would you prohibit other users from editing an object, say, a profile object that does - does not belong to itself?

Most online examples are complexes with several user roles, I could not get this work, it should be simple:

def initialize(user) can :update, Profile do |profile| profile.try(:user) == current_user end end 

And inside my ProfilesController # edit

 authorize! :update, @profile 
+4
source share
3 answers

First question: have you contributed your roles to User ?

application / models / user.rb

 class User < ActiveRecord::Base attr_accessible :email, :password, :remember_me devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, # regular devise stuff before_create :setup_default_role_for_new_users ROLES = %w[admin default banned] private def setup_default_role_for_new_users if self.role.blank? self.role = "default" end end end 

As you can see, I have 3 different roles, and when a new user is created, they are always default users. Now, with the CanCan setting, let's say you wanted admin be able to do everything, default users could do everything with their own profiles, banned users can't do anything, and guest users can see profiles:

 class Ability include CanCan::Ability # Remember that CanCan is for a resource, meaning it must have a class(model). def initialize(user) user ||= User.new # guest user (not logged in) if user.role == "admin" can :manage, :all elsif user.role == "default" can :manage, Profile, :user_id => user.id elsif user.role == "banned" cannot :manage, :all else can :read, Profile # guest user end end end 

So, as you allow users to edit only their own profiles, and no one elses.


Other useful notes: Make sure the user_id column is in the Profile table. Also, if you might need to guess that users see these profiles:

 class ProfileController < ApplicationController before_filter :authenticate_user!, :except => :show load_and_authorize_resource end 

They will not be able to use any other action, and CanCan still verifies authentication for everything else but show .

Good luck


UPDATE: Creating a role attribute for users

I performed a migration that would add a role column to the Devise users table:

 rails generate migration add_role_to_users role:string 

And then rake db:migrate . The new migration file should look like this, and also check the db / schema.rb file to make sure that it is separate from the user table correctly. If it is not then rake db:drop , then rake db:create , and then rake db:migrate again.

 class AddRoleToUsers < ActiveRecord::Migration def self.up add_column :users, :role, :string end def self.down remove_column :users, :role end end 

This is how you successfully do the work of user.role .

Note. Make sure you leave the line: can :manage, Profile, :user_id => user.id as is unchanged. It should work after adding the role column to User .

IMPORTANT! If you use Rails 3, DO NOT MAKE the role attr_accessible or everyone can edit their roles! Rails 4 uses Strong Parameters by default and does not affect this problem, since you can select the allowed parameters.

+12
source

Give something like this a try ...

 can :update, Profile, :user_id => user.id 
+4
source

UPDATE

It seems that the above code examples are correct. After reading all the documents cancan rtfm; p I found out about the role column you need to add.

Due to the fact that I have created an action to update the profile, it seems that CanCan does not work! I decided as shown below:

  def edit @profile = Profile.find params[:id] what = params[:what] if can? :update, @profile if ["basics", "location", "details", "photos", "interests"].member?(what) render :action => "edit_#{what}" else render :action => "edit_basics" end else raise CanCan::AccessDenied.new("Not authorized!", :update, Profile) end end 

This may not be the cleanest way, but the only way to make it work. Any suggestions for improvements are welcome, I have

  load_and_authorize_resource 

Internal Profile Controller! Possibly a mistake

0
source

Source: https://habr.com/ru/post/1383970/


All Articles