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 d6a91eacdbc6..d62b92a7ecba 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 @@ -31,7 +31,7 @@ trait ChangeUserRoleCmdMsgHdlr extends RightsManagementTrait { } yield { RegisteredUsers.updateUserRole(liveMeeting.registeredUsers, u, userRole) } - val promoteGuest = !liveMeeting.props.usersProp.authenticatedGuest + val promoteGuest = !liveMeeting.props.usersProp.authenticatedGuest || liveMeeting.props.usersProp.allowPromoteGuestToModerator if (msg.body.role == Roles.MODERATOR_ROLE && (!uvo.guest || promoteGuest)) { // Promote non-guest users. val notifyEvent = MsgBuilder.buildNotifyUserInMeetingEvtMsg( diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala index 37cebe559871..cbfab07a53ca 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala @@ -19,7 +19,8 @@ case class MeetingUsersPoliciesDbModel( meetingLayout: String, allowModsToUnmuteUsers: Boolean, allowModsToEjectCameras: Boolean, - authenticatedGuest: Boolean + authenticatedGuest: Boolean, + allowPromoteGuestToModerator: Boolean ) class MeetingUsersPoliciesDbTableDef(tag: Tag) extends Table[MeetingUsersPoliciesDbModel](tag, "meeting_usersPolicies") { @@ -34,10 +35,11 @@ class MeetingUsersPoliciesDbTableDef(tag: Tag) extends Table[MeetingUsersPolicie val allowModsToUnmuteUsers = column[Boolean]("allowModsToUnmuteUsers") val allowModsToEjectCameras = column[Boolean]("allowModsToEjectCameras") val authenticatedGuest = column[Boolean]("authenticatedGuest") + val allowPromoteGuestToModerator = column[Boolean]("allowPromoteGuestToModerator") // val fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId) - override val * : ProvenShape[MeetingUsersPoliciesDbModel] = (meetingId, maxUsers, maxUserConcurrentAccesses, webcamsOnlyForModerator, userCameraCap, guestPolicy, guestLobbyMessage, meetingLayout, allowModsToUnmuteUsers, allowModsToEjectCameras, authenticatedGuest) <> (MeetingUsersPoliciesDbModel.tupled, MeetingUsersPoliciesDbModel.unapply) + override val * : ProvenShape[MeetingUsersPoliciesDbModel] = (meetingId, maxUsers, maxUserConcurrentAccesses, webcamsOnlyForModerator, userCameraCap, guestPolicy, guestLobbyMessage, meetingLayout, allowModsToUnmuteUsers, allowModsToEjectCameras, authenticatedGuest, allowPromoteGuestToModerator) <> (MeetingUsersPoliciesDbModel.tupled, MeetingUsersPoliciesDbModel.unapply) } object MeetingUsersPoliciesDAO { @@ -56,6 +58,7 @@ object MeetingUsersPoliciesDAO { allowModsToUnmuteUsers = usersProp.allowModsToUnmuteUsers, allowModsToEjectCameras = usersProp.allowModsToEjectCameras, authenticatedGuest = usersProp.authenticatedGuest, + allowPromoteGuestToModerator = usersProp.allowPromoteGuestToModerator, ) ) ).onComplete { diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala index 68cb33ec8152..7bb4243f7374 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala @@ -44,6 +44,7 @@ trait AppsTestFixtures { val allowModsToUnmuteUsers = false val allowModsToEjectCameras = false val authenticatedGuest = false + val allowPromoteGuestToModerator = false val meetingLayout = "" val captureNotesFilename = s"Room 0${sequence} (Notes)" val captureSlidesFilename = s"Room 0${sequence} (Whiteboard)" @@ -70,7 +71,7 @@ trait AppsTestFixtures { val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, userCameraCap = userCameraCap, guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, allowModsToEjectCameras = allowModsToEjectCameras, - authenticatedGuest = authenticatedGuest, meetingLayout = meetingLayout) + authenticatedGuest = authenticatedGuest, allowPromoteGuestToModerator = allowPromoteGuestToModerator, meetingLayout = meetingLayout) val metadataProp = new MetadataProp(metadata) val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp, diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala index 453f43eb6296..a30922bce345 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala @@ -41,15 +41,16 @@ case class WelcomeProp(welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMe case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean) case class UsersProp( - maxUsers: Int, - maxUserConcurrentAccesses:Int, - webcamsOnlyForModerator: Boolean, - userCameraCap: Int, - guestPolicy: String, - meetingLayout: String, - allowModsToUnmuteUsers: Boolean, - allowModsToEjectCameras: Boolean, - authenticatedGuest: Boolean + maxUsers: Int, + maxUserConcurrentAccesses: Int, + webcamsOnlyForModerator: Boolean, + userCameraCap: Int, + guestPolicy: String, + meetingLayout: String, + allowModsToUnmuteUsers: Boolean, + allowModsToEjectCameras: Boolean, + authenticatedGuest: Boolean, + allowPromoteGuestToModerator: Boolean ) case class MetadataProp(metadata: collection.immutable.Map[String, String]) diff --git a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala index 88cc48c9254c..0cddb749dd52 100755 --- a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala +++ b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/TestFixtures.scala @@ -44,6 +44,7 @@ trait TestFixtures { val keepEvents = false val guestPolicy = "ALWAYS_ASK" val authenticatedGuest = false + val allowPromoteGuestToModerator = false val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo") val captureNotesFilename = s"Room 0${sequence} (Notes)" val captureSlidesFilename = s"Room 0${sequence} (Whiteboard)" @@ -71,7 +72,7 @@ trait TestFixtures { val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart) val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, userCameraCap = userCameraCap, - guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, allowModsToEjectCameras = allowModsToEjectCameras, authenticatedGuest = authenticatedGuest) + guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, allowModsToEjectCameras = allowModsToEjectCameras, authenticatedGuest = authenticatedGuest, allowPromoteGuestToModerator = allowPromoteGuestToModerator) val metadataProp = new MetadataProp(metadata) val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp, usersProp, metadataProp) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java index 098bd4f2bc5f..0c51f71846bc 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java @@ -33,6 +33,7 @@ public class ApiParams { public static final String FREE_JOIN = "freeJoin"; public static final String FULL_NAME = "fullName"; public static final String GUEST_POLICY = "guestPolicy"; + public static final String ALLOW_PROMOTE_GUEST_TO_MODERATOR = "allowPromoteGuestToModerator"; public static final String MEETING_LAYOUT = "meetingLayout"; public static final String IS_BREAKOUT = "isBreakout"; public static final String LOGO = "logo"; 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 28c28380673c..dbf722a79d6e 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 @@ -446,8 +446,8 @@ private void handleCreateMeeting(Meeting m) { m.getWebcamsOnlyForModerator(), m.getMeetingCameraCap(), m.getUserCameraCap(), m.getMaxPinnedCameras(), m.getModeratorPassword(), m.getViewerPassword(), m.getLearningDashboardAccessToken(), m.getCreateTime(), formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(), - m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getModeratorOnlyMessage(), - m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(), + m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getAllowPromoteGuestToModerator(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), + m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(), m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getMeetingExpireWhenLastUserLeftInMinutes(), m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(), m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(), diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 9421955f1aec..9326aa0efd2a 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -79,6 +79,7 @@ public class ParamsProcessorUtil { private String defaultAvatarURL; private String defaultGuestPolicy; private Boolean authenticatedGuest; + private Boolean defaultAllowPromoteGuestToModerator; private String defaultMeetingLayout; private int defaultMeetingDuration; private boolean disableRecordingDefault; @@ -672,6 +673,11 @@ boolean record = processRecordMeeting(params.get(ApiParams.RECORD)); guestPolicy = params.get(ApiParams.GUEST_POLICY); } + Boolean allowPromoteGuestToModerator = defaultAllowPromoteGuestToModerator; + if (!StringUtils.isEmpty(params.get(ApiParams.ALLOW_PROMOTE_GUEST_TO_MODERATOR))) { + allowPromoteGuestToModerator = Boolean.parseBoolean(params.get(ApiParams.ALLOW_PROMOTE_GUEST_TO_MODERATOR)); + } + String presentationUploadExternalDescription = defaultPresentationUploadExternalDescription; if (!StringUtils.isEmpty(params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION))) { presentationUploadExternalDescription = params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION); @@ -760,6 +766,7 @@ boolean record = processRecordMeeting(params.get(ApiParams.RECORD)); .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout) .withGuestPolicy(guestPolicy) .withAuthenticatedGuest(authenticatedGuest) + .withAllowPromoteGuestToModerator(allowPromoteGuestToModerator) .withAllowRequestsWithoutSession(allowRequestsWithoutSession) .withMeetingLayout(meetingLayout) .withBreakoutRoomsParams(breakoutParams) @@ -1290,6 +1297,10 @@ public void setAuthenticatedGuest(Boolean value) { this.authenticatedGuest = value; } + public void setDefaultAllowPromoteGuestToModerator(Boolean value) { + this.defaultAllowPromoteGuestToModerator = value; + } + public void setDefaultMeetingLayout(String meetingLayout) { this.defaultMeetingLayout = meetingLayout; } 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 8ea0af81f6b8..3d45e3b928c9 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 @@ -81,6 +81,7 @@ public class Meeting { private String guestLobbyMessage = ""; private Map usersWithGuestLobbyMessages; private Boolean authenticatedGuest = false; + private Boolean allowPromoteGuestToModerator = false; private String meetingLayout = MeetingLayout.SMART_LAYOUT; private boolean userHasJoined = false; private Map guestUsersWithPositionInWaitingLine; @@ -165,6 +166,7 @@ record = builder.record; isBreakout = builder.isBreakout; guestPolicy = builder.guestPolicy; authenticatedGuest = builder.authenticatedGuest; + allowPromoteGuestToModerator = builder.allowPromoteGuestToModerator; meetingLayout = builder.meetingLayout; allowRequestsWithoutSession = builder.allowRequestsWithoutSession; breakoutRoomsParams = builder.breakoutRoomsParams; @@ -501,6 +503,14 @@ public Boolean getAuthenticatedGuest() { return authenticatedGuest; } + public void setAllowPromoteGuestToModerator(Boolean value) { + allowPromoteGuestToModerator = value; + } + + public Boolean getAllowPromoteGuestToModerator() { + return allowPromoteGuestToModerator; + } + public void setMeetingLayout(String layout) { meetingLayout = layout; } @@ -910,6 +920,7 @@ public static class Builder { private boolean isBreakout; private String guestPolicy; private Boolean authenticatedGuest; + private Boolean allowPromoteGuestToModerator; private Boolean allowRequestsWithoutSession; private String meetingLayout; private BreakoutRoomsParams breakoutRoomsParams; @@ -1096,6 +1107,11 @@ public Builder withAuthenticatedGuest(Boolean authGuest) { return this; } + public Builder withAllowPromoteGuestToModerator(Boolean value) { + allowPromoteGuestToModerator = value; + return this; + } + public Builder withAllowRequestsWithoutSession(Boolean value) { allowRequestsWithoutSession = value; return this; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java index be4af85cc3ad..dd16fc56fc2d 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java @@ -26,7 +26,7 @@ void createMeeting(String meetingID, String externalMeetingID, Integer maxPinnedCameras, String moderatorPass, String viewerPass, String learningDashboardAccessToken, Long createTime, String createDate, Boolean isBreakout, Integer sequence, Boolean freejoin, Map metadata, - String guestPolicy, Boolean authenticatedGuest, String meetingLayout, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage, + String guestPolicy, Boolean authenticatedGuest, Boolean allowPromoteGuestToModerator, String meetingLayout, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage, String dialNumber, Integer maxUsers, Integer maxUserConcurrentAccesses, Integer meetingExpireIfNoUserJoinedInMinutes, Integer meetingExpireWhenLastUserLeftInMinutes, diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/UsersProp2.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/UsersProp2.java index 28b94a1b70bf..4304832f0caf 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/UsersProp2.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/UsersProp2.java @@ -7,6 +7,7 @@ public class UsersProp2 { public final String guestPolicy; public final String meetingLayout; public final boolean authenticatedGuest; + public final boolean allowPromoteGuestToModerator; public final boolean userHasJoined; public final boolean webcamsOnlyForModerator; public final int userCameraCap; @@ -21,6 +22,7 @@ public UsersProp2(int maxUsers, String guestPolicy, String meetingLayout, boolean authenticatedGuest, + boolean allowPromoteGuestToModerator, boolean userHasJoined, Map userCustomData, Map users, @@ -31,6 +33,7 @@ public UsersProp2(int maxUsers, this.guestPolicy = guestPolicy; this.meetingLayout = meetingLayout; this.authenticatedGuest = authenticatedGuest; + this.allowPromoteGuestToModerator = allowPromoteGuestToModerator; this.userHasJoined = userHasJoined; this.userCustomData = userCustomData; this.users = users; diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala index 3679c54dd36d..1330c3386237 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala @@ -130,7 +130,8 @@ class BbbWebApiGWApp( createTime: java.lang.Long, createDate: String, isBreakout: java.lang.Boolean, sequence: java.lang.Integer, freeJoin: java.lang.Boolean, - metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean, meetingLayout: String, + metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean, allowPromoteGuestToModerator: java.lang.Boolean, + meetingLayout: String, welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String, dialNumber: String, maxUsers: java.lang.Integer, @@ -216,7 +217,8 @@ class BbbWebApiGWApp( userCameraCap = userCameraCap.intValue(), guestPolicy = guestPolicy, meetingLayout = meetingLayout, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), allowModsToEjectCameras = allowModsToEjectCameras.booleanValue(), - authenticatedGuest = authenticatedGuest.booleanValue() + authenticatedGuest = authenticatedGuest.booleanValue(), + allowPromoteGuestToModerator = allowPromoteGuestToModerator.booleanValue() ) val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap) diff --git a/bbb-graphql-server/bbb_schema.sql b/bbb-graphql-server/bbb_schema.sql index 18c9bb3cd409..a5588cf90ede 100644 --- a/bbb-graphql-server/bbb_schema.sql +++ b/bbb-graphql-server/bbb_schema.sql @@ -128,16 +128,17 @@ create view "v_meeting_voiceSettings" as select * from meeting_voice; create table "meeting_usersPolicies" ( "meetingId" varchar(100) primary key references "meeting"("meetingId") ON DELETE CASCADE, - "maxUsers" integer, - "maxUserConcurrentAccesses" integer, - "webcamsOnlyForModerator" boolean, - "userCameraCap" integer, - "guestPolicy" varchar(100), - "guestLobbyMessage" text, - "meetingLayout" varchar(100), - "allowModsToUnmuteUsers" boolean, - "allowModsToEjectCameras" boolean, - "authenticatedGuest" boolean + "maxUsers" integer, + "maxUserConcurrentAccesses" integer, + "webcamsOnlyForModerator" boolean, + "userCameraCap" integer, + "guestPolicy" varchar(100), + "guestLobbyMessage" text, + "meetingLayout" varchar(100), + "allowModsToUnmuteUsers" boolean, + "allowModsToEjectCameras" boolean, + "authenticatedGuest" boolean, + "allowPromoteGuestToModerator" boolean ); create index "idx_meeting_usersPolicies_meetingId" on "meeting_usersPolicies"("meetingId"); @@ -153,6 +154,7 @@ SELECT "meeting_usersPolicies"."meetingId", "meeting_usersPolicies"."allowModsToUnmuteUsers", "meeting_usersPolicies"."allowModsToEjectCameras", "meeting_usersPolicies"."authenticatedGuest", + "meeting_usersPolicies"."allowPromoteGuestToModerator", "meeting"."isBreakout" is false "moderatorsCanMuteAudio", "meeting"."isBreakout" is false and "meeting_usersPolicies"."allowModsToUnmuteUsers" is true "moderatorsCanUnmuteAudio" FROM "meeting_usersPolicies" 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 index fb3299a103c7..c778c0d934bb 100644 --- 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 @@ -8,6 +8,7 @@ select_permissions: - allowModsToEjectCameras - allowModsToUnmuteUsers - authenticatedGuest + - allowPromoteGuestToModerator - guestLobbyMessage - guestPolicy - maxUserConcurrentAccesses diff --git a/bigbluebutton-html5/imports/ui/Types/meeting.ts b/bigbluebutton-html5/imports/ui/Types/meeting.ts index 1885e31936e6..c46301c75d0e 100644 --- a/bigbluebutton-html5/imports/ui/Types/meeting.ts +++ b/bigbluebutton-html5/imports/ui/Types/meeting.ts @@ -48,6 +48,7 @@ export interface UsersPolicies { allowModsToEjectCameras: boolean; allowModsToUnmuteUsers: boolean; authenticatedGuest: boolean; + allowPromoteGuestToModerator: boolean; guestPolicy: string; maxUserConcurrentAccesses: number; maxUsers: number; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 08c2bb9bceae..9f150171db68 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -279,6 +279,7 @@ const getUsersProp = () => { 'usersPolicies.allowModsToUnmuteUsers': 1, 'usersPolicies.allowModsToEjectCameras': 1, 'usersPolicies.authenticatedGuest': 1, + 'usersPolicies.allowPromoteGuestToModerator': 1, }, }, ); @@ -289,6 +290,7 @@ const getUsersProp = () => { allowModsToUnmuteUsers: false, allowModsToEjectCameras: false, authenticatedGuest: false, + allowPromoteGuestToModerator: false, }; }; @@ -341,14 +343,18 @@ const getAvailableActions = ( && !isSubjectUserModerator && !isDialInUser && !isBreakoutRoom - && !(isSubjectUserGuest && usersProp.authenticatedGuest); + && !(isSubjectUserGuest + && usersProp.authenticatedGuest + && !usersProp.allowPromoteGuestToModerator); const allowedToDemote = amIModerator && !amISubjectUser && isSubjectUserModerator && !isDialInUser && !isBreakoutRoom - && !(isSubjectUserGuest && usersProp.authenticatedGuest); + && !(isSubjectUserGuest + && usersProp.authenticatedGuest + && !usersProp.allowPromoteGuestToModerator); const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/queries.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/queries.ts index 5f7b189f6c2b..4bf83dee9042 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/queries.ts @@ -20,6 +20,7 @@ subscription MeetingPermissions { allowModsToEjectCameras allowModsToUnmuteUsers authenticatedGuest + allowPromoteGuestToModerator guestPolicy maxUserConcurrentAccesses maxUsers diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts index 82def88c0507..bc62c887bbba 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts @@ -60,14 +60,14 @@ export const generateActionsPermissions = ( && !isSubjectUserModerator && !isDialInUser && !isBreakout - && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest); + && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest && !usersPolicies?.allowPromoteGuestToModerator); const allowedToDemote = amIModerator && !amISubjectUser && isSubjectUserModerator && !isDialInUser && !isBreakout - && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest); + && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest && !usersPolicies?.allowPromoteGuestToModerator); const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED; diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index 2c3570d49414..62ac61adf771 100644 --- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties +++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties @@ -160,6 +160,9 @@ defaultGuestPolicy=ALWAYS_ACCEPT # Enables or disables authenticated guest authenticatedGuest=true +# Allows moderators to promote guests to moderators when authenticatedGuest is enabled +defaultAllowPromoteGuestToModerator=false + #--------------------------------------------------- # Default Meeting Layout # Accepted values are the standard layouts: CUSTOM_LAYOUT, SMART_LAYOUT, PRESENTATION_FOCUS, VIDEO_FOCUS diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index 81e97d4f29cc..25d29ffb8dca 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -165,6 +165,7 @@ with BigBlueButton; if not, see . +