Apply locksettings-hideUserList as validation on fetch users in Hasura

This commit is contained in:
Gustavo Trott 2023-04-12 11:07:54 -03:00
parent b230286d95
commit 63bc1593d5
24 changed files with 345 additions and 43 deletions

View File

@ -75,7 +75,7 @@ object MeetingDAO {
).onComplete {
case Success(rowsAffected) => {
DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in Meeting table!")
MeetingUsersDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp)
MeetingUsersPoliciesDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp)
MeetingLockSettingsDAO.insert(meetingProps.meetingProp.intId, meetingProps.lockSettingsProps)
MeetingMetadataDAO.insert(meetingProps.meetingProp.intId, meetingProps.metadataProp)
MeetingRecordingDAO.insert(meetingProps.meetingProp.intId, meetingProps.recordProp)

View File

@ -7,7 +7,7 @@ import slick.lifted.{ ProvenShape }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success }
case class MeetingUsersDbModel(
case class MeetingUsersPoliciesDbModel(
meetingId: String,
maxUsers: Int,
maxUserConcurrentAccesses: Int,
@ -20,7 +20,7 @@ case class MeetingUsersDbModel(
authenticatedGuest: Boolean
)
class MeetingUsersDbTableDef(tag: Tag) extends Table[MeetingUsersDbModel](tag, "meeting_users") {
class MeetingUsersPoliciesDbTableDef(tag: Tag) extends Table[MeetingUsersPoliciesDbModel](tag, "meeting_usersPolicies") {
val meetingId = column[String]("meetingId", O.PrimaryKey)
val maxUsers = column[Int]("maxUsers")
val maxUserConcurrentAccesses = column[Int]("maxUserConcurrentAccesses")
@ -34,14 +34,14 @@ class MeetingUsersDbTableDef(tag: Tag) extends Table[MeetingUsersDbModel](tag, "
// val fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId)
override val * : ProvenShape[MeetingUsersDbModel] = (meetingId, maxUsers, maxUserConcurrentAccesses, webcamsOnlyForModerator, userCameraCap, guestPolicy, meetingLayout, allowModsToUnmuteUsers, allowModsToEjectCameras, authenticatedGuest) <> (MeetingUsersDbModel.tupled, MeetingUsersDbModel.unapply)
override val * : ProvenShape[MeetingUsersPoliciesDbModel] = (meetingId, maxUsers, maxUserConcurrentAccesses, webcamsOnlyForModerator, userCameraCap, guestPolicy, meetingLayout, allowModsToUnmuteUsers, allowModsToEjectCameras, authenticatedGuest) <> (MeetingUsersPoliciesDbModel.tupled, MeetingUsersPoliciesDbModel.unapply)
}
object MeetingUsersDAO {
object MeetingUsersPoliciesDAO {
def insert(meetingId:String, usersProp: UsersProp) = {
DatabaseConnection.db.run(
TableQuery[MeetingUsersDbTableDef].forceInsert(
MeetingUsersDbModel(
TableQuery[MeetingUsersPoliciesDbTableDef].forceInsert(
MeetingUsersPoliciesDbModel(
meetingId = meetingId,
maxUsers = usersProp.maxUsers,
maxUserConcurrentAccesses = usersProp.maxUserConcurrentAccesses,
@ -56,9 +56,9 @@ object MeetingUsersDAO {
)
).onComplete {
case Success(rowsAffected) => {
DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingUsers table!")
DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingUsersPolicies table!")
}
case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingUsers: $e")
case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingUsersPolicies: $e")
}
}
}

View File

@ -32,12 +32,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import com.google.gson.JsonObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.bigbluebutton.api.domain.GuestPolicy;
import org.bigbluebutton.api.domain.Meeting;
import org.bigbluebutton.api.domain.Recording;
import org.bigbluebutton.api.domain.RegisteredUser;
import org.bigbluebutton.api.domain.User;
import org.bigbluebutton.api.domain.UserSession;
import org.bigbluebutton.api.domain.*;
import org.bigbluebutton.api.messaging.MessageListener;
import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage;
import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage;
@ -921,7 +916,7 @@ public class MeetingService implements MessageListener {
}
User user = new User(message.userId, message.externalUserId,
message.name, message.role, message.avatarURL, message.guest, message.guestStatus,
message.name, message.role, message.locked, message.avatarURL, message.guest, message.guestStatus,
message.clientType);
if(m.getMaxUsers() > 0 && m.countUniqueExtIds() >= m.getMaxUsers()) {
@ -1041,7 +1036,7 @@ public class MeetingService implements MessageListener {
} else {
if (message.userId.startsWith("v_")) {
// A dial-in user joined the meeting. Dial-in users by convention has userId that starts with "v_".
User vuser = new User(message.userId, message.userId, message.name, "DIAL-IN-USER", "",
User vuser = new User(message.userId, message.userId, message.name, "DIAL-IN-USER", true, "",
true, GuestPolicy.ALLOW, "DIAL-IN");
vuser.setVoiceJoined(true);
m.userJoined(vuser);
@ -1121,6 +1116,21 @@ public class MeetingService implements MessageListener {
log.warn("The meeting {} doesn't exist", message.meetingId);
}
private void userLockedInMeeting(UserLockedInMeeting message) {
Meeting m = getMeeting(message.meetingId);
if (m != null) {
User user = m.getUserById(message.userId);
if (user != null) {
user.setLocked(message.locked);
log.debug("Setting locked flag in meeting {} for participant: {}", message.meetingId, user.getFullname());
return;
}
log.warn("The participant {} doesn't exist in the meeting {}", message.userId, message.meetingId);
return;
}
log.warn("The meeting {} doesn't exist", message.meetingId);
}
private void processMessage(final IMessage message) {
Runnable task = new Runnable() {
public void run() {
@ -1138,6 +1148,8 @@ public class MeetingService implements MessageListener {
updatedStatus((UserStatusChanged) message);
} else if (message instanceof UserRoleChanged) {
userRoleChanged((UserRoleChanged) message);
} else if (message instanceof UserLockedInMeeting) {
userLockedInMeeting((UserLockedInMeeting) message);
} else if (message instanceof UserJoinedVoice) {
userJoinedVoice((UserJoinedVoice) message);
} else if (message instanceof UserLeftVoice) {

View File

@ -27,9 +27,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import org.apache.commons.lang3.RandomStringUtils;
public class Meeting {

View File

@ -30,6 +30,7 @@ public class User {
private String externalUserId;
private String fullname;
private String role;
private Boolean locked;
private String avatarURL;
private Map<String,String> status;
private Boolean guest;
@ -44,6 +45,7 @@ public class User {
String externalUserId,
String fullname,
String role,
Boolean locked,
String avatarURL,
Boolean guest,
String guestStatus,
@ -52,6 +54,7 @@ public class User {
this.externalUserId = externalUserId;
this.fullname = fullname;
this.role = role;
this.locked = locked;
this.avatarURL = avatarURL;
this.guest = guest;
this.guestStatus = guestStatus;
@ -119,6 +122,9 @@ public class User {
public void setRole(String role) {
this.role = role;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
public String getAvatarUrl() {
return avatarURL;

View File

@ -6,6 +6,7 @@ public class UserJoined implements IMessage {
public final String externalUserId;
public final String name;
public final String role;
public final Boolean locked;
public final String avatarURL;
public final Boolean guest;
public final String guestStatus;
@ -17,6 +18,7 @@ public class UserJoined implements IMessage {
String externalUserId,
String name,
String role,
Boolean locked,
String avatarURL,
Boolean guest,
String guestStatus,
@ -26,6 +28,7 @@ public class UserJoined implements IMessage {
this.externalUserId = externalUserId;
this.name = name;
this.role = role;
this.locked = locked;
this.avatarURL = avatarURL;
this.guest = guest;
this.guestStatus = guestStatus;

View File

@ -0,0 +1,13 @@
package org.bigbluebutton.api.messaging.messages;
public class UserLockedInMeeting implements IMessage {
public final String meetingId;
public final String userId;
public final Boolean locked;
public UserLockedInMeeting(String meetingId, String userId, Boolean locked) {
this.meetingId = meetingId;
this.userId = userId;
this.locked = locked;
}
}

View File

@ -86,6 +86,8 @@ class ReceivedJsonMsgHdlrActor(val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEvent
route[UserBroadcastCamStoppedEvtMsg](envelope, jsonNode)
case UserRoleChangedEvtMsg.NAME =>
route[UserRoleChangedEvtMsg](envelope, jsonNode)
case UserLockedInMeetingEvtMsg.NAME =>
route[UserLockedInMeetingEvtMsg](envelope, jsonNode)
case CreateBreakoutRoomSysCmdMsg.NAME =>
route[CreateBreakoutRoomSysCmdMsg](envelope, jsonNode)
case PresentationUploadTokenSysPubMsg.NAME =>

View File

@ -33,6 +33,7 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
case m: UserJoinedVoiceConfToClientEvtMsg => handleUserJoinedVoiceConfToClientEvtMsg(m)
case m: UserLeftVoiceConfToClientEvtMsg => handleUserLeftVoiceConfToClientEvtMsg(m)
case m: UserRoleChangedEvtMsg => handleUserRoleChangedEvtMsg(m)
case m: UserLockedInMeetingEvtMsg => handleUserLockedInMeetingEvtMsg(m)
case m: UserBroadcastCamStartedEvtMsg => handleUserBroadcastCamStartedEvtMsg(m)
case m: UserBroadcastCamStoppedEvtMsg => handleUserBroadcastCamStoppedEvtMsg(m)
case m: CreateBreakoutRoomSysCmdMsg => handleCreateBreakoutRoomSysCmdMsg(m)
@ -122,10 +123,8 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
def handleUserJoinedMeetingEvtMsg(msg: UserJoinedMeetingEvtMsg): Unit = {
olgMsgGW.handle(new UserJoined(msg.header.meetingId, msg.body.intId,
msg.body.extId, msg.body.name, msg.body.role, msg.body.avatar, msg.body.guest,
msg.body.guestStatus,
msg.body.clientType))
msg.body.extId, msg.body.name, msg.body.role, msg.body.locked, msg.body.avatar,
msg.body.guest, msg.body.guestStatus, msg.body.clientType))
}
def handlePresenterUnassignedEvtMsg(msg: PresenterUnassignedEvtMsg): Unit = {
@ -168,6 +167,10 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW)
olgMsgGW.handle(new UserRoleChanged(msg.header.meetingId, msg.body.userId, msg.body.role))
}
def handleUserLockedInMeetingEvtMsg(msg: UserLockedInMeetingEvtMsg): Unit = {
olgMsgGW.handle(new UserLockedInMeeting(msg.header.meetingId, msg.body.userId, msg.body.locked))
}
def handlePresentationUploadTokenSysPubMsg(msg: PresentationUploadTokenSysPubMsg): Unit = {
olgMsgGW.handle(new PresentationUploadToken(msg.body.podId, msg.body.authzToken, msg.body.filename, msg.body.meetingId))
}

View File

@ -21,6 +21,8 @@ DROP VIEW IF EXISTS "v_user_camera";
DROP VIEW IF EXISTS "v_user_voice";
--DROP VIEW IF EXISTS "v_user_whiteboard";
DROP VIEW IF EXISTS "v_user_breakoutRoom";
DROP VIEW IF EXISTS "v_user";
DROP VIEW IF EXISTS "v_user_ref";
DROP TABLE IF EXISTS "user_camera";
DROP TABLE IF EXISTS "user_voice";
--DROP TABLE IF EXISTS "user_whiteboard";
@ -99,7 +101,7 @@ create table "meeting_voice" (
);
create index "idx_meeting_voice_meetingId" on "meeting_voice"("meetingId");
create table "meeting_users" (
create table "meeting_usersPolicies" (
"meetingId" varchar(100) primary key references "meeting"("meetingId") ON DELETE CASCADE,
"maxUsers" integer,
"maxUserConcurrentAccesses" integer,
@ -111,7 +113,9 @@ create table "meeting_users" (
"allowModsToEjectCameras" boolean,
"authenticatedGuest" boolean
);
create index "idx_meeting_users_meetingId" on "meeting_users"("meetingId");
create index "idx_meeting_usersPolicies_meetingId" on "meeting_usersPolicies"("meetingId");
CREATE OR REPLACE VIEW "v_meeting_usersPolicies" AS SELECT * FROM "meeting_usersPolicies";
create table "meeting_metadata"(
"meetingId" varchar(100) references "meeting"("meetingId") ON DELETE CASCADE,
@ -203,8 +207,66 @@ CREATE TABLE "user" (
CREATE INDEX "idx_user_meetingId" ON "user"("meetingId");
--Virtual columns isModerator and isOnline
ALTER TABLE "user" ADD COLUMN "isModerator" boolean GENERATED ALWAYS AS (CASE WHEN "role" = 'MODERATOR' THEN true ELSE false END) STORED;
ALTER TABLE "user" ADD COLUMN "isOnline" boolean GENERATED ALWAYS AS (CASE WHEN "joined" IS true AND "loggedOut" IS false THEN true ELSE false END) STORED;
--ALTER TABLE "user" ADD COLUMN "isModerator" boolean GENERATED ALWAYS AS (CASE WHEN "role" = 'MODERATOR' THEN true ELSE false END) STORED;
--ALTER TABLE "user" ADD COLUMN "isOnline" boolean GENERATED ALWAYS AS (CASE WHEN "joined" IS true AND "loggedOut" IS false THEN true ELSE false END) STORED;
CREATE OR REPLACE VIEW "v_user"
AS SELECT "user"."userId",
"user"."extId",
"user"."meetingId",
"user"."name",
"user"."avatar",
"user"."color",
"user"."emoji",
"user"."guest",
"user"."guestStatus",
"user"."mobile",
"user"."clientType",
"user"."role",
"user"."authed",
"user"."joined",
"user"."leftFlag",
"user"."banned",
"user"."loggedOut",
"user"."registeredOn",
"user"."presenter",
"user"."pinned",
"user"."locked",
CASE WHEN "user"."role" = 'MODERATOR' THEN true ELSE false END "isModerator",
CASE WHEN "user"."joined" IS true AND "user"."loggedOut" IS false THEN true ELSE false END "isOnline"
FROM "user"
WHERE "user"."loggedOut" IS FALSE
AND "user".joined IS TRUE;
CREATE INDEX "idx_v_user_meetingId" ON "user"("meetingId") where "user"."loggedOut" IS FALSE and "user".joined IS TRUE;
--v_user_ref will be used only as foreign key (not possible to fetch this table directly through graphql)
--it is necessary because v_user has some conditions like "lockSettings-hideUserList"
--but viewers still needs to query this users as foreign key of chat, cameras, etc
CREATE OR REPLACE VIEW "v_user_ref"
AS SELECT "user"."userId",
"user"."extId",
"user"."meetingId",
"user"."name",
"user"."avatar",
"user"."color",
"user"."emoji",
"user"."guest",
"user"."guestStatus",
"user"."mobile",
"user"."clientType",
"user"."role",
"user"."authed",
"user"."joined",
"user"."leftFlag",
"user"."banned",
"user"."loggedOut",
"user"."registeredOn",
"user"."presenter",
"user"."pinned",
"user"."locked",
CASE WHEN "user"."role" = 'MODERATOR' THEN true ELSE false END "isModerator",
CASE WHEN "user"."joined" IS true AND "user"."loggedOut" IS false THEN true ELSE false END "isOnline"
FROM "user";
CREATE TABLE "user_voice" (
"userId" varchar(50) PRIMARY KEY NOT NULL REFERENCES "user"("userId") ON DELETE CASCADE,

View File

@ -32,8 +32,15 @@ cp ./graphql.nginx /usr/share/bigbluebutton/nginx
systemctl restart nginx
# Install Hasura graphql as service
wget https://graphql-engine-cdn.hasura.io/server/latest/linux-amd64 -O /usr/local/bin/hasura-graphql-engine
chmod +x /usr/local/bin/hasura-graphql-engine
#wget https://graphql-engine-cdn.hasura.io/server/latest/linux-amd64 -O /usr/local/bin/hasura-graphql-engine
#chmod +x /usr/local/bin/hasura-graphql-engine
git clone --branch v2.22.1 https://github.com/iMDT/hasura-graphql-engine.git
cat hasura-graphql-engine/hasura-graphql.part-a* > hasura-graphql
rm -rf hasura-graphql-engine/
chmod +x hasura-graphql
mv hasura-graphql /usr/local/bin/hasura-graphql-engine
apt-get install -y gnupg2 curl apt-transport-https ca-certificates libkrb5-3 libpq5 libnuma1 unixodbc-dev libmariadb-dev-compat mariadb-client-10.3
cp ./hasura-config.env /etc/default/bbb-graphql-server
cp ./bbb-graphql-server.service /lib/systemd/system/bbb-graphql-server.service

View File

@ -6,11 +6,10 @@ object_relationships:
using:
manual_configuration:
column_mapping:
meetingId: meetingId
userId: userId
insertion_order: null
remote_table:
name: user
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client

View File

@ -11,6 +11,15 @@ object_relationships:
remote_table:
name: v_meeting_lockSettings
schema: public
- name: usersPolicies
using:
manual_configuration:
column_mapping:
meetingId: meetingId
insertion_order: null
remote_table:
name: v_meeting_usersPolicies
schema: public
select_permissions:
- role: bbb_client
permission:

View File

@ -4,7 +4,13 @@ table:
object_relationships:
- name: user
using:
foreign_key_constraint_on: userId
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client
permission:

View File

@ -11,10 +11,10 @@ object_relationships:
using:
manual_configuration:
column_mapping:
participantId: userId
userId: userId
insertion_order: null
remote_table:
name: user
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client

View File

@ -0,0 +1,20 @@
table:
name: v_meeting_usersPolicies
schema: public
select_permissions:
- role: bbb_client
permission:
columns:
- allowModsToEjectCameras
- allowModsToUnmuteUsers
- authenticatedGuest
- webcamsOnlyForModerator
- guestPolicy
- meetingId
- meetingLayout
- maxUserConcurrentAccesses
- maxUsers
- userCameraCap
filter:
meetingId:
_eq: X-Hasura-MeetingId

View File

@ -11,11 +11,10 @@ object_relationships:
using:
manual_configuration:
column_mapping:
meetingId: meetingId
userId: userId
insertion_order: null
remote_table:
name: user
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client

View File

@ -0,0 +1,107 @@
table:
name: v_user
schema: public
configuration:
column_config: {}
custom_column_names: {}
custom_name: user
custom_root_fields: {}
object_relationships:
- name: connectionStatus
using:
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: user_connectionStatus
schema: public
- name: lastBreakoutRoom
using:
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: v_user_breakoutRoom
schema: public
- name: meeting
using:
manual_configuration:
column_mapping:
meetingId: meetingId
insertion_order: null
remote_table:
name: meeting
schema: public
- name: voice
using:
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: v_user_voice
schema: public
array_relationships:
- name: cameras
using:
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: v_user_camera
schema: public
- name: presPagesWritable
using:
manual_configuration:
column_mapping:
meetingId: meetingId
userId: userId
insertion_order: null
remote_table:
name: v_pres_page_writers
schema: public
select_permissions:
- role: bbb_client
permission:
columns:
- registeredOn
- authed
- banned
- guest
- isModerator
- isOnline
- joined
- leftFlag
- locked
- loggedOut
- mobile
- pinned
- presenter
- avatar
- clientType
- color
- emoji
- extId
- guestStatus
- meetingId
- name
- role
- userId
filter:
_and:
- meetingId:
_eq: X-Hasura-MeetingId
- _or:
- meetingId:
_eq: X-Hasura-ModeratorInMeeting
- isModerator:
_eq: true
- meetingId:
_neq: X-Hasura-LockedInMeeting
- meeting:
lockSettings:
hideUserList:
_eq: false

View File

@ -6,6 +6,16 @@ configuration:
custom_column_names: {}
custom_name: user_camera
custom_root_fields: {}
object_relationships:
- name: user
using:
manual_configuration:
column_mapping:
userId: userId
insertion_order: null
remote_table:
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client
permission:

View File

@ -0,0 +1,40 @@
table:
name: v_user_ref
schema: public
configuration:
column_config: {}
custom_column_names: {}
custom_name: user_ref
custom_root_fields: {}
select_permissions:
- role: bbb_client
permission:
columns:
- userId
- extId
- meetingId
- name
- avatar
- color
- emoji
- guest
- guestStatus
- mobile
- clientType
- role
- authed
- joined
- leftFlag
- banned
- loggedOut
- registeredOn
- presenter
- pinned
- locked
- isModerator
- isOnline
filter:
meetingId:
_eq: X-Hasura-MeetingId
query_root_fields: []
subscription_root_fields: []

View File

@ -11,11 +11,10 @@ object_relationships:
using:
manual_configuration:
column_mapping:
meetingId: meetingId
userId: userId
insertion_order: null
remote_table:
name: user
name: v_user
schema: public
select_permissions:
- role: bbb_client

View File

@ -11,11 +11,10 @@ object_relationships:
using:
manual_configuration:
column_mapping:
meetingId: meetingId
userId: userId
insertion_order: null
remote_table:
name: user
name: v_user_ref
schema: public
select_permissions:
- role: bbb_client

View File

@ -1,16 +1,18 @@
- "!include public_chat_user.yaml"
- "!include public_meeting.yaml"
- "!include public_user.yaml"
- "!include public_user_connectionStatus.yaml"
- "!include public_v_chat.yaml"
- "!include public_v_chat_message_private.yaml"
- "!include public_v_chat_message_public.yaml"
- "!include public_v_meeting_lockSettings.yaml"
- "!include public_v_meeting_usersPolicies.yaml"
- "!include public_v_pres_annotation_curr.yaml"
- "!include public_v_pres_annotation_history_curr.yaml"
- "!include public_v_pres_page_cursor.yaml"
- "!include public_v_pres_page_writers.yaml"
- "!include public_v_user.yaml"
- "!include public_v_user_breakoutRoom.yaml"
- "!include public_v_user_camera.yaml"
- "!include public_v_user_ref.yaml"
- "!include public_v_user_typing_public.yaml"
- "!include public_v_user_voice.yaml"

View File

@ -21,10 +21,12 @@ package org.bigbluebutton.web.controllers
import groovy.json.JsonBuilder
import org.bigbluebutton.api.MeetingService
import org.bigbluebutton.api.domain.UserSession
import org.bigbluebutton.api.domain.User
import org.bigbluebutton.api.util.ParamsUtil
import org.bigbluebutton.api.ParamsProcessorUtil
import java.nio.charset.StandardCharsets
class ConnectionController {
MeetingService meetingService
ParamsProcessorUtil paramsProcessorUtil
@ -68,6 +70,8 @@ class ConnectionController {
Boolean allowRequestsWithoutSession = meetingService.getAllowRequestsWithoutSession(sessionToken)
Boolean isSessionTokenInvalid = !session[sessionToken] && !allowRequestsWithoutSession
User u = meetingService.getMeeting(userSession.meetingID).getUserById(userSession.internalUserId)
response.addHeader("Cache-Control", "no-cache")
if (userSession != null && !isSessionTokenInvalid) {
@ -77,7 +81,10 @@ class ConnectionController {
def builder = new JsonBuilder()
builder {
"response" "authorized"
"x-hasura-role" "bbb_client"
"X-Hasura-Role" "bbb_client"
"X-Hasura-Locked" u.locked ? "true" : "false"
"X-Hasura-LockedInMeeting" u.locked ? userSession.meetingID : ""
"X-Hasura-ModeratorInMeeting" u.isModerator() ? userSession.meetingID : ""
"X-Hasura-UserId" userSession.internalUserId
"X-Hasura-MeetingId" userSession.meetingID
}