0

I'm using Ruby on rails with devise. I generated a scaffold.

tasks_controller.rb:

def index
   @tasks= current_user.tasks
end

By using this, I'm able to show the people only what they have created, but other users can see the data of tasks that they have not entered, like:

GET /tasks/1
GET /tasks/2

Although the tasks with id 1 is not created by the current_user, the user can access that.

hoijui
  • 3,615
  • 2
  • 33
  • 41
Ninja Boy
  • 1,112
  • 3
  • 14
  • 28

3 Answers3

2

Yes you can restrict this using filters e.g.

 class TasksController < ApplicationController
    before_filter :user_can_view_task, only: :show

    def show
       #you do not need to set @task here as it will be set by the filter method
    end

    private
       def user_can_view_task
          @task = Task.find(params[:id])
          unless @task.user_id == current_user.id
            flash[:notice] = "You may only view Tasks you have created."
            redirect_to(tasks_path)
          end 
       end
 end

Every time a User hits the route for the show view it will execute this method prior to rendering the view. (Thus "before")

This method will look up the task and determine if the current_user created the task (assuming associations between User and Task). If the user is not the task creator it will redirect them back to the index view and inform them that they can only view tasks they have created rather than allowing them to access the show.

engineersmnky
  • 25,495
  • 2
  • 36
  • 52
0

Try:

def show
  @task = current_user.tasks.find(params[:id])
  # or with error handling
  # begin
  #   @task = current_user.tasks.find(params[:id])
  # rescue
  #   redirect_to [:tasks], flash: { error: 'not authorized' }
  #   return
  # end
end
Jacob Brown
  • 7,221
  • 4
  • 30
  • 50
0

There is Pundit gem(https://github.com/elabs/pundit) for these cases. Your code will look:

class TaskPolicy
  attr_reader :user, :task

  def initialize(user, task)
    @user = user
    @task = task
  end

  def show?
    user.tasks.include? task
  end
end

And your controller's action:

def show
  @task = Task.find(params[:id])
  authorize @task
  ...
end

This action will raise Pundit::NotAuthorizedError if current user hasn't certaint task

Sergei Stralenia
  • 855
  • 7
  • 16
  • It's fine, but def show? user.tasks.include? task what does it do? I want to restrict the user, like if you created a task only you can view it. and also i'm getting unable to find policy `TaskPolicy` for ` error. Kindly help me out @SergeiStralenia and btw, any reference on how to write policies for pundit, kindly attach – Ninja Boy Oct 15 '15 at 16:20
  • @th3lazytig3r, you should install gem pundit. Then invoke 'rails g pundit:install'. This script will create app/policies directory in your project. Then create task_policy.rb file and insert my task policy code. Modify your show action. And last insert 'include Pundit' in your application controller. And everything will work. – Sergei Stralenia Oct 15 '15 at 16:33