Store sessionToken in akka-apps (in order to invalidate connections in graphql-middleware)

This commit is contained in:
Gustavo Trott 2023-04-14 15:48:10 -03:00
parent b9c0909b2a
commit e3a2e4b01a
23 changed files with 80 additions and 34 deletions

View File

@ -90,6 +90,13 @@ object PermissionCheck extends SystemConfiguration {
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, reason, outGW)
// Force reconnection with graphql to refresh permissions
for {
regUser <- RegisteredUsers.findWithUserId(userId, liveMeeting.registeredUsers)
} yield {
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.sessionToken, reason, outGW)
}
} else {
// TODO: get this object a context so it can use the akka logging system
println(s"Skipping violation ejection of ${userId} trying to ${reason} in ${meetingId}")

View File

@ -30,6 +30,9 @@ trait EjectUserFromBreakoutInternalMsgHdlr {
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(msg.breakoutId, registeredUser.id, msg.ejectedBy, msg.reasonCode, outGW)
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, msg.reasonCode, outGW)
//send users update to parent meeting
BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus)

View File

@ -70,7 +70,11 @@ trait ChangeUserRoleCmdMsgHdlr extends RightsManagementTrait {
}
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, uvo.intId, "role_changed", outGW)
for {
u <- RegisteredUsers.findWithUserId(uvo.intId, liveMeeting.registeredUsers)
} yield {
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, uvo.intId, u.sessionToken, "role_changed", outGW)
}
}
}
}

View File

@ -72,6 +72,9 @@ trait EjectUserFromMeetingCmdMsgHdlr extends RightsManagementTrait {
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(meetingId, ru.id, ejectedBy, EjectReasonCode.EJECT_USER, outGW)
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, EjectReasonCode.EJECT_USER, outGW)
}
} else {
// User is ejecting self, so just eject this userid not all sessions if joined using multiple
@ -88,6 +91,9 @@ trait EjectUserFromMeetingCmdMsgHdlr extends RightsManagementTrait {
)
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, EjectReasonCode.EJECT_USER, outGW)
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, EjectReasonCode.EJECT_USER, outGW)
}
}
@ -118,5 +124,12 @@ trait EjectUserFromMeetingSysMsgHdlr {
)
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, EjectReasonCode.SYSTEM_EJECT_USER, outGW)
// Force reconnection with graphql to refresh permissions
for {
regUser <- RegisteredUsers.findWithUserId(userId, liveMeeting.registeredUsers)
} yield {
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.sessionToken, EjectReasonCode.SYSTEM_EJECT_USER, outGW)
}
}
}

View File

@ -2,7 +2,7 @@ package org.bigbluebutton.core.apps.users
import org.bigbluebutton.LockSettingsUtil
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.models.{ Users2x, VoiceUsers }
import org.bigbluebutton.core.models.{ RegisteredUsers, Users2x, VoiceUsers }
import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
import org.bigbluebutton.core2.message.senders.Sender
@ -41,7 +41,11 @@ trait LockUserInMeetingCmdMsgHdlr extends RightsManagementTrait {
}
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, uvo.intId, "lock_user_changed", outGW)
for {
u <- RegisteredUsers.findWithUserId(uvo.intId, liveMeeting.registeredUsers)
} yield {
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, uvo.intId, u.sessionToken, "lock_user_changed", outGW)
}
log.info("Lock user. meetingId=" + props.meetingProp.intId + " userId=" + uvo.intId + " locked=" + uvo.locked)
val event = build(props.meetingProp.intId, uvo.intId, msg.body.lockedBy, uvo.locked)

View File

