Merge pull request #4534 from ritzalam/implement-multi-chat

Implement multi chat and multi-presentation
This commit is contained in:
Richard Alam 2017-10-18 13:13:53 -04:00 committed by GitHub
commit 40fbc78194
21 changed files with 304 additions and 99 deletions

View File

@ -79,3 +79,7 @@ services {
telizeHost = "www.telize.com"
telizePort = 80
}
apps {
checkPermissions = true
}

View File

@ -59,4 +59,6 @@ trait SystemConfiguration {
lazy val httpPort = Try(config.getInt("http.port")).getOrElse(9090)
lazy val telizeHost = Try(config.getString("services.telizeHost")).getOrElse("")
lazy val telizePort = Try(config.getInt("services.telizePort")).getOrElse(80)
lazy val applyPermissionCheck = Try(config.getBoolean("apps.checkPermissions")).getOrElse(false)
}

View File

@ -1,10 +1,63 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.core.models.{ Roles, UserState, Users2x }
import org.bigbluebutton.core.running.OutMsgRouter
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
trait PermisssionCheck {
object PermisssionCheck {
def isAllowed(permission: String, role: String, user: UserVO): Boolean = {
true
val MOD_LEVEL = 100
val AUTHED_LEVEL = 50
val GUEST_LEVEL = 0
val PRESENTER_LEVEL = 100
val VIEWER_LEVEL = 0
private def permissionToLevel(user: UserState): Int = {
if (user.role == Roles.MODERATOR_ROLE) {
MOD_LEVEL
} else if (user.authed) {
AUTHED_LEVEL
} else {
GUEST_LEVEL
}
}
private def roleToLevel(user: UserState): Int = {
if (user.presenter) PRESENTER_LEVEL else VIEWER_LEVEL
}
/**
* This method will check if the user that issued the command has the correct permissions.
*
* Example of the permissions level are "AUTHENTICATED", "MODERATOR" and "GUEST". Example of roles
* are "VIEWER" and "PRESENTER".
*
* @param permissionLevel Lowest permission needed to have access.
* @param roleLevel Lowest role needed to have access.
* @return true allows API to execute, false denies executing API
*/
def isAllowed(permissionLevel: Int, roleLevel: Int, users: Users2x, userId: String): Boolean = {
Users2x.findWithIntId(users, userId) match {
case Some(user) =>
println("permissionToLevel = " + permissionToLevel(user) + " permissionLevel=" + permissionLevel)
val permLevelCheck = permissionToLevel(user) >= permissionLevel
println("roleToLevel = " + roleToLevel(user) + " roleLevel=" + roleLevel)
val roleLevelCheck = roleToLevel(user) >= roleLevel
println("PERMLEVELCHECK = " + permLevelCheck + " ROLELEVELCHECK=" + roleLevelCheck)
permLevelCheck && roleLevelCheck
false
case None => false
}
}
def ejectUserForFailedPermission(meetingId: String, userId: String, reason: String, outGW: OutMsgRouter): Unit = {
val ejectedBy = "SYSTEM"
Sender.sendUserEjectedFromMeetingClientEvtMsg(meetingId, userId, ejectedBy, reason, outGW)
// send a system message to force disconnection
Sender.sendUserEjectedFromMeetingSystemMsg(meetingId, userId, ejectedBy, outGW)
}
}

View File

@ -8,8 +8,6 @@ import org.bigbluebutton.core.running.LiveMeeting
class PresentationApp2x(implicit val context: ActorContext)
extends NewPresentationMsgHdlr
// with SetCurrentPresentationPubMsgHdlr
// with GetPresentationInfoReqMsgHdlr
with SetCurrentPagePubMsgHdlr
with ResizeAndMovePagePubMsgHdlr
with RemovePresentationPubMsgHdlr
@ -18,7 +16,6 @@ class PresentationApp2x(implicit val context: ActorContext)
with PresentationConversionUpdatePubMsgHdlr
with PresentationPageCountErrorPubMsgHdlr
with PresentationPageGeneratedPubMsgHdlr
with PresentationConversionCompletedPubMsgHdlr
with SyncGetPresentationInfoRespMsgHdlr {
val log = Logging(context.system, getClass)

View File

@ -1,47 +0,0 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.running.{ LiveMeeting }
trait PresentationConversionCompletedPubMsgHdlr {
this: PresentationApp2x =>
def handle(
msg: PresentationConversionCompletedSysPubMsg,
liveMeeting: LiveMeeting, bus: MessageBus
): Unit = {
def broadcastEvent(msg: PresentationConversionCompletedSysPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, msg.header.userId
)
val envelope = BbbCoreEnvelope(PresentationConversionCompletedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(
PresentationConversionCompletedEvtMsg.NAME,
liveMeeting.props.meetingProp.intId, msg.header.userId
)
val body = PresentationConversionCompletedEvtMsgBody(msg.body.podId, msg.body.messageKey, msg.body.code, msg.body.presentation)
val event = PresentationConversionCompletedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
bus.outGW.send(msgEvent)
}
val pages = new collection.mutable.HashMap[String, PageVO]
msg.body.presentation.pages.foreach { p =>
val page = PageVO(p.id, p.num, p.thumbUri, p.swfUri, p.txtUri, p.svgUri, p.current, p.xOffset, p.yOffset,
p.widthRatio, p.heightRatio)
pages += page.id -> page
}
val pres = new Presentation(msg.body.presentation.id, msg.body.presentation.name, msg.body.presentation.current,
pages.toMap, msg.body.presentation.downloadable)
presentationConversionCompleted(liveMeeting, pres)
broadcastEvent(msg)
}
}

View File

@ -1,5 +1,3 @@
package org.bigbluebutton.core.apps.presentationpod
import org.bigbluebutton.common2.domain.{ PresentationPodVO, PresentationVO }

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.core.apps.presentationpod
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.domain.MeetingState2x
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.common2.domain.{ PageVO, PresentationVO }
import org.bigbluebutton.core.apps.Presentation
trait PresentationConversionCompletedSysPubMsgHdlr {
this: PresentationPodHdlrs =>
def handle(
msg: PresentationConversionCompletedSysPubMsg, state: MeetingState2x,
liveMeeting: LiveMeeting, bus: MessageBus
): MeetingState2x = {
def broadcastPresentationConversionCompletedEvtMsg(podId: String, userId: String, messageKey: String,
code: String, presentation: PresentationVO): Unit = {
val routing = Routing.addMsgToClientRouting(
MessageTypes.BROADCAST_TO_MEETING,
liveMeeting.props.meetingProp.intId, userId
)
val envelope = BbbCoreEnvelope(PresentationConversionCompletedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(PresentationConversionCompletedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, userId)
val body = PresentationConversionCompletedEvtMsgBody(podId, messageKey, code, presentation)
val event = PresentationConversionCompletedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
bus.outGW.send(msgEvent)
}
val pages = new collection.mutable.HashMap[String, PageVO]
msg.body.presentation.pages.foreach { p =>
val page = PageVO(p.id, p.num, p.thumbUri, p.swfUri, p.txtUri, p.svgUri, p.current, p.xOffset, p.yOffset,
p.widthRatio, p.heightRatio)
pages += page.id -> page
}
val pres = new Presentation(msg.body.presentation.id, msg.body.presentation.name, msg.body.presentation.current,
pages.toMap, msg.body.presentation.downloadable)
val presVO = PresentationPodsApp.translatePresentationToPresentationVO(pres)
val podId = msg.body.podId
val newState = for {
pod <- PresentationPodsApp.getPresentationPod(state, podId)
} yield {
broadcastPresentationConversionCompletedEvtMsg(pod.id, msg.header.userId, msg.body.messageKey, msg.body.code, presVO)
val pods = state.presentationPodManager.addPresentationToPod(pod.id, pres)
state.update(pods)
}
newState match {
case Some(ns) => ns
case None => state
}
}
}

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.core.apps.presentationpod
//import org.bigbluebutton.core.apps.presentationpod._
import akka.actor.ActorContext
import akka.event.Logging
@ -9,6 +8,7 @@ class PresentationPodHdlrs(implicit val context: ActorContext)
with GetPresentationInfoReqMsgHdlr
with GetAllPresentationPodsReqMsgHdlr
with SetCurrentPresentationPubMsgHdlr
with PresentationConversionCompletedSysPubMsgHdlr
with RemovePresentationPodPubMsgHdlr {
val log = Logging(context.system, getClass)

View File

@ -12,11 +12,6 @@ object PresentationPodsApp {
PresentationPodFactory.create(ownerId)
}
// def createPresentationPod(id: String, ownerId: String, currentPresenter: String, authorizedPresenters: Vector[String],
// presentations: collection.immutable.Map[String, Presentation]): PresentationPod = {
// PresentationPodFactory.create(ownerId)
// }
def createDefaultPresentationPod(state: MeetingState2x): MeetingState2x = {
val defaultPresPod = PresentationPodFactory.create("the-owner-id")
val podManager = state.presentationPodManager.addPod(defaultPresPod)
@ -52,5 +47,9 @@ object PresentationPodsApp {
state.update(podManager)
}
def translatePresentationToPresentationVO(pres: Presentation): PresentationVO = {
PresentationVO(pres.id, pres.name, pres.current, pres.pages.values.toVector, pres.downloadable)
}
}

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.core.apps.presentationpod
import org.bigbluebutton.common2.domain.PresentationPodVO
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.bus.MessageBus
import org.bigbluebutton.core.domain.MeetingState2x

View File

@ -1,17 +1,45 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.api.Permissions
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.running.{ OutMsgRouter }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait ChangeLockSettingsInMeetingCmdMsgHdlr {
trait ChangeLockSettingsInMeetingCmdMsgHdlrDefault {
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {}
}
trait ChangeLockSettingsInMeetingCmdMsgHdlrCheckPerm
extends ChangeLockSettingsInMeetingCmdMsgHdlrDefault with SystemConfiguration {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
override def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.setBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to change lock settings"
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.setBy, reason, outGW)
} else {
super.handleSetLockSettings(msg)
}
}
}
trait ChangeLockSettingsInMeetingCmdMsgHdlr extends ChangeLockSettingsInMeetingCmdMsgHdlrCheckPerm {
this: MeetingActor =>
val outGW: OutMsgRouter
override def handleSetLockSettings(msg: ChangeLockSettingsInMeetingCmdMsg): Unit = {
val settings = Permissions(
disableCam = msg.body.disableCam,
disableMic = msg.body.disableMic,

View File

@ -3,7 +3,7 @@ package org.bigbluebutton.core.apps.users
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
trait EjectUserFromMeetingCmdMsgHdlr {
this: UsersApp =>
@ -16,22 +16,22 @@ trait EjectUserFromMeetingCmdMsgHdlr {
user <- Users2x.ejectFromMeeting(liveMeeting.users2x, msg.body.userId)
} yield {
RegisteredUsers.remove(msg.body.userId, liveMeeting.registeredUsers)
val reason = "user ejected by another user"
// send a message to client
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
Sender.sendUserEjectedFromMeetingClientEvtMsg(
liveMeeting.props.meetingProp.intId,
user.intId, msg.body.ejectedBy
user.intId, msg.body.ejectedBy, reason, outGW
)
outGW.send(ejectFromMeetingClientEvent)
log.info("Ejecting user from meeting (client msg). meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.userId)
// send a system message to force disconnection
val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(
Sender.sendUserEjectedFromMeetingSystemMsg(
liveMeeting.props.meetingProp.intId,
user.intId, "eject-user"
user.intId, msg.body.ejectedBy, outGW
)
outGW.send(ejectFromMeetingSystemEvent)
log.info("Ejecting user from meeting (system msg). meetingId=" + liveMeeting.props.meetingProp.intId +
" userId=" + msg.body.userId)

View File

@ -1,23 +1,61 @@
package org.bigbluebutton.core.apps.users
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs.MuteUserCmdMsg
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.models.VoiceUsers
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
import org.bigbluebutton.core2.message.senders.MsgBuilder
trait MuteUserCmdMsgHdlr {
this: MeetingActor =>
trait MuteUserCmdMsgHdlrDefault {
def handleMuteUserCmdMsg(msg: MuteUserCmdMsg): Unit = {
println("**************** MuteUserCmdMsgHdlrDefault ")
}
}
trait MuteUserCmdMsgHdlrPermCheck extends MuteUserCmdMsgHdlrDefault with SystemConfiguration {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
def handleMuteUserCmdMsg(msg: MuteUserCmdMsg) {
log.info("Received mute user request. meetingId=" + props.meetingProp.intId + " userId="
override def handleMuteUserCmdMsg(msg: MuteUserCmdMsg): Unit = {
println("**************** MuteUserCmdMsgHdlrPermCheck ")
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.mutedBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to mute user in meeting."
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
} else {
super.handleMuteUserCmdMsg(msg)
}
}
}
trait MuteUserCmdMsgHdlr extends MuteUserCmdMsgHdlrDefault {
this: UsersApp =>
val liveMeeting: LiveMeeting
val outGW: OutMsgRouter
override def handleMuteUserCmdMsg(msg: MuteUserCmdMsg) {
println("**************** MuteUserCmdMsgHdlr ")
val meetingId = liveMeeting.props.meetingProp.intId
val voiceConf = liveMeeting.props.voiceProp.voiceConf
log.info("Received mute user request. meetingId=" + meetingId + " userId="
+ msg.body.userId)
for {
u <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
} yield {
log.info("Send mute user request. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(props.meetingProp.intId, props.voiceProp.voiceConf,
log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u)
val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg(meetingId, voiceConf,
u.voiceUserId, !u.muted)
outGW.send(event)
}

View File

@ -21,7 +21,9 @@ class UsersApp(
with SetRecordingStatusCmdMsgHdlr
with GetRecordingStatusReqMsgHdlr
with AssignPresenterReqMsgHdlr
with EjectUserFromMeetingCmdMsgHdlr {
with EjectUserFromMeetingCmdMsgHdlr
with MuteUserCmdMsgHdlr
with MuteUserCmdMsgHdlrPermCheck {
val log = Logging(context.system, getClass)
}

View File

@ -13,8 +13,10 @@ object PresentationPodFactory {
case class PresentationPod(id: String, ownerId: String, currentPresenter: String, authorizedPresenters: Vector[String],
presentations: collection.immutable.Map[String, Presentation]) {
def addPresentation(presentation: Presentation): PresentationPod = copy(presentations =
presentations + (presentation.id -> presentation))
def addPresentation(presentation: Presentation): PresentationPod = {
copy(presentations = presentations + (presentation.id -> presentation))
}
def removePresentation(id: String): PresentationPod = copy(presentations = presentations - id)
def addAuthorizedPresenter(userId: String): PresentationPod = copy(authorizedPresenters = authorizedPresenters :+ userId)
@ -42,14 +44,39 @@ case class PresentationPod(id: String, ownerId: String, currentPresenter: String
}
}
def getPresentationsSize(): Int = {
presentations.values.size
}
}
case class PresentationPodManager(presentationPods: collection.immutable.Map[String, PresentationPod]) {
def addPod(presPod: PresentationPod): PresentationPodManager = copy(presentationPods + (presPod.id -> presPod))
def removePod(podId: String): PresentationPodManager = copy(presentationPods = presentationPods - podId)
def addPod(presPod: PresentationPod): PresentationPodManager = {
copy(presentationPods = presentationPods + (presPod.id -> presPod))
}
def removePod(podId: String): PresentationPodManager = {
copy(presentationPods = presentationPods - podId)
}
def getNumberOfPods(): Int = presentationPods.size
def getPod(podId: String): Option[PresentationPod] = presentationPods.get(podId)
def getAllPresentationPodsInMeeting(): Vector[PresentationPod] = presentationPods.values.toVector
def updatePresentationPod(presPod: PresentationPod): PresentationPodManager = addPod(presPod)
def addPresentationToPod(podId: String, pres: Presentation): PresentationPodManager = {
val updatedManager = for {
pod <- getPod(podId)
} yield {
val updatedPod = pod.addPresentation(pres)
updatePresentationPod(updatedPod)
}
updatedManager match {
case Some(ns) => ns
case None => this
}
}
}

View File

@ -167,4 +167,5 @@ object Roles {
val PRESENTER_ROLE = "PRESENTER"
val VIEWER_ROLE = "VIEWER"
val GUEST_ROLE = "GUEST"
val AUTHENTICATED_ROLE = "AUTHENTICATED"
}

View File

@ -62,7 +62,6 @@ class MeetingActor(
with BreakoutApp2x
with UsersApp2x
with PermisssionCheck
with UserBroadcastCamStartMsgHdlr
with UserJoinMeetingReqMsgHdlr
with UserJoinMeetingAfterReconnectReqMsgHdlr
@ -71,8 +70,9 @@ class MeetingActor(
with UserDisconnectedFromGlobalAudioMsgHdlr
with MuteAllExceptPresentersCmdMsgHdlr
with MuteMeetingCmdMsgHdlr
with MuteMeetingCmdMsgHdlrCheckPerm
with IsMeetingMutedReqMsgHdlr
with MuteUserCmdMsgHdlr
with EjectUserFromVoiceCmdMsgHdlr
with EndMeetingSysCmdMsgHdlr
with DestroyMeetingSysCmdMsgHdlr
@ -265,7 +265,7 @@ class MeetingActor(
case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m)
case m: UserTalkingInVoiceConfEvtMsg => handleUserTalkingInVoiceConfEvtMsg(m)
case m: RecordingStartedVoiceConfEvtMsg => handleRecordingStartedVoiceConfEvtMsg(m)
case m: MuteUserCmdMsg => handleMuteUserCmdMsg(m)
case m: MuteUserCmdMsg => usersApp.handleMuteUserCmdMsg(m)
case m: MuteAllExceptPresentersCmdMsg => handleMuteAllExceptPresentersCmdMsg(m)
case m: EjectUserFromVoiceCmdMsg => handleEjectUserFromVoiceCmdMsg(m)
case m: IsMeetingMutedReqMsg => handleIsMeetingMutedReqMsg(m)
@ -295,7 +295,6 @@ class MeetingActor(
case m: PresentationConversionUpdateSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus)
case m: PresentationPageCountErrorSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus)
case m: PresentationPageGeneratedSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus)
case m: PresentationConversionCompletedSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus)
case m: AssignPresenterReqMsg => handlePresenterChange(m)
// Presentation Pods
@ -304,6 +303,7 @@ class MeetingActor(
case m: GetPresentationInfoReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: GetAllPresentationPodsReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: SetCurrentPresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
case m: PresentationConversionCompletedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus)
// Caption
case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus)

View File

@ -1,17 +1,43 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.apps.PermisssionCheck
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core2.MeetingStatus2x
trait MuteMeetingCmdMsgHdlr {
trait MuteMeetingCmdMsgHdlrDefault {
def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {}
}
trait MuteMeetingCmdMsgHdlrCheckPerm extends MuteMeetingCmdMsgHdlrDefault with SystemConfiguration {
this: MeetingActor =>
val outGW: OutMsgRouter
def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg) {
override def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {
val isAllowed = PermisssionCheck.isAllowed(
PermisssionCheck.MOD_LEVEL,
PermisssionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.body.mutedBy
)
if (applyPermissionCheck && !isAllowed) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to mute meeting."
PermisssionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
} else {
super.handleMuteMeetingCmdMsg(msg)
}
}
}
trait MuteMeetingCmdMsgHdlr extends MuteMeetingCmdMsgHdlrDefault {
this: MeetingActor =>
val outGW: OutMsgRouter
override def handleMuteMeetingCmdMsg(msg: MuteMeetingCmdMsg): Unit = {
def build(meetingId: String, userId: String, muted: Boolean, mutedBy: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)

View File

@ -166,11 +166,12 @@ object MsgBuilder {
BbbCommonEnvCoreMsg(envelope, event)
}
def buildUserEjectedFromMeetingEvtMsg(meetingId: String, userId: String, ejectedBy: String): BbbCommonEnvCoreMsg = {
def buildUserEjectedFromMeetingEvtMsg(meetingId: String, userId: String,
ejectedBy: String, reason: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(UserEjectedFromMeetingEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserEjectedFromMeetingEvtMsg.NAME, meetingId, userId)
val body = UserEjectedFromMeetingEvtMsgBody(userId, ejectedBy)
val body = UserEjectedFromMeetingEvtMsgBody(userId, ejectedBy, reason)
val event = UserEjectedFromMeetingEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)

View File

@ -1,8 +1,22 @@
package org.bigbluebutton.core2.message.senders
import org.bigbluebutton.common2.msgs.BbbCommonEnvCoreMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.OutMsgRouter
trait Sender {
object Sender {
def sendUserEjectedFromMeetingClientEvtMsg(meetingId: String, userId: String,
ejectedBy: String, reason: String, outGW: OutMsgRouter): Unit = {
val ejectFromMeetingClientEvent = MsgBuilder.buildUserEjectedFromMeetingEvtMsg(
meetingId, userId, ejectedBy, reason
)
outGW.send(ejectFromMeetingClientEvent)
}
def sendUserEjectedFromMeetingSystemMsg(meetingId: String, userId: String,
ejectedBy: String, outGW: OutMsgRouter): Unit = {
val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(
meetingId, userId, ejectedBy
)
outGW.send(ejectFromMeetingSystemEvent)
}
}

View File

@ -127,7 +127,7 @@ case class UserEmojiChangedEvtMsgBody(userId: String, emoji: String)
*/
object UserEjectedFromMeetingEvtMsg { val NAME = "UserEjectedFromMeetingEvtMsg" }
case class UserEjectedFromMeetingEvtMsg(header: BbbClientMsgHeader, body: UserEjectedFromMeetingEvtMsgBody) extends StandardMsg
case class UserEjectedFromMeetingEvtMsgBody(userId: String, ejectedBy: String)
case class UserEjectedFromMeetingEvtMsgBody(userId: String, ejectedBy: String, reason: String)
object AssignPresenterReqMsg { val NAME = "AssignPresenterReqMsg"}
case class AssignPresenterReqMsg(header: BbbClientMsgHeader, body: AssignPresenterReqMsgBody) extends StandardMsg