diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index 91dbac6f96e626e2cb0f37dfee8c1cd453a0fa67..a5cc4119b6bb1fcbdb3add5b91a2f9775890845d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -76,6 +76,10 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[EjectUserFromMeetingSysMsg](envelope, jsonNode) case ValidateConnAuthTokenSysMsg.NAME => route[ValidateConnAuthTokenSysMsg](meetingManagerChannel, envelope, jsonNode) + case AddPadSysMsg.NAME => + routeGenericMsg[AddPadSysMsg](envelope, jsonNode) + case AddCaptionsPadsSysMsg.NAME => + routeGenericMsg[AddCaptionsPadsSysMsg](envelope, jsonNode) // Guests case GetGuestsWaitingApprovalReqMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index b5b2fb22df505c8952a8a335d6769b68782c8800..d9a666efafd63d833fc6ea5ee9fcb62c016ab7e2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -26,6 +26,7 @@ import org.bigbluebutton.core.models._ import org.bigbluebutton.core2.{ MeetingStatus2x, Permissions } import org.bigbluebutton.core2.message.handlers._ import org.bigbluebutton.core2.message.handlers.meeting._ +import org.bigbluebutton.core2.message.handlers.pads._ import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.apps.breakout._ import org.bigbluebutton.core.apps.polls._ @@ -84,6 +85,8 @@ class MeetingActor( with SyncGetMeetingInfoRespMsgHdlr with ClientToServerLatencyTracerMsgHdlr with ValidateConnAuthTokenSysMsgHdlr + with AddPadSysMsgHdlr + with AddCaptionsPadsSysMsgHdlr with UserActivitySignCmdMsgHdlr { object CheckVoiceRecordingInternalMsg @@ -491,6 +494,9 @@ class MeetingActor( case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m) + case m: AddPadSysMsg => handleAddPadSysMsg(m) + case m: AddCaptionsPadsSysMsg => handleAddCaptionsPadsSysMsg(m) + case m: UserActivitySignCmdMsg => handleUserActivitySignCmdMsg(m) case _ => log.warning("***** Cannot handle " + msg.envelope.name) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddCaptionsPadsSysMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddCaptionsPadsSysMsgHdlr.scala new file mode 100755 index 0000000000000000000000000000000000000000..466f3a354f2dacfc07eb9ecdf6e22c8e83c1298b --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddCaptionsPadsSysMsgHdlr.scala @@ -0,0 +1,21 @@ +package org.bigbluebutton.core2.message.handlers.pads + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core2.message.senders.MsgBuilder + +trait AddCaptionsPadsSysMsgHdlr { + this: BaseMeetingActor => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleAddCaptionsPadsSysMsg(msg: AddCaptionsPadsSysMsg) { + val padIds = msg.body.padIds + val meetingId = liveMeeting.props.meetingProp.intId + + log.info(s"Handling add captions pads for meetingId=${meetingId}") + + outGW.send(MsgBuilder.buildAddCaptionsPadsEvtMsg(meetingId, padIds)) + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddPadSysMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddPadSysMsgHdlr.scala new file mode 100755 index 0000000000000000000000000000000000000000..e9a30313d1431c135a801d23473ea4d28b829ba8 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/pads/AddPadSysMsgHdlr.scala @@ -0,0 +1,22 @@ +package org.bigbluebutton.core2.message.handlers.pads + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core2.message.senders.MsgBuilder + +trait AddPadSysMsgHdlr { + this: BaseMeetingActor => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleAddPadSysMsg(msg: AddPadSysMsg) { + val padId = msg.body.padId + val readOnlyId = msg.body.readOnlyId + val meetingId = liveMeeting.props.meetingProp.intId + + log.info(s"Handling add padId=${padId} and readOnlyId=${readOnlyId} for meetingId=${meetingId}") + + outGW.send(MsgBuilder.buildAddPadEvtMsg(meetingId, padId, readOnlyId)) + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala index c24d64e29f0b3995a66b20570adc3d8009d4a61d..3f079333d7f5fed63f26a32ac2bc66721d13aac3 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala @@ -83,6 +83,26 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } + def buildAddPadEvtMsg(meetingId: String, padId: String, readOnlyId: String): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") + val envelope = BbbCoreEnvelope(AddPadEvtMsg.NAME, routing) + val header = BbbCoreHeaderWithMeetingId(AddPadEvtMsg.NAME, meetingId) + val body = AddPadEvtMsgBody(padId, readOnlyId) + val event = AddPadEvtMsg(header, body) + + BbbCommonEnvCoreMsg(envelope, event) + } + + def buildAddCaptionsPadsEvtMsg(meetingId: String, padIds: Array[String]): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") + val envelope = BbbCoreEnvelope(AddCaptionsPadsEvtMsg.NAME, routing) + val header = BbbCoreHeaderWithMeetingId(AddCaptionsPadsEvtMsg.NAME, meetingId) + val body = AddCaptionsPadsEvtMsgBody(padIds) + val event = AddCaptionsPadsEvtMsg(header, body) + + BbbCommonEnvCoreMsg(envelope, event) + } + def buildGetUsersMeetingRespMsg(meetingId: String, userId: String, webusers: Vector[WebUser]): BbbCommonEnvCoreMsg = { val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) val envelope = BbbCoreEnvelope(GetUsersMeetingRespMsg.NAME, routing) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala index 677c475b91c530bb8d157c38c31a38017be28070..6f8023dfd31a021cc4abc183d87babb0355bffbf 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala @@ -189,6 +189,22 @@ case class ValidateConnAuthTokenSysRespMsg( case class ValidateConnAuthTokenSysRespMsgBody(meetingId: String, userId: String, connId: String, authzed: Boolean, app: String) +object AddPadSysMsg { val NAME = "AddPadSysMsg" } +case class AddPadSysMsg(header: BbbClientMsgHeader, body: AddPadSysMsgBody) extends StandardMsg +case class AddPadSysMsgBody(padId: String, readOnlyId: String) + +object AddCaptionsPadsSysMsg { val NAME = "AddCaptionsPadsSysMsg" } +case class AddCaptionsPadsSysMsg(header: BbbClientMsgHeader, body: AddCaptionsPadsSysMsgBody) extends StandardMsg +case class AddCaptionsPadsSysMsgBody(padIds: Array[String]) + +object AddPadEvtMsg { val NAME = "AddPadEvtMsg" } +case class AddPadEvtMsg(header: BbbCoreHeaderWithMeetingId, body: AddPadEvtMsgBody) extends BbbCoreMsg +case class AddPadEvtMsgBody(padId: String, readOnlyId: String) + +object AddCaptionsPadsEvtMsg { val NAME = "AddCaptionsPadsEvtMsg" } +case class AddCaptionsPadsEvtMsg(header: BbbCoreHeaderWithMeetingId, body: AddCaptionsPadsEvtMsgBody) extends BbbCoreMsg +case class AddCaptionsPadsEvtMsgBody(padIds: Array[String]) + object PublishedRecordingSysMsg { val NAME = "PublishedRecordingSysMsg" } case class PublishedRecordingSysMsg(header: BbbCoreBaseHeader, body: PublishedRecordingSysMsgBody) extends BbbCoreMsg case class PublishedRecordingSysMsgBody(recordId: String) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index adff3ac4616bc09b4548d55046439796735269fe..71d13675136f93bffd97eac1150f21768e411c13 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -54,6 +54,8 @@ import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.PublishedRecordingMessage; import org.bigbluebutton.api.messaging.converters.messages.UnpublishedRecordingMessage; import org.bigbluebutton.api.messaging.converters.messages.DeletedRecordingMessage; +import org.bigbluebutton.api.messaging.messages.AddPad; +import org.bigbluebutton.api.messaging.messages.AddCaptionsPads; import org.bigbluebutton.api.messaging.messages.CreateBreakoutRoom; import org.bigbluebutton.api.messaging.messages.CreateMeeting; import org.bigbluebutton.api.messaging.messages.EndMeeting; @@ -161,6 +163,20 @@ public class MeetingService implements MessageListener { } } + public Boolean isPadValid(String padId, String sessionToken) { + UserSession us = getUserSessionWithAuthToken(sessionToken); + if (us == null) return false; + + Meeting m = getMeeting(us.meetingID); + if (m == null) return false; + + if (m.hasPad(padId)) { + return true; + } else { + return false; + } + } + public UserSession getUserSessionWithUserId(String userId) { for (UserSession userSession : sessions.values()) { if (userSession.internalUserId.equals(userId)) { @@ -1051,6 +1067,10 @@ public class MeetingService implements MessageListener { processGuestPolicyChanged((GuestPolicyChanged) message); } else if (message instanceof RecordChapterBreak) { processRecordingChapterBreak((RecordChapterBreak) message); + } else if (message instanceof AddPad) { + processAddPad((AddPad) message); + } else if (message instanceof AddCaptionsPads) { + processAddCaptionsPads((AddCaptionsPads) message); } else if (message instanceof MakePresentationDownloadableMsg) { processMakePresentationDownloadableMsg((MakePresentationDownloadableMsg) message); } else if (message instanceof UpdateRecordingStatus) { @@ -1069,6 +1089,22 @@ public class MeetingService implements MessageListener { } } + public void processAddPad(AddPad msg) { + Meeting m = getMeeting(msg.meetingId); + if (m != null) { + m.addPad(msg.padId, msg.readOnlyId); + } + } + + public void processAddCaptionsPads(AddCaptionsPads msg) { + Meeting m = getMeeting(msg.meetingId); + if (m != null) { + for (String padId : msg.padIds) { + m.addPad(padId, "undefined"); + } + } + } + public void processRecordingChapterBreak(RecordChapterBreak msg) { recordingService.kickOffRecordingChapterBreak(msg.meetingId, msg.timestamp); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java index a19b62d7732fa8201b6692d43439f20d3804fd13..9f424916eba2bfe1404ce41b34d760371a6a6cb6 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java @@ -69,6 +69,7 @@ public class Meeting { private String defaultConfigToken; private String guestPolicy = GuestPolicy.ASK_MODERATOR; private boolean userHasJoined = false; + private Map<String, String> pads; private Map<String, String> metadata; private Map<String, Object> userCustomData; private final ConcurrentMap<String, User> users; @@ -131,6 +132,13 @@ public class Meeting { allowDuplicateExtUserid = builder.allowDuplicateExtUserid; endWhenNoModerator = builder.endWhenNoModerator; + /* + * A pad is a pair of padId and readOnlyId that represents + * valid etherpads instances for this meeting. They can be: + * - shared notes + * - closed captions + */ + pads = new HashMap<>(); userCustomData = new HashMap<>(); users = new ConcurrentHashMap<>(); @@ -179,6 +187,10 @@ public class Meeting { return configs.remove(token); } + public Map<String, String> getPads() { + return pads; + } + public Map<String, String> getMetadata() { return metadata; } @@ -537,6 +549,14 @@ public class Meeting { return sum; } + public void addPad(String padId, String readOnlyId) { + pads.put(padId, readOnlyId); + } + + public Boolean hasPad(String id) { + return pads.containsKey(id) || pads.containsValue(id); + } + public void addUserCustomData(String userID, Map<String, String> data) { userCustomData.put(userID, data); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddCaptionsPads.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddCaptionsPads.java new file mode 100755 index 0000000000000000000000000000000000000000..3ccd1e10d72964024d4386b6f8ef332ee6d22260 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddCaptionsPads.java @@ -0,0 +1,11 @@ +package org.bigbluebutton.api.messaging.messages; + +public class AddCaptionsPads implements IMessage { + public final String meetingId; + public final String[] padIds; + + public AddCaptionsPads(String meetingId, String[] padIds) { + this.meetingId = meetingId; + this.padIds = padIds; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddPad.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddPad.java new file mode 100755 index 0000000000000000000000000000000000000000..1f255acd7fa732dd1928cf662da183c2feef8baa --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/AddPad.java @@ -0,0 +1,13 @@ +package org.bigbluebutton.api.messaging.messages; + +public class AddPad implements IMessage { + public final String meetingId; + public final String padId; + public final String readOnlyId; + + public AddPad(String meetingId, String padId, String readOnlyId) { + this.meetingId = meetingId; + this.padId = padId; + this.readOnlyId = readOnlyId; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ParamsUtil.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ParamsUtil.java index d02927d1e0d037d88fdc327499eb1382387db98f..9a4b3e96744392aa33f586a300ff07e97e16c22b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ParamsUtil.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ParamsUtil.java @@ -51,4 +51,20 @@ public class ParamsUtil { } return token; } + + public static String getPadId(String url) { + String padId = "undefined"; + try { + String decodedURL = URLDecoder.decode(url, "UTF-8"); + String[] splitURL = decodedURL.split("\\?"); + // If there is no query params, it's an invalid URL already + if (splitURL.length == 2) { + String[] params = splitURL[0].split("\\/"); + padId = params[params.length - 1]; + } + } catch (UnsupportedEncodingException e) { + log.error(e.toString()); + } + return padId; + } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala index c78d684342c844fbac7a7f30408da245607685ec..7eb216f80f497677bae82e1fa9494eb9a1f4fa27 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala @@ -94,6 +94,10 @@ class ReceivedJsonMsgHdlrActor(val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEvent route[GuestsWaitingApprovedEvtMsg](envelope, jsonNode) case GuestPolicyChangedEvtMsg.NAME => route[GuestPolicyChangedEvtMsg](envelope, jsonNode) + case AddPadEvtMsg.NAME => + route[AddPadEvtMsg](envelope, jsonNode) + case AddCaptionsPadsEvtMsg.NAME => + route[AddCaptionsPadsEvtMsg](envelope, jsonNode) case RecordingChapterBreakSysMsg.NAME => route[RecordingChapterBreakSysMsg](envelope, jsonNode) case SetPresentationDownloadableEvtMsg.NAME => diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala index 8c70b881e6f45b461b7a738bb72e956a05b20af4..a43fbcf516824d68f3bc763c645150caa1ea273f 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala @@ -39,6 +39,8 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) case m: PresentationUploadTokenSysPubMsg => handlePresentationUploadTokenSysPubMsg(m) case m: GuestsWaitingApprovedEvtMsg => handleGuestsWaitingApprovedEvtMsg(m) case m: GuestPolicyChangedEvtMsg => handleGuestPolicyChangedEvtMsg(m) + case m: AddCaptionsPadsEvtMsg => handleAddCaptionsPadsEvtMsg(m) + case m: AddPadEvtMsg => handleAddPadEvtMsg(m) case m: RecordingChapterBreakSysMsg => handleRecordingChapterBreakSysMsg(m) case m: SetPresentationDownloadableEvtMsg => handleSetPresentationDownloadableEvtMsg(m) case m: RecordingStatusChangedEvtMsg => handleRecordingStatusChangedEvtMsg(m) @@ -50,6 +52,14 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) olgMsgGW.handle(new GuestPolicyChanged(msg.header.meetingId, msg.body.policy)) } + def handleAddPadEvtMsg(msg: AddPadEvtMsg): Unit = { + olgMsgGW.handle(new AddPad(msg.header.meetingId, msg.body.padId, msg.body.readOnlyId)) + } + + def handleAddCaptionsPadsEvtMsg(msg: AddCaptionsPadsEvtMsg): Unit = { + olgMsgGW.handle(new AddCaptionsPads(msg.header.meetingId, msg.body.padIds)) + } + def handleRecordingChapterBreakSysMsg(msg: RecordingChapterBreakSysMsg): Unit = { olgMsgGW.handle(new RecordChapterBreak(msg.body.meetingId, msg.body.timestamp)) } diff --git a/bigbluebutton-html5/imports/api/captions/server/methods/addCaptionsPads.js b/bigbluebutton-html5/imports/api/captions/server/methods/addCaptionsPads.js new file mode 100644 index 0000000000000000000000000000000000000000..4ca15b07f1c2ac5e3f216edd12b163415b16785a --- /dev/null +++ b/bigbluebutton-html5/imports/api/captions/server/methods/addCaptionsPads.js @@ -0,0 +1,19 @@ +import RedisPubSub from '/imports/startup/server/redis'; +import Logger from '/imports/startup/server/logger'; +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; + +export default function addCaptionsPads(meetingId, padIds) { + const REDIS_CONFIG = Meteor.settings.private.redis; + const CHANNEL = REDIS_CONFIG.channels.toAkkaApps; + const EVENT_NAME = 'AddCaptionsPadsSysMsg'; + + check(meetingId, String); + check(padIds, [String]); + + const payload = { + padIds, + }; + + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, 'nodeJSapp', payload); +} diff --git a/bigbluebutton-html5/imports/api/captions/server/methods/addPad.js b/bigbluebutton-html5/imports/api/captions/server/methods/addPad.js new file mode 100644 index 0000000000000000000000000000000000000000..e9b6df837e9dbba0eeb6781a848f919b48eab495 --- /dev/null +++ b/bigbluebutton-html5/imports/api/captions/server/methods/addPad.js @@ -0,0 +1,32 @@ +import RedisPubSub from '/imports/startup/server/redis'; +import Captions from '/imports/api/captions'; +import Logger from '/imports/startup/server/logger'; +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; + +export default function addPad(padId, readOnlyId) { + const REDIS_CONFIG = Meteor.settings.private.redis; + const CHANNEL = REDIS_CONFIG.channels.toAkkaApps; + const EVENT_NAME = 'AddPadSysMsg'; + + check(padId, String); + check(readOnlyId, String); + + const pad = Captions.findOne({ padId }); + + if (!pad) { + Logger.error(`Could not find closed captions pad ${padId}`); + return; + } + + const { meetingId } = pad; + + check(meetingId, String); + + const payload = { + padId, + readOnlyId, + }; + + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, 'nodeJSapp', payload); +} diff --git a/bigbluebutton-html5/imports/api/captions/server/methods/createCaptions.js b/bigbluebutton-html5/imports/api/captions/server/methods/createCaptions.js index 24215b91c52876b47814e62b33fd52687df92340..af29cb8c889a7524d9225b1ba3ddf9394e0f1810 100644 --- a/bigbluebutton-html5/imports/api/captions/server/methods/createCaptions.js +++ b/bigbluebutton-html5/imports/api/captions/server/methods/createCaptions.js @@ -6,6 +6,7 @@ import { getLocalesURL, } from '/imports/api/captions/server/helpers'; import addCaption from '/imports/api/captions/server/modifiers/addCaption'; +import addCaptionsPads from '/imports/api/captions/server/methods/addCaptionsPads'; import axios from 'axios'; export default function createCaptions(meetingId) { @@ -27,10 +28,13 @@ export default function createCaptions(meetingId) { Logger.error(`Could not get locales info for ${meetingId} ${status}`); return; } + const padIds = []; const locales = response.data; locales.forEach((locale) => { const padId = generatePadId(meetingId, locale.locale); addCaption(meetingId, padId, locale); + padIds.push(padId); }); + addCaptionsPads(meetingId, padIds); }).catch(error => Logger.error(`Could not create captions for ${meetingId}: ${error}`)); } diff --git a/bigbluebutton-html5/imports/api/captions/server/modifiers/updateReadOnlyPadId.js b/bigbluebutton-html5/imports/api/captions/server/modifiers/updateReadOnlyPadId.js index 8fddb6f814559a1e6a36762d2066c0439a4bc09d..fffbadf204f6e2b9218fd4756c2c6d55e9591bef 100644 --- a/bigbluebutton-html5/imports/api/captions/server/modifiers/updateReadOnlyPadId.js +++ b/bigbluebutton-html5/imports/api/captions/server/modifiers/updateReadOnlyPadId.js @@ -1,6 +1,7 @@ import Captions from '/imports/api/captions'; import Logger from '/imports/startup/server/logger'; import { check } from 'meteor/check'; +import addPad from '/imports/api/captions/server/methods/addPad'; export default function updateReadOnlyPadId(padId, readOnlyPadId) { check(padId, String); @@ -20,6 +21,7 @@ export default function updateReadOnlyPadId(padId, readOnlyPadId) { const numberAffected = Captions.update(selector, modifier, { multi: true }); if (numberAffected) { + addPad(padId, readOnlyPadId); Logger.verbose('Captions: added readOnlyPadId', { padId, readOnlyPadId }); } } catch (err) { diff --git a/bigbluebutton-html5/imports/api/note/server/methods/addPad.js b/bigbluebutton-html5/imports/api/note/server/methods/addPad.js new file mode 100644 index 0000000000000000000000000000000000000000..45acbde7833747f08f34c2db93b22692d72a5445 --- /dev/null +++ b/bigbluebutton-html5/imports/api/note/server/methods/addPad.js @@ -0,0 +1,21 @@ +import RedisPubSub from '/imports/startup/server/redis'; +import Logger from '/imports/startup/server/logger'; +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; + +export default function addPad(meetingId, padId, readOnlyId) { + const REDIS_CONFIG = Meteor.settings.private.redis; + const CHANNEL = REDIS_CONFIG.channels.toAkkaApps; + const EVENT_NAME = 'AddPadSysMsg'; + + check(meetingId, String); + check(padId, String); + check(readOnlyId, String); + + const payload = { + padId, + readOnlyId, + }; + + return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, 'nodeJSapp', payload); +} diff --git a/bigbluebutton-html5/imports/api/note/server/modifiers/addNote.js b/bigbluebutton-html5/imports/api/note/server/modifiers/addNote.js index a3f8ae2f6317a9e25068a0798f1825fb01d5b980..15f8152b19ec4b00ec8ab218a4a9914dbcdb74e4 100644 --- a/bigbluebutton-html5/imports/api/note/server/modifiers/addNote.js +++ b/bigbluebutton-html5/imports/api/note/server/modifiers/addNote.js @@ -1,6 +1,7 @@ import { check } from 'meteor/check'; import Note from '/imports/api/note'; import Logger from '/imports/startup/server/logger'; +import addPad from '/imports/api/note/server/methods/addPad'; export default function addNote(meetingId, noteId, readOnlyNoteId) { check(meetingId, String); @@ -23,6 +24,7 @@ export default function addNote(meetingId, noteId, readOnlyNoteId) { const { insertedId } = Note.upsert(selector, modifier); if (insertedId) { + addPad(meetingId, noteId, readOnlyNoteId); Logger.info(`Added note id=${noteId} readOnlyId=${readOnlyNoteId} meeting=${meetingId}`); } else { Logger.info(`Upserted note id=${noteId} readOnlyId=${readOnlyNoteId} meeting=${meetingId}`); diff --git a/bigbluebutton-html5/imports/ui/components/note/service.js b/bigbluebutton-html5/imports/ui/components/note/service.js index 1a6ee84ea198bfda5b2388c1f9c1aa5fe496f1a3..6920998cee8b40553e51dc77de55b902e6ad0bb8 100644 --- a/bigbluebutton-html5/imports/ui/components/note/service.js +++ b/bigbluebutton-html5/imports/ui/components/note/service.js @@ -25,6 +25,8 @@ const getLang = () => { const getNoteParams = () => { let config = {}; + const User = Users.findOne({ userId: Auth.userID }, { fields: { name: 1 } }); + config.userName = User.name; config.lang = getLang(); config.rtl = document.documentElement.getAttribute('dir') === 'rtl'; diff --git a/bigbluebutton-web/bbb-web.nginx b/bigbluebutton-web/bbb-web.nginx index 120d2dcf8af99924bcea9b2e307214ab5d1e2b70..57d34ebbe4e7270ace3b9eec34728a9ea7212b48 100755 --- a/bigbluebutton-web/bbb-web.nginx +++ b/bigbluebutton-web/bbb-web.nginx @@ -88,6 +88,14 @@ proxy_set_header X-Original-URI $request_uri; } + location = /bigbluebutton/connection/validatePad { + internal; + proxy_pass http://127.0.0.1:8090; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header X-Original-URI $request_uri; + } + location ~ "^/bigbluebutton\/textTrack\/(?<textTrackToken>[a-zA-Z0-9]+)\/(?<recordId>[a-zA-Z0-9_-]+)\/(?<textTrack>.+)$" { # Workaround IE refusal to set cookies in iframe add_header P3P 'CP="No P3P policy available"'; diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/UrlMappings.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/UrlMappings.groovy index 10d573ce34a7026da877fe57d62a894146f7c503..33a9343563de7a2e835e2dfbf8744eb147daaccc 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/UrlMappings.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/UrlMappings.groovy @@ -95,10 +95,6 @@ class UrlMappings { action = [POST: 'putRecordingTextTrack'] } - "/connection/checkAuthorization"(controller:"connection") { - action = [GET:'checkAuthorization'] - } - "/bigbluebutton/$controller/$action?/$id?(.${format})?" { constraints { // apply constraints here diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy old mode 100644 new mode 100755 index b55ccd7c55932046679cd87fe92194188b3df27d..4abb86651cdd5e7bace8a26dbfef2cbea15cdad7 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy @@ -44,4 +44,25 @@ class ConnectionController { log.error("Error while authenticating connection.\n" + e.getMessage()) } } + + def validatePad = { + try { + String uri = request.getHeader("x-original-uri") + String sessionToken = ParamsUtil.getSessionToken(uri) + String padId = ParamsUtil.getPadId(uri) + Boolean valid = meetingService.isPadValid(padId, sessionToken) + + response.addHeader("Cache-Control", "no-cache") + response.contentType = 'plain/text' + if (valid) { + response.setStatus(200) + response.outputStream << 'authorized' + } else { + response.setStatus(401) + response.outputStream << 'unauthorized' + } + } catch (IOException e) { + log.error("Error while authenticating connection.\n" + e.getMessage()) + } + } }