Zero
Zero

Reputation: 151

How to fix Insufficient Authorization in Rails?

I was working on a simple messaging app using Dana Mulder's tutorial at https://medium.com/@danamulder/tutorial-create-a-simple-messaging-system-on-rails-d9b94b0fbca1#.xjhgikji4 However after being able to get a working system I realized that any user can see other user messages by playing around with the url.

For example users can iterate the number in this url http://localhost:3000/conversations/3/messages and see all other messages where they are not a part of. I was trying to add some protection without luck. Would anybody know how to fix the insufficient authorization issue for this application? Thanks!.

Here is my conversations_controller.rb

class ConversationsController < ApplicationController
  before_action :confirm_logged_in
  layout 'authenticated'

  def index
    @users = User.all
    @conversations = Conversation.all
  end

  def create
    if Conversation.between(params[:sender_id],params[:recipient_id]).present?
      @conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
    else
      @conversation = Conversation.create!(conversation_params)
    end
    redirect_to conversation_messages_path(@conversation)
  end

  private
  def conversation_params
    params.permit(:sender_id, :recipient_id)
  end
end

Here is the messages_controller.rb

class MessagesController < ApplicationController

  layout 'authenticated'
  before_action do
    @conversation = Conversation.find(params[:conversation_id])
  end

  def index
    @messages = @conversation.messages
    if @messages.length > 10
      @over_ten = true
      @messages = @messages[-10..-1]
    end
    if params[:m]
      @over_ten = false
      @messages = @conversation.messages
    end
    if @messages.last
      if @messages.last.user_id != current_user.id
        @messages.last.read = true;
      end
    end

    @message = @conversation.messages.new
  end

  def new
    @message = @conversation.messages.new
  end

  def create
    @message = @conversation.messages.new(message_params)
    if @message.save
      redirect_to conversation_messages_path(@conversation)
    end
  end

  private
  def message_params
    params.require(:message).permit(:body, :user_id)
  end
end

Upvotes: 0

Views: 87

Answers (1)

Long Nguyen
Long Nguyen

Reputation: 11275

I assume that in your model design, User has many conversions current_user is object represent currently logged-in user. You can limit conversation that he can view to only conversation that belong to him by this query:

@conversation = Conversation.where("(sender_id = ? OR recipient_id =?) AND id = ?", current_user.id, current_user.id, params[:conversation_id]).first

instead of @conversation = Conversation.find(params[:conversation_id]), which will get any Conversation he passed into param conversation_id.

Upvotes: 1

Related Questions