From 420b6a9a14b89817139080a136a07e2abe4c9e7e Mon Sep 17 00:00:00 2001
From: Richard Alam <ritzalam@gmail.com>
Date: Mon, 13 Nov 2017 14:25:31 -0800
Subject: [PATCH]  - provide a way to skip whitelist filter in bbb-apps  - tell
 akka-apps to eject user for client that violates whitelist  - when validate
 token fails, disconnect client.

---
 .../core/apps/PermissionCheck.scala           | 14 ++--
 .../CreateBreakoutRoomsCmdMsgHdlr.scala       |  3 +-
 .../breakout/EndAllBreakoutRoomsMsgHdlr.scala |  2 +-
 .../RequestBreakoutJoinURLReqMsgHdlr.scala    |  2 +-
 .../TransferUserToMeetingRequestHdlr.scala    |  2 +-
 .../core/apps/caption/CaptionApp2x.scala      |  4 +-
 .../ClearPublicChatHistoryPubMsgHdlr.scala    |  2 +-
 .../CreateGroupChatReqMsgHdlr.scala           |  2 +-
 .../SendGroupChatMessageMsgHdlr.scala         |  2 +-
 .../apps/layout/BroadcastLayoutMsgHdlr.scala  |  2 +-
 .../apps/polls/HidePollResultReqMsgHdlr.scala |  2 +-
 .../apps/polls/ShowPollResultReqMsgHdlr.scala |  2 +-
 .../polls/StartCustomPollReqMsgHdlr.scala     |  2 +-
 .../core/apps/polls/StartPollReqMsgHdlr.scala |  2 +-
 .../core/apps/polls/StopPollReqMsgHdlr.scala  |  2 +-
 .../CreateNewPresentationPodPubMsgHdlr.scala  |  2 +-
 .../GetAllPresentationPodsReqMsgHdlr.scala    |  2 +-
 .../GetPresentationInfoReqMsgHdlr.scala       |  2 +-
 .../PresentationUploadTokenReqMsgHdlr.scala   |  2 +-
 .../RemovePresentationPodPubMsgHdlr.scala     |  2 +-
 .../RemovePresentationPubMsgHdlr.scala        |  2 +-
 .../ResizeAndMovePagePubMsgHdlr.scala         |  2 +-
 .../SetCurrentPagePubMsgHdlr.scala            |  2 +-
 .../SetCurrentPresentationPubMsgHdlr.scala    |  2 +-
 .../SetPresenterInPodReqMsgHdlr.scala         |  2 +-
 .../ClearSharedNotePubMsgHdlr.scala           |  2 +-
 .../CreateSharedNoteReqMsgHdlr.scala          |  2 +-
 .../DestroySharedNoteReqMsgHdlr.scala         |  2 +-
 .../AddUserToPresenterGroupCmdMsgHdlr.scala   |  2 +-
 .../users/AssignPresenterReqMsgHdlr.scala     |  2 +-
 ...hangeLockSettingsInMeetingCmdMsgHdlr.scala |  2 +-
 .../users/ChangeUserEmojiCmdMsgHdlr.scala     |  2 +-
 .../apps/users/ChangeUserRoleCmdMsgHdlr.scala |  2 +-
 .../EjectUserFromMeetingCmdMsgHdlr.scala      | 62 ++++-----------
 .../users/LockUserInMeetingCmdMsgHdlr.scala   |  2 +-
 .../users/LockUsersInMeetingCmdMsgHdlr.scala  |  2 +-
 .../users/LogoutAndEndMeetingCmdMsgHdlr.scala |  2 +-
 .../core/apps/users/MuteUserCmdMsgHdlr.scala  |  2 +-
 ...moveUserFromPresenterGroupCmdMsgHdlr.scala |  2 +-
 .../users/SetRecordingStatusCmdMsgHdlr.scala  |  2 +-
 .../core/apps/users/UserLeaveReqMsgHdlr.scala |  2 +-
 .../core/apps/users/UsersApp.scala            | 75 ++++++++++++++++++-
 .../users/ValidateAuthTokenReqMsgHdlr.scala   |  4 +-
 .../ClearWhiteboardPubMsgHdlr.scala           |  2 +-
 .../ModifyWhiteboardAccessPubMsgHdlr.scala    |  2 +-
 .../SendCursorPositionPubMsgHdlr.scala        |  2 +-
 .../SendWhiteboardAnnotationPubMsgHdlr.scala  |  2 +-
 .../whiteboard/UndoWhiteboardPubMsgHdlr.scala |  2 +-
 .../core/running/HandlerHelpers.scala         | 17 +----
 .../EjectUserFromVoiceCmdMsgHdlr.scala        |  2 +-
 .../MuteAllExceptPresentersCmdMsgHdlr.scala   |  2 +-
 .../handlers/MuteMeetingCmdMsgHdlr.scala      |  2 +-
 .../guests/GuestsWaitingApprovedMsgHdlr.scala |  2 +-
 .../guests/SetGuestPolicyMsgHdlr.scala        |  2 +-
 .../core2/message/senders/Sender.scala        |  7 +-
 .../client/meeting/UserActor.scala            | 22 ++++--
 .../common2/msgs/SystemMsgs.scala             |  6 ++
 .../bigbluebutton/common2/msgs/UsersMgs.scala |  4 +-
 58 files changed, 181 insertions(+), 131 deletions(-)

diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala
index d93e7272e5..f5df76c482 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala
@@ -1,7 +1,8 @@
 package org.bigbluebutton.core.apps
 
+import org.bigbluebutton.core.apps.users.UsersApp
 import org.bigbluebutton.core.models.{ Roles, UserState, Users2x }
-import org.bigbluebutton.core.running.OutMsgRouter
+import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
 import org.bigbluebutton.core2.message.senders.{ MsgBuilder, Sender }
 
 object PermissionCheck {
@@ -40,23 +41,20 @@ object PermissionCheck {
   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(users, user) + " roleLevel=" + roleLevel)
         val roleLevelCheck = roleToLevel(users, user) >= roleLevel
-
-        println("PERMLEVELCHECK = " + permLevelCheck + " ROLELEVELCHECK=" + roleLevelCheck)
         permLevelCheck && roleLevelCheck
       case None => false
     }
 
   }
 
-  def ejectUserForFailedPermission(meetingId: String, userId: String, reason: String, outGW: OutMsgRouter): Unit = {
+  def ejectUserForFailedPermission(meetingId: String, userId: String, reason: String,
+                                   outGW: OutMsgRouter, liveMeeting: LiveMeeting): Unit = {
     val ejectedBy = "SYSTEM"
 
-    Sender.sendUserEjectedFromMeetingClientEvtMsg(meetingId, userId, ejectedBy, reason, outGW)
+    UsersApp.ejectUserFromMeeting(outGW, liveMeeting, userId, ejectedBy, reason)
     // send a system message to force disconnection
-    Sender.sendUserEjectedFromMeetingSystemMsg(meetingId, userId, ejectedBy, outGW)
+    Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, outGW)
   }
 }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
