If my app uses AJAX to submit a user's message
to a server side speak
method that has no need for a controller (and therefore no space to write a before_filter
), how would I implement behavior that restricts users
who are not a part of that conversation
from submitting messages through the browser console?
If I open my app and type App.messages.speak("hi", #guess random number#)
that message is submitted to the conversation whether they are a part of it or not.
messages_channel.rb
class MessagesChannel < ApplicationCable::Channel
def speak(data)
Message.create! body: data['body'], conversation_id: data['conversation_id'], user_id: current_user.id
end
end
messages.coffee
App.messages = App.cable.subscriptions.create "MessagesChannel",
speak: (body, conversation_id) ->
@perform 'speak', body: body, conversation_id: conversation_id
submit_message = () ->
$('#response').on 'keydown', (event) ->
if event.keyCode is 13
conversation_id = $("[data-conversation-id]").data("conversation-id")
App.messages.speak(event.target.value, conversation_id)
event.target.value = ""
event.preventDefault()
I'm thinking I could remove the conversation_id
param from the speak
method and set it elsewhere that isn't dependent on user input? Currently I have it set as a data attribute, which means people could still mess with it.
Solved it with a callback.
class Message < ApplicationRecord
before_create :exclude_non_participants
def exclude_non_participants
if conversation.participates?(user)
true
else
throw :abort
end
end
end
participates?(user)
in this case is:
class Conversation < ApplicationRecord
def participates?(user)
sender == user || receiver == user
end
end
If there's a better way to do this, please let me know. For now, I think this works?