diff --git a/engine/app/channels/coplan/plan_presence_channel.rb b/engine/app/channels/coplan/plan_presence_channel.rb index e6ee4a8a..31235cc7 100644 --- a/engine/app/channels/coplan/plan_presence_channel.rb +++ b/engine/app/channels/coplan/plan_presence_channel.rb @@ -40,7 +40,7 @@ def current_user def resolve_current_user return connection.current_user if connection.respond_to?(:current_user) && connection.current_user - CoPlan::Authentication.user_from_request(connection.request) + CoPlan::Authentication.user_from_request(connection.__send__(:request)) end def broadcast_viewers diff --git a/spec/channels/coplan/plan_presence_channel_spec.rb b/spec/channels/coplan/plan_presence_channel_spec.rb index 9e7da87f..9d1916dc 100644 --- a/spec/channels/coplan/plan_presence_channel_spec.rb +++ b/spec/channels/coplan/plan_presence_channel_spec.rb @@ -30,6 +30,29 @@ expect(CoPlan::PlanViewer.where(plan: plan, user: websocket_user)).to exist end + it "authenticates through the engine callback when ActionCable keeps the request private" do + request = ActionDispatch::Request.empty + private_request_connection = Class.new do + def initialize(request) + @request = request + end + + private + + attr_reader :request + end.new(request) + channel = described_class.allocate + allow(channel).to receive(:connection).and_return(private_request_connection) + allow(CoPlan.configuration).to receive(:authenticate).and_return( + ->(received_request) { { external_id: "private-request-user", name: received_request.object_id.to_s } } + ) + + websocket_user = channel.send(:resolve_current_user) + + expect(websocket_user.external_id).to eq("private-request-user") + expect(websocket_user.name).to eq(request.object_id.to_s) + end + it "rejects when plan does not exist" do subscribe(plan_id: "nonexistent") expect(subscription).to be_rejected