From 7d248f2bc7a61430c91bb922f403b325601a1e9b Mon Sep 17 00:00:00 2001 From: Ahmad Farhat Date: Fri, 9 Aug 2024 16:11:51 -0400 Subject: [PATCH] Pass through user_id to BBB meeting (#5915) --- app/controllers/api/v1/meetings_controller.rb | 17 +++++++ app/services/big_blue_button_api.rb | 3 +- app/services/meeting_starter.rb | 6 ++- spec/controllers/meetings_controller_spec.rb | 46 ++++++++++++------- spec/services/meeting_starter_spec.rb | 2 + 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/app/controllers/api/v1/meetings_controller.rb b/app/controllers/api/v1/meetings_controller.rb index f0a68b5819..a0dddd6657 100644 --- a/app/controllers/api/v1/meetings_controller.rb +++ b/app/controllers/api/v1/meetings_controller.rb @@ -37,6 +37,7 @@ def start render_data data: BigBlueButtonApi.new(provider: current_provider).join_meeting( room: @room, name: current_user.name, + user_id: fetch_bbb_user_id, avatar_url: current_user.avatar.attached? ? url_for(current_user.avatar) : nil, role: 'Moderator' ), status: :created @@ -81,6 +82,7 @@ def status data[:joinUrl] = BigBlueButtonApi.new(provider: current_provider).join_meeting( room: @room, name: current_user ? current_user.name : params[:name], + user_id: fetch_bbb_user_id, avatar_url: current_user&.avatar&.attached? ? url_for(current_user.avatar) : nil, role: bbb_role ) @@ -145,6 +147,21 @@ def infer_bbb_role(mod_code:, viewer_code:, anyone_join_as_mod:) 'Viewer' end end + + def fetch_bbb_user_id + return "gl-#{current_user.id}" if current_user + + return cookies[:guest_id] if cookies[:guest_id].present? + + guest_id = "gl-guest-#{SecureRandom.hex(12)}" + + cookies[:guest_id] = { + value: guest_id, + expires: 1.day.from_now + } + + guest_id + end end end end diff --git a/app/services/big_blue_button_api.rb b/app/services/big_blue_button_api.rb index 21493fdbb6..495e1dacdf 100644 --- a/app/services/big_blue_button_api.rb +++ b/app/services/big_blue_button_api.rb @@ -44,12 +44,13 @@ def start_meeting(room:, options: {}, presentation_url: nil) end end - def join_meeting(room:, role:, name: nil, avatar_url: nil) + def join_meeting(room:, role:, user_id:, name: nil, avatar_url: nil) bbb_server.join_meeting_url( room.meeting_id, name, '', # empty password -> use the role passed ing { + userId: user_id, role:, avatarURL: avatar_url, createTime: room.last_session&.to_datetime&.strftime('%Q') diff --git a/app/services/meeting_starter.rb b/app/services/meeting_starter.rb index 99d95e3ffc..63009ffd2a 100644 --- a/app/services/meeting_starter.rb +++ b/app/services/meeting_starter.rb @@ -69,9 +69,11 @@ def computed_options(access_code:) logoutURL: room_url, meta_endCallbackUrl: meeting_ended_url(host: @base_url), 'meta_bbb-recording-ready-url': recording_ready_url(host: @base_url), - 'meta_bbb-origin-version': ENV.fetch('VERSION_TAG', 'v3'), 'meta_bbb-origin': 'greenlight', - 'meta_bbb-origin-server-name': URI(@base_url).host + 'meta_bbb-origin-server-name': URI(@base_url).host, + 'meta_bbb-origin-version': ENV.fetch('VERSION_TAG', 'v3'), + 'meta_bbb-context-name': @room.name, + 'meta_bbb-context-id': @room.friendly_id } end diff --git a/spec/controllers/meetings_controller_spec.rb b/spec/controllers/meetings_controller_spec.rb index 48aeec11d8..a4d1c6f67a 100644 --- a/spec/controllers/meetings_controller_spec.rb +++ b/spec/controllers/meetings_controller_spec.rb @@ -25,6 +25,8 @@ let(:test_user) { create(:user) } let(:test_room) { create(:room, user: test_user) } let(:user_with_manage_rooms_permission) { create(:user, :with_manage_rooms_permission) } + let(:user_id) { "gl-#{user.id}" } + let(:guest_user_id) { "gl-#{guest_user.id}" } before do request.headers['ACCEPT'] = 'application/json' @@ -43,7 +45,7 @@ it 'makes a call to the MeetingStarter service with the right values and returns the join url' do expect(MeetingStarter).to receive(:new).with(room:, base_url: request.base_url, current_user: user, provider: 'greenlight').and_call_original expect_any_instance_of(MeetingStarter).to receive(:call) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, user_id:, avatar_url: nil, role: 'Moderator') post :start, params: { friendly_id: room.friendly_id } @@ -61,7 +63,7 @@ it 'makes a call to the BigBlueButtonApi to get the join url' do expect_any_instance_of(BigBlueButtonApi) .to receive(:join_meeting) - .with(room:, name: user.name, avatar_url: nil, role: 'Moderator') + .with(room:, name: user.name, user_id:, avatar_url: nil, role: 'Moderator') post :start, params: { friendly_id: room.friendly_id } end @@ -72,7 +74,7 @@ expect_any_instance_of(BigBlueButtonApi) .to receive(:join_meeting) - .with(room:, name: user.name, avatar_url:, role: 'Moderator') + .with(room:, name: user.name, user_id:, avatar_url:, role: 'Moderator') post :start, params: { friendly_id: room.friendly_id } end @@ -129,7 +131,8 @@ it 'allows a user who the room is shared with to start the meeting' do expect_any_instance_of(MeetingStarter).to receive(:call) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, user_id: guest_user_id, + avatar_url: nil, role: 'Moderator') post :start, params: { friendly_id: room.friendly_id } @@ -142,7 +145,8 @@ describe '#status' do it 'gets the joinUrl if the meeting is running' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, avatar_url: nil, role: 'Viewer') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, user_id:, avatar_url: nil, + role: 'Viewer') post :status, params: { friendly_id: test_room.friendly_id, name: user.name } expect(response).to have_http_status(:ok) @@ -161,14 +165,15 @@ it 'joins as viewer if no access code is required nor provided' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, avatar_url: nil, role: 'Viewer') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, user_id:, avatar_url: nil, + role: 'Viewer') post :status, params: { friendly_id: test_room.friendly_id, name: user.name } expect(response).to have_http_status(:ok) end it 'joins as moderator if user is joining his own room' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, user_id:, avatar_url: nil, role: 'Moderator') post :status, params: { friendly_id: room.friendly_id, name: user.name } expect(response).to have_http_status(:ok) end @@ -180,7 +185,7 @@ expect_any_instance_of(BigBlueButtonApi) .to receive(:join_meeting) - .with(room: test_room, name: user.name, avatar_url:, role: 'Viewer') + .with(room: test_room, name: user.name, user_id:, avatar_url:, role: 'Viewer') post :status, params: { friendly_id: test_room.friendly_id, name: user.name } end @@ -203,7 +208,8 @@ it 'joins as moderator' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, user_id: guest_user_id, + avatar_url: nil, role: 'Moderator') post :status, params: { friendly_id: room.friendly_id, name: guest_user.name } end end @@ -219,7 +225,8 @@ it 'joins as viewer if access code correspond to the viewer access code' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, avatar_url: nil, role: 'Viewer') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, user_id:, avatar_url: nil, + role: 'Viewer') expect(RoomSettingsGetter).to receive(:new).with( room_id: test_room.id, provider: 'greenlight', show_codes: true, current_user: user, settings: %w[glRequireAuthentication glViewerAccessCode glModeratorAccessCode glAnyoneCanStart glAnyoneJoinAsModerator] @@ -234,7 +241,7 @@ it 'joins as moderator if access code correspond to moderator access code' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, user_id:, avatar_url: nil, role: 'Moderator') expect(RoomSettingsGetter).to receive(:new).with( room_id: room.id, provider: 'greenlight', show_codes: true, current_user: user, settings: %w[glRequireAuthentication glViewerAccessCode glModeratorAccessCode glAnyoneCanStart glAnyoneJoinAsModerator] @@ -273,7 +280,8 @@ it 'user joins as a moderator' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, user_id: guest_user_id, + avatar_url: nil, role: 'Moderator') expect(RoomSettingsGetter).to receive(:new).with( room_id: room.id, provider: 'greenlight', show_codes: true, current_user: guest_user, settings: %w[glRequireAuthentication glViewerAccessCode glModeratorAccessCode glAnyoneCanStart glAnyoneJoinAsModerator] @@ -299,7 +307,8 @@ it 'user joins as moderator if an access code is needed and the input correspond the viewer access code' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, user_id: guest_user_id, + avatar_url: nil, role: 'Moderator') expect(RoomSettingsGetter).to receive(:new).with( room_id: room.id, provider: 'greenlight', show_codes: true, current_user: guest_user, settings: %w[glRequireAuthentication glViewerAccessCode glModeratorAccessCode glAnyoneCanStart glAnyoneJoinAsModerator] @@ -314,7 +323,8 @@ it 'user joins as moderator if an access code is needed and the input correspond the moderator access code' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, avatar_url: nil, role: 'Moderator') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: guest_user.name, user_id: guest_user_id, + avatar_url: nil, role: 'Moderator') expect(RoomSettingsGetter).to receive(:new).with( room_id: room.id, provider: 'greenlight', show_codes: true, current_user: guest_user, settings: %w[glRequireAuthentication glViewerAccessCode glModeratorAccessCode glAnyoneCanStart glAnyoneJoinAsModerator] @@ -387,7 +397,8 @@ it 'allows the user to join if they are signed in' do allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, avatar_url: nil, role: 'Viewer') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room: test_room, name: user.name, user_id:, avatar_url: nil, + role: 'Viewer') post :status, params: { friendly_id: test_room.friendly_id, name: user.name } @@ -406,10 +417,13 @@ end it 'allows access to an unauthenticated user' do + allow(SecureRandom).to receive(:hex).and_return('abc123456789') + session[:session_token] = nil allow_any_instance_of(BigBlueButtonApi).to receive(:meeting_running?).and_return(true) - expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, avatar_url: nil, role: 'Viewer') + expect_any_instance_of(BigBlueButtonApi).to receive(:join_meeting).with(room:, name: user.name, user_id: 'gl-guest-abc123456789', + avatar_url: nil, role: 'Viewer') post :status, params: { friendly_id: room.friendly_id, name: user.name } diff --git a/spec/services/meeting_starter_spec.rb b/spec/services/meeting_starter_spec.rb index 254c77e5ef..4fb0464bb0 100644 --- a/spec/services/meeting_starter_spec.rb +++ b/spec/services/meeting_starter_spec.rb @@ -46,6 +46,8 @@ 'meta_bbb-origin-version': 'v3', 'meta_bbb-origin': 'greenlight', 'meta_bbb-origin-server-name': URI(base_url).host, + 'meta_bbb-context-name': room.name, + 'meta_bbb-context-id': room.friendly_id, setting: 'value' } end