At the moment, any logged in user can go to http://localhost:3000/notes/note_id and view the note there. How do I restrict this so that you can only see notes that belong to you? Thanks for reading.
views:
59answers:
4In the NotesController #show action, redirect or show a permission denied error if the user_id on the note doesn't == the logged in user id.
Another solution is to put this code in a before_filter in the NotesController, since the same validation is performed for the #edit and #delete methods.
Edit: Putting all the suggestions together (Sorry if this has been confusing):
Edit2: Using Veeti's association answer, which I always seem to forget, we can add current_user.notes.find() to the mix. Like he said, your current_user needs to return a User object, and you'll need a has_many :notes in your User model.
class NotesController < ApplicationController
before_filter :check_ownership, :except => [:new, :create, :index]
#.. new, create, index, show, edit, delete actions
private
def check_ownership
redirect_to :back unless current_user.notes.find(params[:id])
end
end
I like using acl9
as an authentication which has a the concept of an object owner
. Then you can put in a line like
access_control do
allow :owner, :of => :note, :to => [:show, :edit, :update]
end
See http://wiki.github.com/be9/acl9/tutorial-securing-a-controller (in particular, step 4) for more details.
If you don't want to use a plugin, Jon's solution makes sense.
The best way to achieve this is using before_filter. You can read about the details, but essentially, it runs a method before the action is called. In this method, you can check to see if the person attempting access to the note actually has permission to do so. Another good thing about this approach is that you can put the method in ApplicationController, lib/, etc, and add the before_filter to whatever controllers or actions need it. Here's a simple example:
application_controller.rb:
class ApplicationController < ActionController:Base
def verify_note_permission
current_user.id == Note.find(params[:id]).user_id or redirect_to :back
end
notes_controller.rb
class NotesController < ApplicationController
before_filter :verify_note_permission
...
end
This will check to ensure the current user's id matches the ID on the document, or it redirects back to wherever they came from. You could also add flash messages here along with a custom check for permissions implemented in the model. (Probably belongs in the model anyways).
Assuming that you have a method called current_user
which returns the current User
, you could use the Note
relationship on the User
to only search for a note of theirs with the specified ID, so instead of:
@note = Note.find(params[:id])
do
@note = current_user.notes.find(params[:id])
(Of course, you will need to specify associations in your models.)