4

I'm using Devise for the first time with rails, and I'm having trouble with one thing: I used the provided authenticate_user! method in my user's controller to restrict access to pages like so: before_filter :authenticate_user!, :only => [:edit, :show, :update, :create, :destroy]

But this allows any signed in user to access any other users :edit action, which I want to restrict to only that user. How would I do that?

ankit
  • 3,328
  • 3
  • 26
  • 39

2 Answers2

5

In your edit method, you need to do a check to see if the user owns the record:

def edit
   @record = Record.find(params[:id])
   if @record.user == current_user
      @record.update_attributes(params[:record])
   else
      redirect_to root_path
   end
end
Dex
  • 12,527
  • 15
  • 69
  • 90
  • Hi, I just tried this. I get the following error: `uninitialized constant UsersController::Record` Also I find it really surprising that a well developed authentication method like this doesn't have direct support for something like this. – ankit Jul 26 '11 at 12:19
  • Just to clarify, this is what I did: `private def verify_ownership @record = Record.find(params[:id]) if @record.user == current_user return true else return false end` and then I use a `before_filter` at the top of my controller – ankit Jul 26 '11 at 12:25
  • replace `Record` with whatever your actual model name is. I am also assuming that your model has a `user_id` column. You can use CanCan or Declarative Authentication with this. Or just use if-then-else statements to ensure proper permissions. Devise handles authentications, not roles. – Dex Jul 26 '11 at 12:25
  • I tried replacing `Record` with `User`, and then I check if `@record == current_user`, but for some reason this still allows any user to edit any other user's records – ankit Jul 26 '11 at 12:28
  • Forget what I said about a `before_filter`, you need to redirect instead of returning true/false. Take the code out and put it in the actual method. – Dex Jul 26 '11 at 12:31
3

You should look into Authorization such as CanCan. Or alternatively create a new method like so:

# Create an admin boolean column for your user table.

def authenticate_admin!
  authenticate_user! and current_user.admin?
end
Zach Inglis
  • 1,242
  • 1
  • 14
  • 28
  • I think you misunderstood my question. I don't need administrator users who can edit any user's records. I just need to restrict users to be able to modify only their own records. – ankit Jul 26 '11 at 12:20
  • He did misunderstand it a little but you should still look into using CanCan. You're looking for Authorization and CanCan does it wonderfully. – pcg79 Jul 26 '11 at 13:44