diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala index 802262031a..8c8ba5dcaa 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala @@ -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) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala similarity index 78% rename from akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersDAO.scala rename to akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala index 04145fcfec..27ab5d20c0 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala @@ -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") } } } \ No newline at end of file diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index 7c7e3c977a..9e3525236b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -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) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java index d53682cedf..e42ccfb77a 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java @@ -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 { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java index da93ef6b91..db9bef435b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java @@ -30,6 +30,7 @@ public class User { private String externalUserId; private String fullname; private String role; + private Boolean locked; private String avatarURL; private Map 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; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java index 669e498c47..a019ad572e 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java @@ -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; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserLockedInMeeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserLockedInMeeting.java new file mode 100755 index 0000000000..881a1264ed --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserLockedInMeeting.java @@ -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; + } +} diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala index a7f9d8f5ed..edfb3b371d 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala @@ -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 => diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala index 6e4092228d..dd15781791 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala @@ -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)) } diff --git a/bbb-graphql-server/bbb_schema.sql b/bbb-graphql-server/bbb_schema.sql index e4d5785b6c..974190c992 100644 --- a/bbb-graphql-server/bbb_schema.sql +++ b/bbb-graphql-server/bbb_schema.sql @@ -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, diff --git a/bbb-graphql-server/install-hasura.sh b/bbb-graphql-server/install-hasura.sh index 1054b476b4..b16f2e55d9 100755 --- a/bbb-graphql-server/install-hasura.sh +++ b/bbb-graphql-server/install-hasura.sh @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_chat_user.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_chat_user.yaml index f109e104d8..502bc8a85a 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_chat_user.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_chat_user.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_meeting.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_meeting.yaml index 35ca42ed34..2b750a8547 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_meeting.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_meeting.yaml @@ -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: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_user_connectionStatus.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_user_connectionStatus.yaml index 25831b2a28..ea0e18f29d 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_user_connectionStatus.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_user_connectionStatus.yaml @@ -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: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml index c43fbbeb96..27d90031ef 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_usersPolicies.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_usersPolicies.yaml new file mode 100644 index 0000000000..f9a85f8350 --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_usersPolicies.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_cursor.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_cursor.yaml index 1d6dec7bd2..dee6258f68 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_cursor.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_cursor.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml new file mode 100644 index 0000000000..1e169c3585 --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_camera.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_camera.yaml index 603e25e21e..fede65ba0b 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_camera.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_camera.yaml @@ -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: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml new file mode 100644 index 0000000000..2a9f10119b --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml @@ -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: [] diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_typing_public.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_typing_public.yaml index 12d156b0f1..692b40fa9a 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_typing_public.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_typing_public.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml index 263ae00da7..5c80356f29 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml @@ -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 diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml index 90ea5e2628..2bdcd120b3 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml @@ -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" diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy index fa6b631f61..d2980bed60 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ConnectionController.groovy @@ -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 }