Merge pull request #19159 from gustavotrott/graphql-support-dial-in-user
graphql: Add support for Dial-in user
This commit is contained in:
commit
5a69742983
@ -57,7 +57,7 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration {
|
|||||||
locked = MeetingStatus2x.getPermissions(liveMeeting.status).lockOnJoin,
|
locked = MeetingStatus2x.getPermissions(liveMeeting.status).lockOnJoin,
|
||||||
avatar = "",
|
avatar = "",
|
||||||
color = userColor,
|
color = userColor,
|
||||||
clientType = "",
|
clientType = if (isDialInUser) "dial-in-user" else "",
|
||||||
pickExempted = false,
|
pickExempted = false,
|
||||||
userLeftFlag = UserLeftFlag(false, 0)
|
userLeftFlag = UserLeftFlag(false, 0)
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ import org.bigbluebutton.common2.msgs._
|
|||||||
import org.bigbluebutton.core.models._
|
import org.bigbluebutton.core.models._
|
||||||
import org.bigbluebutton.core.apps.users.UsersApp
|
import org.bigbluebutton.core.apps.users.UsersApp
|
||||||
import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers
|
import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers
|
||||||
|
import org.bigbluebutton.core.db.UserDAO
|
||||||
import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
|
import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
|
||||||
|
|
||||||
trait UserLeftVoiceConfEvtMsgHdlr {
|
trait UserLeftVoiceConfEvtMsgHdlr {
|
||||||
@ -39,6 +40,7 @@ trait UserLeftVoiceConfEvtMsgHdlr {
|
|||||||
UsersApp.guestWaitingLeft(liveMeeting, user.intId, outGW)
|
UsersApp.guestWaitingLeft(liveMeeting, user.intId, outGW)
|
||||||
}
|
}
|
||||||
Users2x.remove(liveMeeting.users2x, user.intId)
|
Users2x.remove(liveMeeting.users2x, user.intId)
|
||||||
|
UserDAO.delete(user.intId)
|
||||||
VoiceApp.removeUserFromVoiceConf(liveMeeting, outGW, msg.body.voiceUserId)
|
VoiceApp.removeUserFromVoiceConf(liveMeeting, outGW, msg.body.voiceUserId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.bigbluebutton.core.apps.voice
|
package org.bigbluebutton.core.apps.voice
|
||||||
|
|
||||||
import org.apache.pekko.actor.{ ActorContext, ActorSystem, Cancellable }
|
import org.apache.pekko.actor.{ActorContext, ActorSystem, Cancellable}
|
||||||
import org.bigbluebutton.SystemConfiguration
|
import org.bigbluebutton.SystemConfiguration
|
||||||
import org.bigbluebutton.LockSettingsUtil
|
import org.bigbluebutton.LockSettingsUtil
|
||||||
import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers
|
import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers
|
||||||
@ -11,8 +11,10 @@ import org.bigbluebutton.common2.msgs._
|
|||||||
import org.bigbluebutton.core.running.{LiveMeeting, MeetingActor, OutMsgRouter}
|
import org.bigbluebutton.core.running.{LiveMeeting, MeetingActor, OutMsgRouter}
|
||||||
import org.bigbluebutton.core.models._
|
import org.bigbluebutton.core.models._
|
||||||
import org.bigbluebutton.core.apps.users.UsersApp
|
import org.bigbluebutton.core.apps.users.UsersApp
|
||||||
|
import org.bigbluebutton.core.db.{UserDAO, UserVoiceDAO}
|
||||||
import org.bigbluebutton.core.util.ColorPicker
|
import org.bigbluebutton.core.util.ColorPicker
|
||||||
import org.bigbluebutton.core.util.TimeUtil
|
import org.bigbluebutton.core.util.TimeUtil
|
||||||
|
|
||||||
import scala.collection.immutable.Map
|
import scala.collection.immutable.Map
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
@ -323,6 +325,8 @@ object VoiceApp extends SystemConfiguration {
|
|||||||
uuid
|
uuid
|
||||||
)
|
)
|
||||||
VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
|
VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState)
|
||||||
|
UserVoiceDAO.update(voiceUserState)
|
||||||
|
UserDAO.updateVoiceUserJoined(voiceUserState)
|
||||||
|
|
||||||
broadcastEvent(voiceUserState)
|
broadcastEvent(voiceUserState)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package org.bigbluebutton.core.apps.voice
|
package org.bigbluebutton.core.apps.voice
|
||||||
|
|
||||||
import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, MessageTypes, Routing, VoiceCallStateEvtMsg, VoiceCallStateEvtMsgBody, VoiceConfCallStateEvtMsg }
|
import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, MessageTypes, Routing, VoiceCallStateEvtMsg, VoiceCallStateEvtMsgBody, VoiceConfCallStateEvtMsg }
|
||||||
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
|
import org.bigbluebutton.core.db.{ UserVoiceConfStateDAO, UserVoiceDAO }
|
||||||
import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
|
import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter }
|
||||||
|
|
||||||
trait VoiceConfCallStateEvtMsgHdlr {
|
trait VoiceConfCallStateEvtMsgHdlr {
|
||||||
@ -38,5 +38,9 @@ trait VoiceConfCallStateEvtMsgHdlr {
|
|||||||
val event = VoiceCallStateEvtMsg(header, body)
|
val event = VoiceCallStateEvtMsg(header, body)
|
||||||
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
|
||||||
outGW.send(msgEvent)
|
outGW.send(msgEvent)
|
||||||
|
|
||||||
|
if (msg.body.userId.nonEmpty) {
|
||||||
|
UserVoiceConfStateDAO.insertOrUpdate(msg.body.userId, msg.body.voiceConf, msg.body.callSession, msg.body.clientSession, msg.body.callState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package org.bigbluebutton.core.db
|
package org.bigbluebutton.core.db
|
||||||
import org.bigbluebutton.core.models.{RegisteredUser}
|
import org.bigbluebutton.core.models.{RegisteredUser, VoiceUserState}
|
||||||
import slick.jdbc.PostgresProfile.api._
|
import slick.jdbc.PostgresProfile.api._
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
@ -106,6 +106,19 @@ object UserDAO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def updateVoiceUserJoined(voiceUserState: VoiceUserState) = {
|
||||||
|
|
||||||
|
DatabaseConnection.db.run(
|
||||||
|
TableQuery[UserDbTableDef]
|
||||||
|
.filter(_.userId === voiceUserState.intId)
|
||||||
|
.map(u => (u.guest, u.guestStatus, u.authed, u.joined))
|
||||||
|
.update((false, "ALLOW", true, true))
|
||||||
|
).onComplete {
|
||||||
|
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user voice table!")
|
||||||
|
case Failure(e) => DatabaseConnection.logger.debug(s"Error updating user voice: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def updateJoinError(userId: String, joinErrorCode: String, joinErrorMessage: String) = {
|
def updateJoinError(userId: String, joinErrorCode: String, joinErrorMessage: String) = {
|
||||||
DatabaseConnection.db.run(
|
DatabaseConnection.db.run(
|
||||||
TableQuery[UserDbTableDef]
|
TableQuery[UserDbTableDef]
|
||||||
@ -120,15 +133,6 @@ object UserDAO {
|
|||||||
|
|
||||||
|
|
||||||
def delete(intId: String) = {
|
def delete(intId: String) = {
|
||||||
// DatabaseConnection.db.run(
|
|
||||||
// TableQuery[UserDbTableDef]
|
|
||||||
// .filter(_.userId === intId)
|
|
||||||
// .delete
|
|
||||||
// ).onComplete {
|
|
||||||
// case Success(rowsAffected) => DatabaseConnection.logger.debug(s"User ${intId} deleted")
|
|
||||||
// case Failure(e) => DatabaseConnection.logger.error(s"Error deleting user ${intId}: $e")
|
|
||||||
// }
|
|
||||||
|
|
||||||
DatabaseConnection.db.run(
|
DatabaseConnection.db.run(
|
||||||
TableQuery[UserDbTableDef]
|
TableQuery[UserDbTableDef]
|
||||||
.filter(_.userId === intId)
|
.filter(_.userId === intId)
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.bigbluebutton.core.db
|
||||||
|
|
||||||
|
import org.bigbluebutton.core.models.{ VoiceUserState }
|
||||||
|
import slick.jdbc.PostgresProfile.api._
|
||||||
|
|
||||||
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
|
import scala.util.{Failure, Success }
|
||||||
|
|
||||||
|
case class UserVoiceConfStateDbModel(
|
||||||
|
userId: String,
|
||||||
|
voiceConf: String,
|
||||||
|
voiceConfCallSession: String,
|
||||||
|
voiceConfClientSession: String,
|
||||||
|
voiceConfCallState: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
class UserVoiceConfStateDbTableDef(tag: Tag) extends Table[UserVoiceConfStateDbModel](tag, None, "user_voice") {
|
||||||
|
override def * = (
|
||||||
|
userId, voiceConf, voiceConfCallSession, voiceConfClientSession, voiceConfCallState
|
||||||
|
) <> (UserVoiceConfStateDbModel.tupled, UserVoiceConfStateDbModel.unapply)
|
||||||
|
val userId = column[String]("userId", O.PrimaryKey)
|
||||||
|
val voiceConf = column[String]("voiceConf")
|
||||||
|
val voiceConfCallSession = column[String]("voiceConfCallSession")
|
||||||
|
val voiceConfClientSession = column[String]("voiceConfClientSession")
|
||||||
|
val voiceConfCallState = column[String]("voiceConfCallState")
|
||||||
|
}
|
||||||
|
|
||||||
|
object UserVoiceConfStateDAO {
|
||||||
|
def insertOrUpdate(userId: String, voiceConf: String, voiceConfCallSession: String, clientSession: String, callState: String) = {
|
||||||
|
DatabaseConnection.db.run(
|
||||||
|
TableQuery[UserVoiceConfStateDbTableDef].insertOrUpdate(
|
||||||
|
UserVoiceConfStateDbModel(
|
||||||
|
userId = userId,
|
||||||
|
voiceConf = voiceConf,
|
||||||
|
voiceConfCallSession = voiceConfCallSession,
|
||||||
|
voiceConfClientSession = clientSession,
|
||||||
|
voiceConfCallState = callState,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).onComplete {
|
||||||
|
case Success(rowsAffected) => {
|
||||||
|
DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_voice table!")
|
||||||
|
}
|
||||||
|
case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting voice: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -7,27 +7,26 @@ import scala.concurrent.ExecutionContext.Implicits.global
|
|||||||
import scala.util.{Failure, Success }
|
import scala.util.{Failure, Success }
|
||||||
|
|
||||||
case class UserVoiceDbModel(
|
case class UserVoiceDbModel(
|
||||||
userId: String,
|
userId: String,
|
||||||
voiceUserId: String,
|
voiceUserId: String,
|
||||||
callerName: String,
|
callerName: String,
|
||||||
callerNum: String,
|
callerNum: String,
|
||||||
callingWith: String,
|
callingWith: String,
|
||||||
joined: Boolean,
|
joined: Boolean,
|
||||||
listenOnly: Boolean,
|
listenOnly: Boolean,
|
||||||
muted: Boolean,
|
muted: Boolean,
|
||||||
spoke: Boolean,
|
spoke: Boolean,
|
||||||
talking: Boolean,
|
talking: Boolean,
|
||||||
floor: Boolean,
|
floor: Boolean,
|
||||||
lastFloorTime: String,
|
lastFloorTime: String,
|
||||||
voiceConf: String,
|
startTime: Option[Long],
|
||||||
startTime: Option[Long],
|
endTime: Option[Long],
|
||||||
endTime: Option[Long],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class UserVoiceDbTableDef(tag: Tag) extends Table[UserVoiceDbModel](tag, None, "user_voice") {
|
class UserVoiceDbTableDef(tag: Tag) extends Table[UserVoiceDbModel](tag, None, "user_voice") {
|
||||||
override def * = (
|
override def * = (
|
||||||
userId, voiceUserId, callerName, callerNum, callingWith, joined, listenOnly,
|
userId, voiceUserId, callerName, callerNum, callingWith, joined, listenOnly,
|
||||||
muted, spoke, talking, floor, lastFloorTime, voiceConf, startTime, endTime
|
muted, spoke, talking, floor, lastFloorTime, startTime, endTime
|
||||||
) <> (UserVoiceDbModel.tupled, UserVoiceDbModel.unapply)
|
) <> (UserVoiceDbModel.tupled, UserVoiceDbModel.unapply)
|
||||||
val userId = column[String]("userId", O.PrimaryKey)
|
val userId = column[String]("userId", O.PrimaryKey)
|
||||||
val voiceUserId = column[String]("voiceUserId")
|
val voiceUserId = column[String]("voiceUserId")
|
||||||
@ -42,6 +41,9 @@ class UserVoiceDbTableDef(tag: Tag) extends Table[UserVoiceDbModel](tag, None, "
|
|||||||
val floor = column[Boolean]("floor")
|
val floor = column[Boolean]("floor")
|
||||||
val lastFloorTime = column[String]("lastFloorTime")
|
val lastFloorTime = column[String]("lastFloorTime")
|
||||||
val voiceConf = column[String]("voiceConf")
|
val voiceConf = column[String]("voiceConf")
|
||||||
|
val voiceConfCallSession = column[String]("voiceConfCallSession")
|
||||||
|
val voiceConfClientSession = column[String]("voiceConfClientSession")
|
||||||
|
val voiceConfCallState = column[String]("voiceConfCallState")
|
||||||
val startTime = column[Option[Long]]("startTime")
|
val startTime = column[Option[Long]]("startTime")
|
||||||
val endTime = column[Option[Long]]("endTime")
|
val endTime = column[Option[Long]]("endTime")
|
||||||
}
|
}
|
||||||
@ -64,7 +66,6 @@ object UserVoiceDAO {
|
|||||||
talking = voiceUserState.talking,
|
talking = voiceUserState.talking,
|
||||||
floor = voiceUserState.floor,
|
floor = voiceUserState.floor,
|
||||||
lastFloorTime = voiceUserState.lastFloorTime,
|
lastFloorTime = voiceUserState.lastFloorTime,
|
||||||
voiceConf = "",
|
|
||||||
startTime = None,
|
startTime = None,
|
||||||
endTime = None
|
endTime = None
|
||||||
)
|
)
|
||||||
@ -85,7 +86,7 @@ object UserVoiceDAO {
|
|||||||
.update((voiceUserState.listenOnly, voiceUserState.muted, voiceUserState.floor, voiceUserState.lastFloorTime))
|
.update((voiceUserState.listenOnly, voiceUserState.muted, voiceUserState.floor, voiceUserState.lastFloorTime))
|
||||||
).onComplete {
|
).onComplete {
|
||||||
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user_voice table!")
|
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user_voice table!")
|
||||||
case Failure(e) => DatabaseConnection.logger.error(s"Error updating user: $e")
|
case Failure(e) => DatabaseConnection.logger.error(s"Error updating user_voice: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,19 @@ object UserVoiceDAO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def deleteUser(userId: String) = {
|
def delete(intId: String) = {
|
||||||
|
DatabaseConnection.db.run(
|
||||||
|
TableQuery[UserDbTableDef]
|
||||||
|
.filter(_.userId === intId)
|
||||||
|
.map(u => (u.loggedOut))
|
||||||
|
.update((true))
|
||||||
|
).onComplete {
|
||||||
|
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated loggedOut=true on user table!")
|
||||||
|
case Failure(e) => DatabaseConnection.logger.error(s"Error updating loggedOut=true user: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def deleteUserVoice(userId: String) = {
|
||||||
//Meteor sets this props instead of removing
|
//Meteor sets this props instead of removing
|
||||||
// muted: false
|
// muted: false
|
||||||
// talking: false
|
// talking: false
|
||||||
@ -124,10 +137,11 @@ object UserVoiceDAO {
|
|||||||
DatabaseConnection.db.run(
|
DatabaseConnection.db.run(
|
||||||
TableQuery[UserVoiceDbTableDef]
|
TableQuery[UserVoiceDbTableDef]
|
||||||
.filter(_.userId === userId)
|
.filter(_.userId === userId)
|
||||||
.delete
|
.map(u => (u.muted, u.talking, u.listenOnly, u.joined, u.spoke, u.startTime, u.endTime))
|
||||||
|
.update((false, false, false, false, false, None, None))
|
||||||
).onComplete {
|
).onComplete {
|
||||||
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Voice of user ${userId} deleted")
|
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Voice of user ${userId} deleted (joined=false)")
|
||||||
case Failure(e) => DatabaseConnection.logger.error(s"Error deleting voice: $e")
|
case Failure(e) => DatabaseConnection.logger.error(s"Error deleting voice user: $e")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ object VoiceUsers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def removeWithIntId(users: VoiceUsers, intId: String): Option[VoiceUserState] = {
|
def removeWithIntId(users: VoiceUsers, intId: String): Option[VoiceUserState] = {
|
||||||
UserVoiceDAO.deleteUser(intId)
|
UserVoiceDAO.deleteUserVoice(intId)
|
||||||
users.remove(intId)
|
users.remove(intId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +250,8 @@ CREATE TABLE "user" (
|
|||||||
"guestLobbyMessage" text,
|
"guestLobbyMessage" text,
|
||||||
"mobile" bool,
|
"mobile" bool,
|
||||||
"clientType" varchar(50),
|
"clientType" varchar(50),
|
||||||
"disconnected" bool, -- this is the old leftFlag (that was renamed), set when the user just closed the client
|
"disconnected" bool default false, -- this is the old leftFlag (that was renamed), set when the user just closed the client
|
||||||
"expired" bool, -- when it is been some time the user is disconnected
|
"expired" bool default false, -- when it is been some time the user is disconnected
|
||||||
"ejected" bool,
|
"ejected" bool,
|
||||||
"ejectReason" varchar(255),
|
"ejectReason" varchar(255),
|
||||||
"ejectReasonCode" varchar(50),
|
"ejectReasonCode" varchar(50),
|
||||||
@ -487,7 +487,7 @@ join meeting_welcome w USING("meetingId");
|
|||||||
|
|
||||||
|
|
||||||
CREATE TABLE "user_voice" (
|
CREATE TABLE "user_voice" (
|
||||||
"userId" varchar(50) PRIMARY KEY NOT NULL REFERENCES "user"("userId") ON DELETE CASCADE,
|
"userId" varchar(50) PRIMARY KEY NOT NULL REFERENCES "user"("userId") ON DELETE CASCADE,
|
||||||
"voiceUserId" varchar(100),
|
"voiceUserId" varchar(100),
|
||||||
"callerName" varchar(100),
|
"callerName" varchar(100),
|
||||||
"callerNum" varchar(100),
|
"callerNum" varchar(100),
|
||||||
@ -500,6 +500,9 @@ CREATE TABLE "user_voice" (
|
|||||||
"floor" boolean,
|
"floor" boolean,
|
||||||
"lastFloorTime" varchar(25),
|
"lastFloorTime" varchar(25),
|
||||||
"voiceConf" varchar(100),
|
"voiceConf" varchar(100),
|
||||||
|
"voiceConfCallSession" varchar(50),
|
||||||
|
"voiceConfClientSession" varchar(10),
|
||||||
|
"voiceConfCallState" varchar(30),
|
||||||
"endTime" bigint,
|
"endTime" bigint,
|
||||||
"startTime" bigint
|
"startTime" bigint
|
||||||
);
|
);
|
||||||
@ -519,7 +522,8 @@ SELECT
|
|||||||
FROM "user" u
|
FROM "user" u
|
||||||
JOIN "user_voice" ON "user_voice"."userId" = u."userId"
|
JOIN "user_voice" ON "user_voice"."userId" = u."userId"
|
||||||
LEFT JOIN "user_voice" user_talking ON (user_talking."userId" = u."userId" and user_talking."talking" IS TRUE)
|
LEFT JOIN "user_voice" user_talking ON (user_talking."userId" = u."userId" and user_talking."talking" IS TRUE)
|
||||||
OR (user_talking."userId" = u."userId" and user_talking."hideTalkingIndicatorAt" > now());
|
OR (user_talking."userId" = u."userId" and user_talking."hideTalkingIndicatorAt" > now())
|
||||||
|
WHERE "user_voice"."joined" is true;
|
||||||
|
|
||||||
CREATE TABLE "user_camera" (
|
CREATE TABLE "user_camera" (
|
||||||
"streamId" varchar(100) PRIMARY KEY,
|
"streamId" varchar(100) PRIMARY KEY,
|
||||||
|
@ -36,6 +36,7 @@ select_permissions:
|
|||||||
- talking
|
- talking
|
||||||
- userId
|
- userId
|
||||||
- voiceConf
|
- voiceConf
|
||||||
|
- voiceConfCallState
|
||||||
- voiceUserId
|
- voiceUserId
|
||||||
filter:
|
filter:
|
||||||
meetingId:
|
meetingId:
|
||||||
|
Loading…
Reference in New Issue
Block a user