@ -49,6 +49,9 @@ trait RegisterUserReqMsgHdlr {
// send a system message to force disconnection
Sender.sendDisconnectClientSysMsg(meetingId, userToRemove.id, SystemUser.ID, EjectReasonCode.DUPLICATE_USER, outGW)
// Force reconnection with graphql to refresh permissions
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, userToRemove.id, userToRemove.sessionToken, EjectReasonCode.DUPLICATE_USER, outGW)
}
}
}
@ -58,7 +61,7 @@ trait RegisterUserReqMsgHdlr {
val guestStatus = msg.body.guestStatus
val regUser = RegisteredUsers.create(msg.body.intUserId, msg.body.extUserId,
msg.body.name, msg.body.role, msg.body.authToken,
msg.body.name, msg.body.role, msg.body.authToken, msg.body.sessionToken,
msg.body.avatarURL, RandomStringGenerator.randomColor, msg.body.guest, msg.body.authed, guestStatus, msg.body.excludeFromDashboard, false)
checkUserConcurrentAccesses(regUser)

View File

@ -37,7 +37,7 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration {
def registerUserInRegisteredUsers() = {
val regUser = RegisteredUsers.create(msg.body.intId, msg.body.voiceUserId,
msg.body.callerIdName, Roles.VIEWER_ROLE, "", "", userColor,
msg.body.callerIdName, Roles.VIEWER_ROLE, "", "", "", userColor,
true, true, GuestStatus.WAIT, true, false)
RegisteredUsers.add(liveMeeting.registeredUsers, regUser, liveMeeting.props.meetingProp.intId)
}

View File

@ -6,14 +6,15 @@ import org.bigbluebutton.core.domain.BreakoutRoom2x
object RegisteredUsers {
def create(userId: String, extId: String, name: String, roles: String,
token: String, avatar: String, color: String, guest: Boolean, authenticated: Boolean,
authToken: String, sessionToken: String, avatar: String, color: String, guest: Boolean, authenticated: Boolean,
guestStatus: String, excludeFromDashboard: Boolean, loggedOut: Boolean): RegisteredUser = {
new RegisteredUser(
userId,
extId,
name,
roles,
token,
authToken,
sessionToken,
avatar,
color,
guest,
@ -201,6 +202,7 @@ case class RegisteredUser(
name: String,
role: String,
authToken: String,
sessionToken: String,
avatarURL: String,
color: String,
guest: Boolean,

View File

@ -972,6 +972,13 @@ class MeetingActor(
)
Sender.sendDisconnectClientSysMsg(liveMeeting.props.meetingProp.intId, u.intId, SystemUser.ID, EjectReasonCode.USER_INACTIVITY, outGW)
// Force reconnection with graphql to refresh permissions
for {
regUser <- RegisteredUsers.findWithUserId(u.intId, liveMeeting.registeredUsers)
} yield {
Sender.sendInvalidateUserGraphqlConnectionSysMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.sessionToken, EjectReasonCode.USER_INACTIVITY, outGW)
}
}
}
}

View File

@ -246,11 +246,11 @@ object MsgBuilder {
BbbCommonEnvCoreMsg(envelope, event)
}
def buildInvalidateUserGraphqlConnectionSysMsg(meetingId: String, userId: String, reason: String): BbbCommonEnvCoreMsg = {
def buildInvalidateUserGraphqlConnectionSysMsg(meetingId: String, userId: String, sessionToken: String, reason: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.SYSTEM, meetingId, userId)
val envelope = BbbCoreEnvelope(InvalidateUserGraphqlConnectionSysMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(InvalidateUserGraphqlConnectionSysMsg.NAME, meetingId)
val body = InvalidateUserGraphqlConnectionSysMsgBody(meetingId, userId, reason)
val body = InvalidateUserGraphqlConnectionSysMsgBody(meetingId, userId, sessionToken, reason)
val event = InvalidateUserGraphqlConnectionSysMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)

View File

@ -8,12 +8,10 @@ object Sender {
ejectedBy: String, reason: String, outGW: OutMsgRouter): Unit = {
val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(meetingId, userId, ejectedBy, reason)
outGW.send(ejectFromMeetingSystemEvent)
//Disconnect graphql too
sendInvalidateUserGraphqlConnectionSysMsg(meetingId, userId, reason, outGW)
}
def sendInvalidateUserGraphqlConnectionSysMsg(meetingId: String, userId: String, reason: String, outGW: OutMsgRouter): Unit = {
val invalidateUserGraphqlConnectionSysMsg = MsgBuilder.buildInvalidateUserGraphqlConnectionSysMsg(meetingId, userId, reason)
def sendInvalidateUserGraphqlConnectionSysMsg(meetingId: String, userId: String, sessionToken: String, reason: String, outGW: OutMsgRouter): Unit = {
val invalidateUserGraphqlConnectionSysMsg = MsgBuilder.buildInvalidateUserGraphqlConnectionSysMsg(meetingId, userId, sessionToken, reason)
outGW.send(invalidateUserGraphqlConnectionSysMsg)
}

View File

@ -50,12 +50,13 @@ object FakeUserGenerator {
val id = "w_" + RandomStringGenerator.randomAlphanumericString(16)
val extId = RandomStringGenerator.randomAlphanumericString(16)
val authToken = RandomStringGenerator.randomAlphanumericString(16)
val sessionToken = RandomStringGenerator.randomAlphanumericString(16)
val avatarURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" +
RandomStringGenerator.randomAlphanumericString(10) + ".png"
val color = "#ff6242"
val ru = RegisteredUsers.create(userId = id, extId, name, role,
authToken, avatarURL, color, guest, authed, guestStatus = GuestStatus.ALLOW, false, false)
authToken, sessionToken, avatarURL, color, guest, authed, guestStatus = GuestStatus.ALLOW, false, false)
RegisteredUsers.add(users, ru, meetingId)
ru
}

View File

@ -10,11 +10,12 @@ object TestDataGen {
val id = "w_" + RandomStringGenerator.randomAlphanumericString(16)
val extId = RandomStringGenerator.randomAlphanumericString(16)
val authToken = RandomStringGenerator.randomAlphanumericString(16)
val sessionToken = RandomStringGenerator.randomAlphanumericString(16)
val avatarURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" +
RandomStringGenerator.randomAlphanumericString(10) + ".png"
val ru = RegisteredUsers.create(userId = id, extId, name, role,
authToken, avatarURL, guest, authed, GuestStatus.ALLOW, false)
authToken, sessionToken, avatarURL, guest, authed, GuestStatus.ALLOW, false)
RegisteredUsers.add(users, ru, meetingId = "test")
ru

View File

@ -240,7 +240,7 @@ case class InvalidateUserGraphqlConnectionSysMsg(
header: BbbCoreHeaderWithMeetingId,
body: InvalidateUserGraphqlConnectionSysMsgBody
) extends BbbCoreMsg
case class InvalidateUserGraphqlConnectionSysMsgBody(meetingId: String, userId: String, reason: String)
case class InvalidateUserGraphqlConnectionSysMsgBody(meetingId: String, userId: String, sessionToken: String, reason: String)
/**
* Sent from akka-apps to bbb-web to inform a summary of the meeting activities

View File

@ -6,7 +6,7 @@ case class RegisterUserReqMsg(
body: RegisterUserReqMsgBody
) extends BbbCoreMsg
case class RegisterUserReqMsgBody(meetingId: String, intUserId: String, name: String, role: String,
extUserId: String, authToken: String, avatarURL: String,
extUserId: String, authToken: String, sessionToken: String, avatarURL: String,
guest: Boolean, authed: Boolean, guestStatus: String, excludeFromDashboard: Boolean)
object UserRegisteredRespMsg { val NAME = "UserRegisteredRespMsg" }

View File

@ -121,10 +121,10 @@ public class MeetingService implements MessageListener {
public void registerUser(String meetingID, String internalUserId,
String fullname, String role, String externUserID,
String authToken, String avatarURL, Boolean guest,
String authToken, String sessionToken, String avatarURL, Boolean guest,
Boolean authed, String guestStatus, Boolean excludeFromDashboard, Boolean leftGuestLobby) {
handle(new RegisterUser(meetingID, internalUserId, fullname, role,
externUserID, authToken, avatarURL, guest, authed, guestStatus, excludeFromDashboard, leftGuestLobby));
externUserID, authToken, sessionToken, avatarURL, guest, authed, guestStatus, excludeFromDashboard, leftGuestLobby));
Meeting m = getMeeting(meetingID);
if (m != null) {
@ -420,7 +420,7 @@ public class MeetingService implements MessageListener {
private void processRegisterUser(RegisterUser message) {
gw.registerUser(message.meetingID,
message.internalUserId, message.fullname, message.role,
message.externUserID, message.authToken, message.avatarURL, message.guest,
message.externUserID, message.authToken, message.sessionToken, message.avatarURL, message.guest,
message.authed, message.guestStatus, message.excludeFromDashboard);
}

View File

@ -9,6 +9,7 @@ public class RegisterUser implements IMessage {
public final String role;
public final String externUserID;
public final String authToken;
public final String sessionToken;
public final String avatarURL;
public final Boolean guest;
public final Boolean authed;
@ -17,15 +18,16 @@ public class RegisterUser implements IMessage {
public final Boolean leftGuestLobby;
public RegisterUser(String meetingID, String internalUserId, String fullname, String role, String externUserID,
String authToken, String avatarURL, Boolean guest,
String authToken, String sessionToken, String avatarURL, Boolean guest,
Boolean authed, String guestStatus, Boolean excludeFromDashboard, Boolean leftGuestLobby) {
this.meetingID = meetingID;
this.internalUserId = internalUserId;
this.fullname = fullname;
this.role = role;
this.externUserID = externUserID;
this.authToken = authToken;
this.avatarURL = avatarURL;
this.authToken = authToken;
this.sessionToken = sessionToken;
this.avatarURL = avatarURL;
this.guest = guest;
this.authed = authed;
this.guestStatus = guestStatus;

View File

@ -47,7 +47,7 @@ public interface IBbbWebApiGWApp {
String presentationUploadExternalUrl);
void registerUser(String meetingID, String internalUserId, String fullname, String role,
String externUserID, String authToken, String avatarURL,
String externUserID, String authToken, String sessionToken, String avatarURL,
Boolean guest, Boolean authed, String guestStatus, Boolean excludeFromDashboard);
void guestWaitingLeft(String meetingID, String internalUserId);

View File

@ -252,8 +252,8 @@ class BbbWebApiGWApp(
}
def registerUser(meetingId: String, intUserId: String, name: String,
role: String, extUserId: String, authToken: String, avatarURL: String,
guest: java.lang.Boolean, authed: java.lang.Boolean,
role: String, extUserId: String, authToken: String, sessionToken: String,
avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean,
guestStatus: String, excludeFromDashboard: java.lang.Boolean): Unit = {
// meetingManagerActorRef ! new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name,
@ -261,9 +261,9 @@ class BbbWebApiGWApp(
// guest = guest, authed = authed)
val regUser = new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name,
role = role, extUserId = extUserId, authToken = authToken, avatarURL = avatarURL,
guest = guest.booleanValue(), authed = authed.booleanValue(), guestStatus = guestStatus,
excludeFromDashboard = excludeFromDashboard)
role = role, extUserId = extUserId, authToken = authToken, sessionToken = sessionToken,
avatarURL = avatarURL, guest = guest.booleanValue(), authed = authed.booleanValue(),
guestStatus = guestStatus, excludeFromDashboard = excludeFromDashboard)
val event = MsgBuilder.buildRegisterUserRequestToAkkaApps(regUser)
msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event))

View File

@ -39,7 +39,7 @@ object MsgBuilder {
val envelope = BbbCoreEnvelope(RegisterUserReqMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(RegisterUserReqMsg.NAME, msg.meetingId)
val body = RegisterUserReqMsgBody(meetingId = msg.meetingId, intUserId = msg.intUserId,
name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken,
name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken, sessionToken = msg.sessionToken,
avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed, guestStatus = msg.guestStatus,
excludeFromDashboard = msg.excludeFromDashboard)
val req = RegisterUserReqMsg(header, body)

View File

@ -16,7 +16,7 @@ case class CreateBreakoutRoomMsg(meetingId: String, parentMeetingId: String,
case class AddUserSession(token: String, session: UserSession)
case class RegisterUser(meetingId: String, intUserId: String, name: String, role: String,
extUserId: String, authToken: String, avatarURL: String,
extUserId: String, authToken: String, sessionToken: String, avatarURL: String,
guest: Boolean, authed: Boolean, guestStatus: String, excludeFromDashboard: Boolean)
case class CreateMeetingMsg(defaultProps: DefaultProps)

View File

@ -28,8 +28,8 @@ trait ToAkkaAppsSendersTrait extends SystemConfiguration {
val header = BbbCoreHeaderWithMeetingId(RegisterUserReqMsg.NAME, msg.meetingId)
val body = RegisterUserReqMsgBody(meetingId = msg.meetingId, intUserId = msg.intUserId,
name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken,
avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed, guestStatus = msg.guestStatus,
excludeFromDashboard = msg.excludeFromDashboard)
sessionToken = msg.sessionToken, avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed,
guestStatus = msg.guestStatus, excludeFromDashboard = msg.excludeFromDashboard)
val req = RegisterUserReqMsg(header, body)
val message = BbbCommonEnvCoreMsg(envelope, req)
sendToBus(message)

View File

@ -401,6 +401,7 @@ class ApiController {
us.role,
us.externUserID,
us.authToken,
sessionToken,
us.avatarURL,
us.guest,
us.authed,