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 4580a7e885..8f2b382c5b 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 @@ -30,7 +30,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/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index aa84f65a01..df253bdc3d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -399,7 +399,7 @@ class MeetingActor( case m: ChangeUserPinStateReqMsg => usersApp.handleChangeUserPinStateReqMsg(m) case m: ChangeUserMobileFlagReqMsg => usersApp.handleChangeUserMobileFlagReqMsg(m) case m: SetUserSpeechLocaleReqMsg => usersApp.handleSetUserSpeechLocaleReqMsg(m) - case m: SetUserSpeechOptionsReqMsg => usersApp.handleSetUserSpeechOptionsReqMsg(m) + case m: SetUserSpeechOptionsReqMsg => usersApp.handleSetUserSpeechOptionsReqMsg(m) // Client requested to eject user case m: EjectUserFromMeetingCmdMsg => 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 68cb33ec81..7bb4243f73 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 d224b8f3a2..aa25f667fb 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 88cc48c925..e1a6bcdedf 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,8 @@ 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 63e709764e..a6fd09c02d 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 bf918aa949..62883aaf6b 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 @@ -401,10 +401,12 @@ public class MeetingService implements MessageListener { gw.createMeeting(m.getInternalId(), m.getExternalId(), m.getParentMeetingId(), m.getName(), m.isRecord(), m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), m.getAllowStartStopRecording(), m.getRecordFullDurationMedia(), - m.getWebcamsOnlyForModerator(), m.getMeetingCameraCap(), m.getUserCameraCap(), m.getMaxPinnedCameras(), m.getModeratorPassword(), m.getViewerPassword(), + 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.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(), 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 587828197b..0c51c530fc 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 @@ -86,6 +86,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; @@ -676,7 +677,12 @@ public class ParamsProcessorUtil { String guestPolicy = defaultGuestPolicy; if (!StringUtils.isEmpty(params.get(ApiParams.GUEST_POLICY))) { 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))) { @@ -766,6 +772,7 @@ public class ParamsProcessorUtil { .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout) .withGuestPolicy(guestPolicy) .withAuthenticatedGuest(authenticatedGuest) + .withAllowPromoteGuestToModerator(allowPromoteGuestToModerator) .withAllowRequestsWithoutSession(allowRequestsWithoutSession) .withMeetingLayout(meetingLayout) .withBreakoutRoomsParams(breakoutParams) @@ -1297,7 +1304,11 @@ public class ParamsProcessorUtil { this.authenticatedGuest = value; } - public void setDefaultMeetingLayout(String meetingLayout) { + 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 1a45f0acf6..234d1e073f 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 @@ -83,6 +83,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; @@ -166,6 +167,7 @@ public class Meeting { isBreakout = builder.isBreakout; guestPolicy = builder.guestPolicy; authenticatedGuest = builder.authenticatedGuest; + allowPromoteGuestToModerator = builder.allowPromoteGuestToModerator; meetingLayout = builder.meetingLayout; allowRequestsWithoutSession = builder.allowRequestsWithoutSession; breakoutRoomsParams = builder.breakoutRoomsParams; @@ -499,6 +501,14 @@ public class Meeting { return authenticatedGuest; } + public void setAllowPromoteGuestToModerator(Boolean value) { + allowPromoteGuestToModerator = value; + } + + public Boolean getAllowPromoteGuestToModerator() { + return allowPromoteGuestToModerator; + } + public void setMeetingLayout(String layout) { meetingLayout = layout; } @@ -903,6 +913,7 @@ public class Meeting { private boolean isBreakout; private String guestPolicy; private Boolean authenticatedGuest; + private Boolean allowPromoteGuestToModerator; private Boolean allowRequestsWithoutSession; private String meetingLayout; private BreakoutRoomsParams breakoutRoomsParams; @@ -1085,15 +1096,20 @@ public class Meeting { return this; } - public Builder withAllowRequestsWithoutSession(Boolean value) { + public Builder withAllowPromoteGuestToModerator(Boolean value) { + allowPromoteGuestToModerator = value; + return this; + } + + public Builder withAllowRequestsWithoutSession(Boolean value) { allowRequestsWithoutSession = value; return this; } - public Builder withMeetingLayout(String layout) { - meetingLayout = layout; - return this; - } + public Builder withMeetingLayout(String layout) { + meetingLayout = layout; + return this; + } public Builder withBreakoutRoomsParams(BreakoutRoomsParams params) { breakoutRoomsParams = params; 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 cfb28e33d8..54852b2a68 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,8 @@ public interface IBbbWebApiGWApp { 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 28b94a1b70..4304832f0c 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 class UsersProp2 { String guestPolicy, String meetingLayout, boolean authenticatedGuest, + boolean allowPromoteGuestToModerator, boolean userHasJoined, Map userCustomData, Map users, @@ -31,6 +33,7 @@ public class UsersProp2 { 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 663a4479af..a359709154 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,10 @@ 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, @@ -211,7 +214,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/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js index f9c6f62d39..5bbe41d90a 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js @@ -100,6 +100,7 @@ export default async function addMeeting(meeting) { userCameraCap: Number, guestPolicy: String, authenticatedGuest: Boolean, + allowPromoteGuestToModerator: Boolean, allowModsToUnmuteUsers: Boolean, allowModsToEjectCameras: Boolean, meetingLayout: String, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index bb151ffd1e..b8ad75d7d6 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -401,6 +401,7 @@ const getUsersProp = () => { 'usersProp.allowModsToUnmuteUsers': 1, 'usersProp.allowModsToEjectCameras': 1, 'usersProp.authenticatedGuest': 1, + 'usersProp.allowPromoteGuestToModerator': 1, }, }, ); @@ -411,6 +412,7 @@ const getUsersProp = () => { allowModsToUnmuteUsers: false, allowModsToEjectCameras: false, authenticatedGuest: false, + allowPromoteGuestToModerator: false, }; }; @@ -463,14 +465,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-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index 4a117043fd..c6a04b1ed5 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 # Valid values are 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 3515291768..95d621238b 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 . +