Properly reject invalid ActionCable subscriptions

Previously, we were not properly rejecting the submission, so that the channel name was still evaluated (leading to errors). Now, we handle these cases as well.

Fixes CODEOCEAN-V2
This commit is contained in:
Sebastian Serth
2023-09-30 17:22:27 +02:00
parent 42b0507cd6
commit 2f97c0357c
3 changed files with 52 additions and 20 deletions

View File

@ -2,7 +2,10 @@
class LaExercisesChannel < ApplicationCable::Channel class LaExercisesChannel < ApplicationCable::Channel
def subscribed def subscribed
stream_from specific_channel set_and_authorize_exercise
set_and_authorize_study_group
stream_from specific_channel unless subscription_rejected?
end end
def unsubscribed def unsubscribed
@ -12,7 +15,20 @@ class LaExercisesChannel < ApplicationCable::Channel
private private
def specific_channel def specific_channel
reject unless StudyGroupPolicy.new(current_user, StudyGroup.find(params[:study_group_id])).stream_la? "la_exercises_#{@exercise.id}_channel_study_group_#{@study_group.id}"
"la_exercises_#{params[:exercise_id]}_channel_study_group_#{params[:study_group_id]}" end
def set_and_authorize_exercise
@exercise = Exercise.find(params[:exercise_id])
reject unless ExercisePolicy.new(current_user, @exercise).implement?
rescue ActiveRecord::RecordNotFound
reject
end
def set_and_authorize_study_group
@study_group = @exercise.study_groups.find(params[:study_group_id])
reject unless StudyGroupPolicy.new(current_user, @study_group).stream_la?
rescue ActiveRecord::RecordNotFound
reject
end end
end end

View File

@ -3,7 +3,8 @@
class PgMatchingChannel < ApplicationCable::Channel class PgMatchingChannel < ApplicationCable::Channel
def subscribed def subscribed
set_and_authorize_exercise set_and_authorize_exercise
stream_from specific_channel
stream_from specific_channel unless subscription_rejected?
end end
def unsubscribed def unsubscribed
@ -13,10 +14,6 @@ class PgMatchingChannel < ApplicationCable::Channel
stop_all_streams stop_all_streams
end end
def specific_channel
"pg_matching_channel_exercise_#{@exercise.id}"
end
def waiting_for_match def waiting_for_match
@current_waiting_user = PairProgrammingWaitingUser.find_or_initialize_by(user: current_user, exercise: @exercise) @current_waiting_user = PairProgrammingWaitingUser.find_or_initialize_by(user: current_user, exercise: @exercise)
@current_waiting_user.status_waiting! @current_waiting_user.status_waiting!
@ -40,8 +37,14 @@ class PgMatchingChannel < ApplicationCable::Channel
ActionCable.server.broadcast(specific_channel, {action: 'joined_pg', users: pg.users.map(&:to_page_context)}) ActionCable.server.broadcast(specific_channel, {action: 'joined_pg', users: pg.users.map(&:to_page_context)})
end end
def specific_channel
"pg_matching_channel_exercise_#{@exercise.id}"
end
def set_and_authorize_exercise def set_and_authorize_exercise
@exercise = Exercise.find(params[:exercise_id]) @exercise = Exercise.find(params[:exercise_id])
reject unless ExercisePolicy.new(current_user, @exercise).implement? reject unless ExercisePolicy.new(current_user, @exercise).implement?
rescue ActiveRecord::RecordNotFound
reject
end end
end end

View File

@ -2,7 +2,10 @@
class SynchronizedEditorChannel < ApplicationCable::Channel class SynchronizedEditorChannel < ApplicationCable::Channel
def subscribed def subscribed
stream_from specific_channel set_and_authorize_exercise
authorize_programming_group
stream_from specific_channel unless subscription_rejected?
# We generate a session_id for the user and send it to the client # We generate a session_id for the user and send it to the client
@session_id = SecureRandom.uuid @session_id = SecureRandom.uuid
@ -28,17 +31,6 @@ class SynchronizedEditorChannel < ApplicationCable::Channel
ActionCable.server.broadcast(specific_channel, message) ActionCable.server.broadcast(specific_channel, message)
end end
def specific_channel
reject unless ProgrammingGroupPolicy.new(current_user, programming_group).stream_sync_editor?
"synchronized_editor_channel_group_#{programming_group.id}"
rescue NoMethodError => e
Sentry.capture_exception(e, extra: {current_user:, programming_group:, session_id: @session_id, identifier: @identifier})
end
def programming_group
current_contributor if current_contributor.programming_group?
end
def editor_change(message) def editor_change(message)
change = message.deep_symbolize_keys change = message.deep_symbolize_keys
@ -63,6 +55,16 @@ class SynchronizedEditorChannel < ApplicationCable::Channel
ActionCable.server.broadcast(specific_channel, message) ActionCable.server.broadcast(specific_channel, message)
end end
private
def specific_channel
"synchronized_editor_channel_group_#{programming_group.id}"
end
def programming_group
current_contributor if current_contributor.programming_group?
end
def create_message(action, status) def create_message(action, status)
{ {
action:, action:,
@ -80,4 +82,15 @@ class SynchronizedEditorChannel < ApplicationCable::Channel
session_id: @session_id, session_id: @session_id,
} }
end end
def set_and_authorize_exercise
@exercise = Exercise.find(params[:exercise_id])
reject unless ExercisePolicy.new(current_user, @exercise).implement?
rescue ActiveRecord::RecordNotFound
reject
end
def authorize_programming_group
reject unless ProgrammingGroupPolicy.new(current_user, programming_group).stream_sync_editor?
end
end end