index 694f42c6d1..7f96bb1444 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala
@@ -17,7 +17,8 @@ trait CreateBreakoutRoomsCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to create breakout room for meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId,
+        reason, outGW, liveMeeting)
       state
     } else {
       state.breakout match {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndAllBreakoutRoomsMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndAllBreakoutRoomsMsgHdlr.scala
index f0c563933b..8d7c2be430 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndAllBreakoutRoomsMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndAllBreakoutRoomsMsgHdlr.scala
@@ -16,7 +16,7 @@ trait EndAllBreakoutRoomsMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to end breakout rooms for meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
       state
     } else {
       for {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala
index f6024e82c4..8677493d9b 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/RequestBreakoutJoinURLReqMsgHdlr.scala
@@ -14,7 +14,7 @@ trait RequestBreakoutJoinURLReqMsgHdlr extends BreakoutHdlrHelpers {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to request breakout room URL for meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         model <- state.breakout
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/TransferUserToMeetingRequestHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/TransferUserToMeetingRequestHdlr.scala
index f44b19f0cc..799cbd7a13 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/TransferUserToMeetingRequestHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/TransferUserToMeetingRequestHdlr.scala
@@ -16,7 +16,7 @@ trait TransferUserToMeetingRequestHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to transfer user to voice breakout."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       processRequest(msg)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala
index d3c6dea2c6..9f4ab013ba 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala
@@ -50,7 +50,7 @@ class CaptionApp2x(implicit val context: ActorContext) extends SystemConfigurati
       && isUserCaptionOwner(liveMeeting, msg.header.userId, msg.body.locale)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to edit caption history in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       val successfulEdit = editCaptionHistory(liveMeeting, msg.header.userId, msg.body.startIndex,
         msg.body.endIndex, msg.body.locale, msg.body.text)
@@ -90,7 +90,7 @@ class CaptionApp2x(implicit val context: ActorContext) extends SystemConfigurati
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to change caption owners."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       updateCaptionOwner(liveMeeting, msg.body.locale, msg.body.localeCode, msg.body.ownerId).foreach(f => {
         broadcastUpdateCaptionOwnerEvent(f._1, f._2.localeCode, f._2.ownerId)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/chat/ClearPublicChatHistoryPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/chat/ClearPublicChatHistoryPubMsgHdlr.scala
index b870a29a79..69074b7607 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/chat/ClearPublicChatHistoryPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/chat/ClearPublicChatHistoryPubMsgHdlr.scala
@@ -23,7 +23,7 @@ trait ClearPublicChatHistoryPubMsgHdlr extends LogHelper with SystemConfiguratio
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to clear chat in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       ChatModel.clearPublicChatHistory(liveMeeting.chatModel)
       broadcastEvent(msg)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala
index 324af77e7f..718d8e3d56 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala
@@ -36,7 +36,7 @@ trait CreateGroupChatReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && chatLocked) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to create a new group chat."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       val newState = for {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala
index c072412443..ca12544d64 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala
@@ -38,7 +38,7 @@ trait SendGroupChatMessageMsgHdlr {
     if (applyPermissionCheck && chatLocked) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to send a message to this group chat."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def makeHeader(name: String, meetingId: String, userId: String): BbbClientMsgHeader = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/layout/BroadcastLayoutMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/layout/BroadcastLayoutMsgHdlr.scala
index 5b2a09ef40..1675deb509 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/layout/BroadcastLayoutMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/layout/BroadcastLayoutMsgHdlr.scala
@@ -16,7 +16,7 @@ trait BroadcastLayoutMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to broadcast layout to meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       Layouts.setCurrentLayout(liveMeeting.layouts, msg.body.layout, msg.header.userId)
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/HidePollResultReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/HidePollResultReqMsgHdlr.scala
index 349f41e627..86cc611467 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/HidePollResultReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/HidePollResultReqMsgHdlr.scala
@@ -26,7 +26,7 @@ trait HidePollResultReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to hide poll result."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         hiddenPollId <- Polls.handleHidePollResultReqMsg(msg.header.userId, msg.body.pollId, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/ShowPollResultReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/ShowPollResultReqMsgHdlr.scala
index 8a2afa3d2f..6fe1e60e35 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/ShowPollResultReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/ShowPollResultReqMsgHdlr.scala
@@ -39,7 +39,7 @@ trait ShowPollResultReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to show poll results."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         (result, annotationProp) <- Polls.handleShowPollResultReqMsg(state, msg.header.userId, msg.body.pollId, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartCustomPollReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartCustomPollReqMsgHdlr.scala
index fe23df602c..c03af16048 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartCustomPollReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartCustomPollReqMsgHdlr.scala
@@ -27,7 +27,7 @@ trait StartCustomPollReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to start custom poll."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         pvo <- Polls.handleStartCustomPollReqMsg(state, msg.header.userId, msg.body.pollId, msg.body.pollType, msg.body.answers, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartPollReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartPollReqMsgHdlr.scala
index 86bb1594f1..30e86fc1b1 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartPollReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StartPollReqMsgHdlr.scala
@@ -28,7 +28,7 @@ trait StartPollReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to start poll."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         pvo <- Polls.handleStartPollReqMsg(state, msg.header.userId, msg.body.pollId, msg.body.pollType, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StopPollReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StopPollReqMsgHdlr.scala
index f248f30916..9b770ccd91 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StopPollReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/polls/StopPollReqMsgHdlr.scala
@@ -26,7 +26,7 @@ trait StopPollReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to stop poll."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       stopPoll(state, msg.header.userId, liveMeeting, bus)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/CreateNewPresentationPodPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/CreateNewPresentationPodPubMsgHdlr.scala
index 5a50724634..711ce74370 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/CreateNewPresentationPodPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/CreateNewPresentationPodPubMsgHdlr.scala
@@ -20,7 +20,7 @@ trait CreateNewPresentationPodPubMsgHdlr extends SystemConfiguration {
     )) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to create new presentation pod."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def buildCreateNewPresentationPodEvtMsg(meetingId: String, ownerId: String, podId: String): BbbCommonEnvCoreMsg = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetAllPresentationPodsReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetAllPresentationPodsReqMsgHdlr.scala
index ab3eddeb07..2b0fe1a2d4 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetAllPresentationPodsReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetAllPresentationPodsReqMsgHdlr.scala
@@ -17,7 +17,7 @@ trait GetAllPresentationPodsReqMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to get all presentation pods from meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def buildGetAllPresentationPodsRespMsg(pods: Vector[PresentationPodVO], requesterId: String): BbbCommonEnvCoreMsg = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetPresentationInfoReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetPresentationInfoReqMsgHdlr.scala
index bcecbfa096..c1ee5d4e24 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetPresentationInfoReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/GetPresentationInfoReqMsgHdlr.scala
@@ -16,7 +16,7 @@ trait GetPresentationInfoReqMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission get presentation info from meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def buildGetPresentationInfoRespMsg(presentations: Vector[PresentationVO], podId: String,
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationUploadTokenReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationUploadTokenReqMsgHdlr.scala
index a9e6194e75..13737f2fe4 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationUploadTokenReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationUploadTokenReqMsgHdlr.scala
@@ -68,7 +68,7 @@ trait PresentationUploadTokenReqMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to request presentation upload token."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       if (userIsAllowedToUploadInPod(msg.body.podId, msg.header.userId)) {
         val token = PresentationPodsApp.generateToken(msg.body.podId, msg.header.userId)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPodPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPodPubMsgHdlr.scala
index 506ad49194..38b2e9dde1 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPodPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPodPubMsgHdlr.scala
@@ -15,7 +15,7 @@ trait RemovePresentationPodPubMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to remove presentation pod from meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def buildRemovePresentationPodEvtMsg(meetingId: String, ownerId: String, podId: String): BbbCommonEnvCoreMsg = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPubMsgHdlr.scala
index cbf090c33c..448cee12a7 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/RemovePresentationPubMsgHdlr.scala
@@ -17,7 +17,7 @@ trait RemovePresentationPubMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to remove presentation from meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def broadcastRemovePresentationEvtMsg(podId: String, userId: String, presentationId: String): Unit = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/ResizeAndMovePagePubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/ResizeAndMovePagePubMsgHdlr.scala
index a9e9b4c04f..4e29a73691 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/ResizeAndMovePagePubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/ResizeAndMovePagePubMsgHdlr.scala
@@ -34,7 +34,7 @@ trait ResizeAndMovePagePubMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to resize and move page."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       val podId: String = msg.body.podId
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPagePubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPagePubMsgHdlr.scala
index 708680a2cd..69ded4bf3a 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPagePubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPagePubMsgHdlr.scala
@@ -19,7 +19,7 @@ trait SetCurrentPagePubMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to set current presentation page."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def broadcastSetCurrentPageEvtMsg(podId: String, presentationId: String, pageId: String, userId: String): Unit = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPresentationPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPresentationPubMsgHdlr.scala
index e211715604..424fb7f042 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPresentationPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetCurrentPresentationPubMsgHdlr.scala
@@ -17,7 +17,7 @@ trait SetCurrentPresentationPubMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to change current presentation."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def broadcastSetCurrentPresentationEvent(podId: String, userId: String, presentationId: String): Unit = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInPodReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInPodReqMsgHdlr.scala
index 0e84548126..a5a67a039a 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInPodReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInPodReqMsgHdlr.scala
@@ -18,7 +18,7 @@ trait SetPresenterInPodReqMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to set presenter in presentation pod."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
       state
     } else {
       def broadcastSetPresenterInPodRespMsg(podId: String, prevPresenterId: String, nextPresenterId: String, requesterId: String): Unit = {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/ClearSharedNotePubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/ClearSharedNotePubMsgHdlr.scala
index 4378354308..1bee3e2250 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/ClearSharedNotePubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/ClearSharedNotePubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait ClearSharedNotePubMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to clear shared notes in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       liveMeeting.notesModel.clearNote(msg.body.noteId) match {
         case Some(noteReport) => broadcastEvent(msg, noteReport)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/CreateSharedNoteReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/CreateSharedNoteReqMsgHdlr.scala
index 4bd2c1f3e1..ed1f5df7fb 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/CreateSharedNoteReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/CreateSharedNoteReqMsgHdlr.scala
@@ -25,7 +25,7 @@ trait CreateSharedNoteReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to create new shared note."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       if (!liveMeeting.notesModel.isNotesLimit) {
         val (noteId, isNotesLimit) = liveMeeting.notesModel.createNote(msg.body.noteName)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/DestroySharedNoteReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/DestroySharedNoteReqMsgHdlr.scala
index d678721cbc..4721c712fc 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/DestroySharedNoteReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/sharednotes/DestroySharedNoteReqMsgHdlr.scala
@@ -25,7 +25,7 @@ trait DestroySharedNoteReqMsgHdlr extends SystemConfiguration {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to destory shared note."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       val isNotesLimit = liveMeeting.notesModel.destroyNote(msg.body.noteId)
       broadcastEvent(msg, isNotesLimit)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AddUserToPresenterGroupCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AddUserToPresenterGroupCmdMsgHdlr.scala
index c73a32f7f2..c14a41c815 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AddUserToPresenterGroupCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AddUserToPresenterGroupCmdMsgHdlr.scala
@@ -16,7 +16,7 @@ trait AddUserToPresenterGroupCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to add user to presenter group."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       val userId = msg.body.userId
       val requesterId = msg.body.requesterId
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AssignPresenterReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AssignPresenterReqMsgHdlr.scala
index dbe2634af6..c112a1cc34 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AssignPresenterReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/AssignPresenterReqMsgHdlr.scala
@@ -48,7 +48,7 @@ trait AssignPresenterReqMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to change presenter in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         oldPres <- Users2x.findPresenter(this.liveMeeting.users2x)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeLockSettingsInMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeLockSettingsInMeetingCmdMsgHdlr.scala
index 7de83f9646..b8dfac3f4e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeLockSettingsInMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeLockSettingsInMeetingCmdMsgHdlr.scala
@@ -27,7 +27,7 @@ trait ChangeLockSettingsInMeetingCmdMsgHdlrCheckPerm
     if (applyPermissionCheck && !isAllowed) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to change lock settings"
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.setBy, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.setBy, reason, outGW, liveMeeting)
     } else {
       super.handleSetLockSettings(msg)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala
index aef749dc67..6926031849 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala
@@ -17,7 +17,7 @@ trait ChangeUserEmojiCmdMsgHdlr extends SystemConfiguration {
     if (msg.header.userId != msg.body.userId && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to clear chat in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         uvo <- Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, msg.body.emoji)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRoleCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRoleCmdMsgHdlr.scala
index ad92dcde37..dd27fdd170 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRoleCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRoleCmdMsgHdlr.scala
@@ -15,7 +15,7 @@ trait ChangeUserRoleCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to change user role in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         uvo <- Users2x.changeRole(liveMeeting.users2x, msg.body.userId, msg.body.role)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala
index 3706a2110d..ec170379a9 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala
@@ -13,54 +13,24 @@ trait EjectUserFromMeetingCmdMsgHdlr {
   val outGW: OutMsgRouter
 
   def handleEjectUserFromMeetingCmdMsg(msg: EjectUserFromMeetingCmdMsg) {
-    if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
-      val meetingId = liveMeeting.props.meetingProp.intId
-      val reason = "No permission to eject user from meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
-    } else {
-      for {
-        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
-        Sender.sendUserEjectedFromMeetingClientEvtMsg(
-          liveMeeting.props.meetingProp.intId,
-          user.intId, msg.body.ejectedBy, reason, outGW
-        )
-
-        log.info("Ejecting user from meeting (client msg).  meetingId=" + liveMeeting.props.meetingProp.intId +
-          " userId=" + msg.body.userId)
-
-        // send a system message to force disconnection
-        Sender.sendUserEjectedFromMeetingSystemMsg(
-          liveMeeting.props.meetingProp.intId,
-          user.intId, msg.body.ejectedBy, outGW
-        )
+    val meetingId = liveMeeting.props.meetingProp.intId
+    val userId = msg.body.userId
+    val ejectedBy = msg.body.ejectedBy
 
-        log.info("Ejecting user from meeting (system msg).  meetingId=" + liveMeeting.props.meetingProp.intId +
-          " userId=" + msg.body.userId)
+    if (applyPermissionCheck && !PermissionCheck.isAllowed(
+      PermissionCheck.MOD_LEVEL,
+      PermissionCheck.VIEWER_LEVEL,
+      liveMeeting.users2x,
+      msg.header.userId
+    )) {
 
-        // send a user left event for the clients to update
-        val userLeftMeetingEvent = MsgBuilder.buildUserLeftMeetingEvtMsg(liveMeeting.props.meetingProp.intId, user.intId)
-        outGW.send(userLeftMeetingEvent)
-        log.info("User left meetingId=" + liveMeeting.props.meetingProp.intId + " userId=" + msg.body.userId)
-
-        for {
-          vu <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
-        } yield {
-          val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(
-            liveMeeting.props.meetingProp.intId,
-            liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId
-          )
-          outGW.send(ejectFromVoiceEvent)
-          log.info("Ejecting user from voice.  meetingId=" + liveMeeting.props.meetingProp.intId + " userId=" + vu.intId)
-        }
-
-        if (user.presenter) {
-          automaticallyAssignPresenter(outGW, liveMeeting)
-        }
-      }
+      val reason = "No permission to eject user from meeting."
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
+    } else {
+      val reason = "user ejected by another user"
+      UsersApp.ejectUserFromMeeting(outGW, liveMeeting, userId, ejectedBy, reason)
+      // send a system message to force disconnection
+      Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, outGW)
     }
   }
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUserInMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUserInMeetingCmdMsgHdlr.scala
index 5c87548eab..fe5f77b877 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUserInMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUserInMeetingCmdMsgHdlr.scala
@@ -25,7 +25,7 @@ trait LockUserInMeetingCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to lock user in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         uvo <- Users2x.setUserLocked(liveMeeting.users2x, msg.body.userId, msg.body.lock)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUsersInMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUsersInMeetingCmdMsgHdlr.scala
index 518e3520ec..793ceb6841 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUsersInMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LockUsersInMeetingCmdMsgHdlr.scala
@@ -25,7 +25,7 @@ trait LockUsersInMeetingCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to lock users in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       val usersToLock = Users2x.findAll(liveMeeting.users2x).filter(u => !msg.body.except.toSet(u))
       usersToLock foreach { utl =>
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LogoutAndEndMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LogoutAndEndMeetingCmdMsgHdlr.scala
index d1a4e6a7bb..af61dfbe70 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LogoutAndEndMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/LogoutAndEndMeetingCmdMsgHdlr.scala
@@ -18,7 +18,7 @@ trait LogoutAndEndMeetingCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to end meeting on logout."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         u <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala
index 04547d0f39..d203f30956 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala
@@ -30,7 +30,7 @@ trait MuteUserCmdMsgHdlrPermCheck extends MuteUserCmdMsgHdlrDefault with SystemC
     if (msg.header.userId != msg.body.userId && applyPermissionCheck && !isAllowed) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to mute user in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW, liveMeeting)
     } else {
       super.handleMuteUserCmdMsg(msg)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RemoveUserFromPresenterGroupCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RemoveUserFromPresenterGroupCmdMsgHdlr.scala
index c61995dca2..50c564bd94 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RemoveUserFromPresenterGroupCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RemoveUserFromPresenterGroupCmdMsgHdlr.scala
@@ -16,7 +16,7 @@ trait RemoveUserFromPresenterGroupCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to remove user from presenter group."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       val userId = msg.body.userId
       val requesterId = msg.body.requesterId
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
index ed4083b1f8..aaf1493087 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala
@@ -17,7 +17,7 @@ trait SetRecordingStatusCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to clear chat in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       if (liveMeeting.props.recordProp.allowStartStopRecording &&
         MeetingStatus2x.isRecording(liveMeeting.status) != msg.body.recording) {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala
index 1b422bf666..64aa2e8492 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala
@@ -30,7 +30,7 @@ trait UserLeaveReqMsgHdlr {
       outGW.send(userLeftMeetingEvent)
 
       if (u.presenter) {
-        automaticallyAssignPresenter(outGW, liveMeeting)
+        UsersApp.automaticallyAssignPresenter(outGW, liveMeeting)
 
         // request screenshare to end
         screenshareApp2x.handleScreenshareStoppedVoiceConfEvtMsg(
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
index 45c157ee99..1db210c84f 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala
@@ -4,9 +4,10 @@ import akka.actor.ActorContext
 import akka.event.Logging
 import org.bigbluebutton.common2.msgs._
 import org.bigbluebutton.core.bus.InternalEventBus
+import org.bigbluebutton.core.domain.MeetingState2x
 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 }
 
 object UsersApp {
   def broadcastAddUserToPresenterGroup(meetingId: String, userId: String, requesterId: String,
@@ -49,6 +50,78 @@ object UsersApp {
     }
   }
 
+  def automaticallyAssignPresenter(outGW: OutMsgRouter, liveMeeting: LiveMeeting): Unit = {
+    val meetingId = liveMeeting.props.meetingProp.intId
+    for {
+      moderator <- Users2x.findModerator(liveMeeting.users2x)
+      newPresenter <- Users2x.makePresenter(liveMeeting.users2x, moderator.intId)
+    } yield {
+      sendPresenterAssigned(outGW, meetingId, newPresenter.intId, newPresenter.name, newPresenter.intId)
+    }
+  }
+
+  def sendPresenterAssigned(outGW: OutMsgRouter, meetingId: String, intId: String, name: String, assignedBy: String): Unit = {
+    def event = MsgBuilder.buildPresenterAssignedEvtMsg(meetingId, intId, name, assignedBy)
+    outGW.send(event)
+  }
+
+  def sendUserEjectedMessageToClient(outGW: OutMsgRouter, meetingId: String,
+                                     userId: String, ejectedBy: String, reason: String): Unit = {
+    // send a message to client
+    Sender.sendUserEjectedFromMeetingClientEvtMsg(
+      meetingId,
+      userId, ejectedBy, reason, outGW
+    )
+  }
+
+  def sendUserLeftMeetingToAllClients(outGW: OutMsgRouter, meetingId: String,
+                                      userId: String): Unit = {
+    // send a user left event for the clients to update
+    val userLeftMeetingEvent = MsgBuilder.buildUserLeftMeetingEvtMsg(meetingId, userId)
+    outGW.send(userLeftMeetingEvent)
+  }
+
+  def sendEjectUserFromVoiceToFreeswitch(
+    outGW:       OutMsgRouter,
+    meetingId:   String,
+    voiceConf:   String,
+    voiceUserId: String
+  ): Unit = {
+    val ejectFromVoiceEvent = MsgBuilder.buildEjectUserFromVoiceConfSysMsg(
+      meetingId,
+      voiceConf,
+      voiceUserId
+    )
+    outGW.send(ejectFromVoiceEvent)
+  }
+
+  def ejectUserFromMeeting(outGW: OutMsgRouter, liveMeeting: LiveMeeting,
+                           userId: String, ejectedBy: String, reason: String): Unit = {
+
+    val meetingId = liveMeeting.props.meetingProp.intId
+
+    for {
+      user <- Users2x.ejectFromMeeting(liveMeeting.users2x, userId)
+    } yield {
+      RegisteredUsers.remove(userId, liveMeeting.registeredUsers)
+      sendUserEjectedMessageToClient(outGW, meetingId, userId, ejectedBy, reason)
+      sendUserLeftMeetingToAllClients(outGW, meetingId, userId)
+      if (user.presenter) {
+        automaticallyAssignPresenter(outGW, liveMeeting)
+      }
+    }
+
+    for {
+      vu <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, userId)
+    } yield {
+      sendEjectUserFromVoiceToFreeswitch(
+        outGW,
+        liveMeeting.props.meetingProp.intId,
+        liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId
+      )
+    }
+  }
+
 }
 
 class UsersApp(
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala
index 45774b8aee..9e3dccb3be 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala
@@ -23,9 +23,11 @@ trait ValidateAuthTokenReqMsgHdlr extends HandlerHelpers {
       case Some(u) =>
         userValidated(u, state)
       case None =>
+
         validateTokenFailed(outGW, meetingId = liveMeeting.props.meetingProp.intId,
           userId = msg.body.userId, authToken = msg.body.authToken,
           valid = false, waitForApproval = false, state)
+
     }
   }
 
@@ -34,7 +36,7 @@ trait ValidateAuthTokenReqMsgHdlr extends HandlerHelpers {
     val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId, userId, authToken, valid, waitForApproval)
     outGW.send(event)
 
-    // TODO: Should disconnect user here.
+    UsersApp.ejectUserFromMeeting(outGW, liveMeeting, userId, "SYSTEM", "Invalid auth token.")
 
     state
   }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClearWhiteboardPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClearWhiteboardPubMsgHdlr.scala
index 76565eec2f..0116cf89ba 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClearWhiteboardPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClearWhiteboardPubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait ClearWhiteboardPubMsgHdlr extends SystemConfiguration {
     if (!getWhiteboardAccess(liveMeeting) && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to clear the whiteboard."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         fullClear <- clearWhiteboard(msg.body.whiteboardId, msg.header.userId, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ModifyWhiteboardAccessPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ModifyWhiteboardAccessPubMsgHdlr.scala
index 3dcada455a..416aa58f3d 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ModifyWhiteboardAccessPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ModifyWhiteboardAccessPubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait ModifyWhiteboardAccessPubMsgHdlr extends SystemConfiguration {
     if (!getWhiteboardAccess(liveMeeting) && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to modify access to the whiteboard."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       modifyWhiteboardAccess(msg.body.multiUser, liveMeeting)
       broadcastEvent(msg)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendCursorPositionPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendCursorPositionPubMsgHdlr.scala
index efade9344e..719e2403a6 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendCursorPositionPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendCursorPositionPubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait SendCursorPositionPubMsgHdlr extends SystemConfiguration {
     if (!getWhiteboardAccess(liveMeeting) && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to send your cursor position."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       broadcastEvent(msg)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendWhiteboardAnnotationPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendWhiteboardAnnotationPubMsgHdlr.scala
index c291baa156..aff4a59043 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendWhiteboardAnnotationPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/SendWhiteboardAnnotationPubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait SendWhiteboardAnnotationPubMsgHdlr extends SystemConfiguration {
     if (!getWhiteboardAccess(liveMeeting) && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to send a whiteboard annotation."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       val annotation = sendWhiteboardAnnotation(msg.body.annotation, liveMeeting)
       broadcastEvent(msg, annotation)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/UndoWhiteboardPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/UndoWhiteboardPubMsgHdlr.scala
index 53bc8478d8..455c50ad61 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/UndoWhiteboardPubMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/UndoWhiteboardPubMsgHdlr.scala
@@ -25,7 +25,7 @@ trait UndoWhiteboardPubMsgHdlr extends SystemConfiguration {
     if (!getWhiteboardAccess(liveMeeting) && applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to undo an annotation."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting)
     } else {
       for {
         lastAnnotation <- undoWhiteboard(msg.body.whiteboardId, msg.header.userId, liveMeeting)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
index ec8374f12a..fd7421b1bf 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala
@@ -53,7 +53,7 @@ trait HandlerHelpers extends SystemConfiguration {
         outGW.send(event)
         startRecordingIfAutoStart2x(outGW, liveMeeting)
         if (!Users2x.hasPresenter(liveMeeting.users2x)) {
-          automaticallyAssignPresenter(outGW, liveMeeting)
+          UsersApp.automaticallyAssignPresenter(outGW, liveMeeting)
         }
 
         if (newUser.role == Roles.MODERATOR_ROLE) {
@@ -91,21 +91,6 @@ trait HandlerHelpers extends SystemConfiguration {
     }
   }
 
-  def automaticallyAssignPresenter(outGW: OutMsgRouter, liveMeeting: LiveMeeting): Unit = {
-    val meetingId = liveMeeting.props.meetingProp.intId
-    for {
-      moderator <- Users2x.findModerator(liveMeeting.users2x)
-      newPresenter <- Users2x.makePresenter(liveMeeting.users2x, moderator.intId)
-    } yield {
-      sendPresenterAssigned(outGW, meetingId, newPresenter.intId, newPresenter.name, newPresenter.intId)
-    }
-  }
-
-  def sendPresenterAssigned(outGW: OutMsgRouter, meetingId: String, intId: String, name: String, assignedBy: String): Unit = {
-    def event = MsgBuilder.buildPresenterAssignedEvtMsg(meetingId, intId, name, assignedBy)
-    outGW.send(event)
-  }
-
   def endMeeting(outGW: OutMsgRouter, liveMeeting: LiveMeeting, reason: String): Unit = {
     def buildMeetingEndingEvtMsg(meetingId: String): BbbCommonEnvCoreMsg = {
       val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used")
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/EjectUserFromVoiceCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/EjectUserFromVoiceCmdMsgHdlr.scala
index 1d761ec210..15aef5dd8a 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/EjectUserFromVoiceCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/EjectUserFromVoiceCmdMsgHdlr.scala
@@ -17,7 +17,7 @@ trait EjectUserFromVoiceCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to eject the voice user."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       for {
         u <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala
index 0f1440edcb..6e441b0f73 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala
@@ -15,7 +15,7 @@ trait MuteAllExceptPresentersCmdMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to mute all except presenters."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       if (MeetingStatus2x.isMeetingMuted(liveMeeting.status)) {
         MeetingStatus2x.unmuteMeeting(liveMeeting.status)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala
index 4a57796739..f2a5974829 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala
@@ -25,7 +25,7 @@ trait MuteMeetingCmdMsgHdlrCheckPerm extends MuteMeetingCmdMsgHdlrDefault with S
     if (applyPermissionCheck && !isAllowed) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to mute meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.body.mutedBy, reason, outGW, liveMeeting)
     } else {
       super.handleMuteMeetingCmdMsg(msg)
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestsWaitingApprovedMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestsWaitingApprovedMsgHdlr.scala
index bff3be7f72..ba6b755cae 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestsWaitingApprovedMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestsWaitingApprovedMsgHdlr.scala
@@ -17,7 +17,7 @@ trait GuestsWaitingApprovedMsgHdlr extends HandlerHelpers {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to approve or deny guests in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       msg.body.guests foreach { g =>
         for {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestPolicyMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestPolicyMsgHdlr.scala
index 9aa611fb99..a1369f157f 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestPolicyMsgHdlr.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestPolicyMsgHdlr.scala
@@ -17,7 +17,7 @@ trait SetGuestPolicyMsgHdlr {
     if (applyPermissionCheck && !PermissionCheck.isAllowed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
       val meetingId = liveMeeting.props.meetingProp.intId
       val reason = "No permission to set guest policy in meeting."
-      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW)
+      PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
     } else {
       val newPolicy = msg.body.policy.toUpperCase()
       if (GuestPolicyType.policyTypes.contains(newPolicy)) {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala
index 43ce3bfe42..ff19a919bd 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala
@@ -5,15 +5,16 @@ import org.bigbluebutton.core.running.OutMsgRouter
 object Sender {
 
   def sendUserEjectedFromMeetingClientEvtMsg(meetingId: String, userId: String,
-                                             ejectedBy: String, reason: String, outGW: OutMsgRouter): Unit = {
+                                             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 = {
+  def sendDisconnectClientSysMsg(meetingId: String, userId: String,
+                                 ejectedBy: String, outGW: OutMsgRouter): Unit = {
     val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(
       meetingId, userId, ejectedBy
     )
diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala
index c38e427c4d..219077b364 100755
--- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala
+++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala
@@ -29,7 +29,7 @@ class UserActor(val userId: String,
 
     case msg: ConnectMsg => handleConnectMsg(msg)
     case msg: DisconnectMsg => handleDisconnectMsg(msg)
-    case msg: MsgFromClientMsg => handleMsgFromClientMsg(msg)
+    case msg: MsgFromClientMsg => handleMsgFromClientMsg(msg, true)
     case msg: BbbCommonEnvJsNodeMsg => handleBbbServerMsg(msg)
     case _ => log.debug("***** UserActor cannot handle msg ")
   }
@@ -66,7 +66,7 @@ class UserActor(val userId: String,
     if (Connections.noMoreConnections(conns)) {
       val json = buildUserLeavingMessage(msg.connInfo)
       val msgFromClient = MsgFromClientMsg(msg.connInfo, json)
-      handleMsgFromClientMsg(msgFromClient)
+      handleMsgFromClientMsg(msgFromClient, false)
     }
   }
 
@@ -77,10 +77,20 @@ class UserActor(val userId: String,
     JsonUtil.toJson(event)
   }
 
+  private def buildEjectUserFromMeetingSysMsg(meetingId: String, userId: String): String = {
+    val header = BbbClientMsgHeader(EjectUserFromMeetingSysMsg.NAME, meetingId, userId)
+    val body = EjectUserFromMeetingSysMsgBody(userId, "bbb-apps")
+    val event = EjectUserFromMeetingSysMsg(header, body)
+    JsonUtil.toJson(event)
+  }
 
-  def handleMsgFromClientMsg(msg: MsgFromClientMsg):Unit = {
-
+  private def sendEjectUserFromMeetingToAkkaApps(connInfo: ConnInfo, meetingId: String, userId: String): Unit = {
+    val json = buildEjectUserFromMeetingSysMsg(meetingId, userId)
+    val msgFromClient = MsgFromClientMsg(connInfo, json)
+    handleMsgFromClientMsg(msgFromClient, false)
+  }
 
+  def handleMsgFromClientMsg(msg: MsgFromClientMsg, applyWhitelist: Boolean):Unit = {
     def convertToJsonNode(json: String): Option[JsonNode] = {
       JsonUtil.toJsonNode(json) match {
         case Success(jsonNode) => Some(jsonNode)
@@ -94,13 +104,15 @@ class UserActor(val userId: String,
     val (result, error) = Deserializer.toBbbCoreMessageFromClient(msg.json)
     result match {
       case Some(msgFromClient) =>
-        if (!AllowedMessageNames.MESSAGES.contains(msgFromClient.header.name)) {
+        if (applyWhitelist && !AllowedMessageNames.MESSAGES.contains(msgFromClient.header.name)) {
           // If the message that the client sends isn't allowed disconnect them.
           log.error("User (" + userId + ") tried to send a non-whitelisted message with name=[" + msgFromClient.header.name + "] attempting to disconnect them")
           for {
             conn <- Connections.findActiveConnection(conns)
           } yield {
             msgToClientEventBus.publish(MsgToClientBusMsg(toClientChannel, DisconnectClientMsg(meetingId, conn.connId)))
+            // Tell Akka apps to eject user from meeting.
+            sendEjectUserFromMeetingToAkkaApps(msg.connInfo, meetingId, userId)
           }
         } else {
           // Override the meetingId and userId on the message from client. This
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 333c95a5d8..9eca952d63 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
@@ -70,6 +70,12 @@ case class MeetingDestroyedEvtMsg(header: BbbCoreBaseHeader,
                                 body: MeetingDestroyedEvtMsgBody) extends BbbCoreMsg
 case class MeetingDestroyedEvtMsgBody(meetingId: String)
 
+/**
+  * System server side message to eject user from meeting.
+  */
+object EjectUserFromMeetingSysMsg { val NAME = "EjectUserFromMeetingSysMsg" }
+case class EjectUserFromMeetingSysMsg(header: BbbClientMsgHeader, body: EjectUserFromMeetingSysMsgBody) extends StandardMsg
+case class EjectUserFromMeetingSysMsgBody(userId: String, ejectedBy: String)
 
 object DisconnectAllClientsSysMsg { val NAME = "DisconnectAllClientsSysMsg"}
 case class DisconnectAllClientsSysMsg(header: BbbCoreHeaderWithMeetingId,
diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala
index 72575cdbdb..84080184a6 100755
--- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala
+++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMgs.scala
@@ -236,7 +236,9 @@ object UserJoinMeetingAfterReconnectReqMsg { val NAME = "UserJoinMeetingAfterRec
 case class UserJoinMeetingAfterReconnectReqMsg(header: BbbClientMsgHeader, body: UserJoinMeetingAfterReconnectReqMsgBody) extends StandardMsg
 case class UserJoinMeetingAfterReconnectReqMsgBody(userId: String, authToken: String)
 
-
+/**
+  * Sent from bbb-apps when user disconnects from Red5.
+  */
 object UserLeaveReqMsg { val NAME = "UserLeaveReqMsg" }
 case class UserLeaveReqMsg(header: BbbClientMsgHeader, body: UserLeaveReqMsgBody) extends StandardMsg
 case class UserLeaveReqMsgBody(userId: String, sessionId: String)
-- 
GitLab