Resolve conflicts

This commit is contained in:
Dennis Benz 2024-06-02 15:01:15 +02:00 committed by Gustavo Trott
parent 4063ee811b
commit c8e2d8b239
19 changed files with 92 additions and 49 deletions

View File

@ -31,7 +31,7 @@ trait ChangeUserRoleCmdMsgHdlr extends RightsManagementTrait {
} yield { } yield {
RegisteredUsers.updateUserRole(liveMeeting.registeredUsers, u, userRole) 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)) { if (msg.body.role == Roles.MODERATOR_ROLE && (!uvo.guest || promoteGuest)) {
// Promote non-guest users. // Promote non-guest users.
val notifyEvent = MsgBuilder.buildNotifyUserInMeetingEvtMsg( val notifyEvent = MsgBuilder.buildNotifyUserInMeetingEvtMsg(

View File

@ -19,7 +19,8 @@ case class MeetingUsersPoliciesDbModel(
meetingLayout: String, meetingLayout: String,
allowModsToUnmuteUsers: Boolean, allowModsToUnmuteUsers: Boolean,
allowModsToEjectCameras: Boolean, allowModsToEjectCameras: Boolean,
authenticatedGuest: Boolean authenticatedGuest: Boolean,
allowPromoteGuestToModerator: Boolean
) )
class MeetingUsersPoliciesDbTableDef(tag: Tag) extends Table[MeetingUsersPoliciesDbModel](tag, "meeting_usersPolicies") { 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 allowModsToUnmuteUsers = column[Boolean]("allowModsToUnmuteUsers")
val allowModsToEjectCameras = column[Boolean]("allowModsToEjectCameras") val allowModsToEjectCameras = column[Boolean]("allowModsToEjectCameras")
val authenticatedGuest = column[Boolean]("authenticatedGuest") val authenticatedGuest = column[Boolean]("authenticatedGuest")
val allowPromoteGuestToModerator = column[Boolean]("allowPromoteGuestToModerator")
// val fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId) // 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 { object MeetingUsersPoliciesDAO {
@ -56,6 +58,7 @@ object MeetingUsersPoliciesDAO {
allowModsToUnmuteUsers = usersProp.allowModsToUnmuteUsers, allowModsToUnmuteUsers = usersProp.allowModsToUnmuteUsers,
allowModsToEjectCameras = usersProp.allowModsToEjectCameras, allowModsToEjectCameras = usersProp.allowModsToEjectCameras,
authenticatedGuest = usersProp.authenticatedGuest, authenticatedGuest = usersProp.authenticatedGuest,
allowPromoteGuestToModerator = usersProp.allowPromoteGuestToModerator,
) )
) )
).onComplete { ).onComplete {

View File

@ -44,6 +44,7 @@ trait AppsTestFixtures {
val allowModsToUnmuteUsers = false val allowModsToUnmuteUsers = false
val allowModsToEjectCameras = false val allowModsToEjectCameras = false
val authenticatedGuest = false val authenticatedGuest = false
val allowPromoteGuestToModerator = false
val meetingLayout = "" val meetingLayout = ""
val captureNotesFilename = s"Room 0${sequence} (Notes)" val captureNotesFilename = s"Room 0${sequence} (Notes)"
val captureSlidesFilename = s"Room 0${sequence} (Whiteboard)" val captureSlidesFilename = s"Room 0${sequence} (Whiteboard)"
@ -69,7 +70,7 @@ trait AppsTestFixtures {
val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator,
userCameraCap = userCameraCap, userCameraCap = userCameraCap,
guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, allowModsToEjectCameras = allowModsToEjectCameras, guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, allowModsToEjectCameras = allowModsToEjectCameras,
authenticatedGuest = authenticatedGuest, meetingLayout = meetingLayout) authenticatedGuest = authenticatedGuest, allowPromoteGuestToModerator = allowPromoteGuestToModerator, meetingLayout = meetingLayout)
val metadataProp = new MetadataProp(metadata) val metadataProp = new MetadataProp(metadata)
val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp, val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp,

View File

@ -41,16 +41,17 @@ case class WelcomeProp(welcomeMsg: String, welcomeMsgForModerators: String)
case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean) case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean)
case class UsersProp( case class UsersProp(
maxUsers: Int, maxUsers: Int,
maxUserConcurrentAccesses:Int, maxUserConcurrentAccesses: Int,
webcamsOnlyForModerator: Boolean, webcamsOnlyForModerator: Boolean,
userCameraCap: Int, userCameraCap: Int,
guestPolicy: String, guestPolicy: String,
meetingLayout: String, meetingLayout: String,
allowModsToUnmuteUsers: Boolean, allowModsToUnmuteUsers: Boolean,
allowModsToEjectCameras: Boolean, allowModsToEjectCameras: Boolean,
authenticatedGuest: Boolean, authenticatedGuest: Boolean,
waitingGuestUsersTimeout: Long, allowPromoteGuestToModerator: Boolean,
waitingGuestUsersTimeout: Long
) )
case class MetadataProp(metadata: collection.immutable.Map[String, String]) case class MetadataProp(metadata: collection.immutable.Map[String, String])

View File

@ -44,6 +44,7 @@ trait TestFixtures {
val keepEvents = false val keepEvents = false
val guestPolicy = "ALWAYS_ASK" val guestPolicy = "ALWAYS_ASK"
val authenticatedGuest = false val authenticatedGuest = false
val allowPromoteGuestToModerator = false
val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo") val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo")
val captureNotesFilename = s"Room 0${sequence} (Notes)" val captureNotesFilename = s"Room 0${sequence} (Notes)"
val captureSlidesFilename = s"Room 0${sequence} (Whiteboard)" 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 voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart)
val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator,
userCameraCap = userCameraCap, 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 metadataProp = new MetadataProp(metadata)
val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp, val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp,
usersProp, metadataProp) usersProp, metadataProp)

View File

@ -33,6 +33,7 @@ public class ApiParams {
public static final String FREE_JOIN = "freeJoin"; public static final String FREE_JOIN = "freeJoin";
public static final String FULL_NAME = "fullName"; public static final String FULL_NAME = "fullName";
public static final String GUEST_POLICY = "guestPolicy"; 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 MEETING_LAYOUT = "meetingLayout";
public static final String IS_BREAKOUT = "isBreakout"; public static final String IS_BREAKOUT = "isBreakout";
public static final String LOGO = "logo"; public static final String LOGO = "logo";

View File

@ -423,9 +423,8 @@ public class MeetingService implements MessageListener {
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(), m.getLearningDashboardAccessToken(), m.getCreateTime(),
formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(), formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(),
m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getWaitingGuestUsersTimeout(), m.getMeetingLayout(), m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getAllowPromoteGuestToModerator(), m.getWaitingGuestUsersTimeout(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(),
m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getWelcomeMsgForModerators(), m.getWelcomeMsgForModerators(), m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(),
m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(),
m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getMeetingExpireWhenLastUserLeftInMinutes(), m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getMeetingExpireWhenLastUserLeftInMinutes(),
m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(), m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(),
m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(), m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(),

View File

@ -77,12 +77,14 @@ public class ParamsProcessorUtil {
private String defaultHTML5ClientUrl; private String defaultHTML5ClientUrl;
private String graphqlWebsocketUrl; private String graphqlWebsocketUrl;
private String defaultGuestWaitURL;
private Boolean allowRequestsWithoutSession = false; private Boolean allowRequestsWithoutSession = false;
private Integer defaultHttpSessionTimeout = 14400; private Integer defaultHttpSessionTimeout = 14400;
private Boolean useDefaultAvatar = false; private Boolean useDefaultAvatar = false;
private String defaultAvatarURL; private String defaultAvatarURL;
private String defaultGuestPolicy; private String defaultGuestPolicy;
private Boolean authenticatedGuest; private Boolean authenticatedGuest;
private Boolean defaultAllowPromoteGuestToModerator;
private Long waitingGuestUsersTimeout; private Long waitingGuestUsersTimeout;
private String defaultMeetingLayout; private String defaultMeetingLayout;
private int defaultMeetingDuration; private int defaultMeetingDuration;
@ -678,6 +680,11 @@ public class ParamsProcessorUtil {
guestPolicy = 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; String presentationUploadExternalDescription = defaultPresentationUploadExternalDescription;
if (!StringUtils.isEmpty(params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION))) { if (!StringUtils.isEmpty(params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION))) {
presentationUploadExternalDescription = params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION); presentationUploadExternalDescription = params.get(ApiParams.PRESENTATION_UPLOAD_EXTERNAL_DESCRIPTION);
@ -767,6 +774,7 @@ public class ParamsProcessorUtil {
.withIsBreakout(isBreakout) .withIsBreakout(isBreakout)
.withGuestPolicy(guestPolicy) .withGuestPolicy(guestPolicy)
.withAuthenticatedGuest(authenticatedGuest) .withAuthenticatedGuest(authenticatedGuest)
.withAllowPromoteGuestToModerator(allowPromoteGuestToModerator)
.withWaitingGuestUsersTimeout(waitingGuestUsersTimeout) .withWaitingGuestUsersTimeout(waitingGuestUsersTimeout)
.withAllowRequestsWithoutSession(allowRequestsWithoutSession) .withAllowRequestsWithoutSession(allowRequestsWithoutSession)
.withMeetingLayout(meetingLayout) .withMeetingLayout(meetingLayout)
@ -1302,7 +1310,7 @@ public class ParamsProcessorUtil {
this.useDefaultAvatar = value; this.useDefaultAvatar = value;
} }
public void setdefaultAvatarURL(String url) { public void setDefaultAvatarURL(String url) {
this.defaultAvatarURL = url; this.defaultAvatarURL = url;
} }
@ -1314,6 +1322,10 @@ public class ParamsProcessorUtil {
this.authenticatedGuest = value; this.authenticatedGuest = value;
} }
public void setDefaultAllowPromoteGuestToModerator(Boolean value) {
this.defaultAllowPromoteGuestToModerator = value;
}
public void setWaitingGuestUsersTimeout(Long value) { public void setWaitingGuestUsersTimeout(Long value) {
this.waitingGuestUsersTimeout = value; this.waitingGuestUsersTimeout = value;
} }

View File

@ -81,6 +81,7 @@ public class Meeting {
private String guestLobbyMessage = ""; private String guestLobbyMessage = "";
private Map<String,String> usersWithGuestLobbyMessages; private Map<String,String> usersWithGuestLobbyMessages;
private Boolean authenticatedGuest = false; private Boolean authenticatedGuest = false;
private Boolean allowPromoteGuestToModerator = false;
private long waitingGuestUsersTimeout = 30000; private long waitingGuestUsersTimeout = 30000;
private String meetingLayout = MeetingLayout.SMART_LAYOUT; private String meetingLayout = MeetingLayout.SMART_LAYOUT;
private boolean userHasJoined = false; private boolean userHasJoined = false;
@ -166,8 +167,9 @@ public class Meeting {
isBreakout = builder.isBreakout; isBreakout = builder.isBreakout;
guestPolicy = builder.guestPolicy; guestPolicy = builder.guestPolicy;
authenticatedGuest = builder.authenticatedGuest; authenticatedGuest = builder.authenticatedGuest;
waitingGuestUsersTimeout = builder.waitingGuestUsersTimeout; allowPromoteGuestToModerator = builder.allowPromoteGuestToModerator;
meetingLayout = builder.meetingLayout; waitingGuestUsersTimeout = builder.waitingGuestUsersTimeout;
meetingLayout = builder.meetingLayout;
allowRequestsWithoutSession = builder.allowRequestsWithoutSession; allowRequestsWithoutSession = builder.allowRequestsWithoutSession;
breakoutRoomsParams = builder.breakoutRoomsParams; breakoutRoomsParams = builder.breakoutRoomsParams;
lockSettingsParams = builder.lockSettingsParams; lockSettingsParams = builder.lockSettingsParams;
@ -503,14 +505,22 @@ public class Meeting {
return authenticatedGuest; return authenticatedGuest;
} }
public void setWaitingGuestUsersTimeout(long waitingGuestUsersTimeout) { public void setAllowPromoteGuestToModerator(Boolean value) {
waitingGuestUsersTimeout = waitingGuestUsersTimeout; allowPromoteGuestToModerator = value;
} }
public long getWaitingGuestUsersTimeout() { public Boolean getAllowPromoteGuestToModerator() {
return waitingGuestUsersTimeout; return allowPromoteGuestToModerator;
} }
public void setWaitingGuestUsersTimeout(long waitingGuestUsersTimeout) {
waitingGuestUsersTimeout = waitingGuestUsersTimeout;
}
public long getWaitingGuestUsersTimeout() {
return waitingGuestUsersTimeout;
}
public void setMeetingLayout(String layout) { public void setMeetingLayout(String layout) {
meetingLayout = layout; meetingLayout = layout;
} }
@ -920,7 +930,8 @@ public class Meeting {
private boolean isBreakout; private boolean isBreakout;
private String guestPolicy; private String guestPolicy;
private Boolean authenticatedGuest; private Boolean authenticatedGuest;
private long waitingGuestUsersTimeout; private Boolean allowPromoteGuestToModerator;
private long waitingGuestUsersTimeout;
private Boolean allowRequestsWithoutSession; private Boolean allowRequestsWithoutSession;
private String meetingLayout; private String meetingLayout;
private BreakoutRoomsParams breakoutRoomsParams; private BreakoutRoomsParams breakoutRoomsParams;
@ -1107,8 +1118,13 @@ public class Meeting {
return this; return this;
} }
public Builder withWaitingGuestUsersTimeout(long waitingGuestUsersTimeout) { public Builder withAllowPromoteGuestToModerator(Boolean value) {
this.waitingGuestUsersTimeout = waitingGuestUsersTimeout; allowPromoteGuestToModerator = value;
return this;
}
public Builder withWaitingGuestUsersTimeout(long value) {
waitingGuestUsersTimeout = value;
return this; return this;
} }

View File

@ -16,14 +16,9 @@ import org.bigbluebutton.presentation.messages.IDocConversionMsg;
public interface IBbbWebApiGWApp { public interface IBbbWebApiGWApp {
void send(String channel, String message); void send(String channel, String message);
void createMeeting(String meetingID, void createMeeting(String meetingID, String externalMeetingID,
String externalMeetingID, String parentMeetingID, String meetingName, Boolean recorded,
String parentMeetingID, String voiceBridge, Integer duration, Boolean autoStartRecording,
String meetingName,
Boolean recorded,
String voiceBridge,
Integer duration,
Boolean autoStartRecording,
Boolean allowStartStopRecording, Boolean allowStartStopRecording,
Boolean recordFullDurationMedia, Boolean recordFullDurationMedia,
Boolean webcamsOnlyForModerator, Boolean webcamsOnlyForModerator,
@ -41,6 +36,7 @@ public interface IBbbWebApiGWApp {
Map<String, String> metadata, Map<String, String> metadata,
String guestPolicy, String guestPolicy,
Boolean authenticatedGuest, Boolean authenticatedGuest,
Boolean allowPromoteGuestToModerator,
Long waitingGuestUsersTimeout, Long waitingGuestUsersTimeout,
String meetingLayout, String meetingLayout,
String welcomeMsgTemplate, String welcomeMsgTemplate,

View File

@ -7,6 +7,7 @@ public class UsersProp2 {
public final String guestPolicy; public final String guestPolicy;
public final String meetingLayout; public final String meetingLayout;
public final boolean authenticatedGuest; public final boolean authenticatedGuest;
public final boolean allowPromoteGuestToModerator;
public final boolean userHasJoined; public final boolean userHasJoined;
public final boolean webcamsOnlyForModerator; public final boolean webcamsOnlyForModerator;
public final int userCameraCap; public final int userCameraCap;
@ -21,6 +22,7 @@ public class UsersProp2 {
String guestPolicy, String guestPolicy,
String meetingLayout, String meetingLayout,
boolean authenticatedGuest, boolean authenticatedGuest,
boolean allowPromoteGuestToModerator,
boolean userHasJoined, boolean userHasJoined,
Map<String, String> userCustomData, Map<String, String> userCustomData,
Map<String, User2> users, Map<String, User2> users,
@ -31,6 +33,7 @@ public class UsersProp2 {
this.guestPolicy = guestPolicy; this.guestPolicy = guestPolicy;
this.meetingLayout = meetingLayout; this.meetingLayout = meetingLayout;
this.authenticatedGuest = authenticatedGuest; this.authenticatedGuest = authenticatedGuest;
this.allowPromoteGuestToModerator = allowPromoteGuestToModerator;
this.userHasJoined = userHasJoined; this.userHasJoined = userHasJoined;
this.userCustomData = userCustomData; this.userCustomData = userCustomData;
this.users = users; this.users = users;

View File

@ -6,7 +6,6 @@ import org.apache.pekko.event.Logging
import org.bigbluebutton.api.domain.{BreakoutRoomsParams, Group, LockSettingsParams} import org.bigbluebutton.api.domain.{BreakoutRoomsParams, Group, LockSettingsParams}
import org.bigbluebutton.api.messaging.converters.messages._ import org.bigbluebutton.api.messaging.converters.messages._
import org.bigbluebutton.api.messaging.messages.ChatMessageFromApi import org.bigbluebutton.api.messaging.messages.ChatMessageFromApi
import org.bigbluebutton.api.model.request.SendChatMessage
import org.bigbluebutton.api2.bus._ import org.bigbluebutton.api2.bus._
import org.bigbluebutton.api2.endpoint.redis.WebRedisSubscriberActor import org.bigbluebutton.api2.endpoint.redis.WebRedisSubscriberActor
import org.bigbluebutton.common2.redis.MessageSender import org.bigbluebutton.common2.redis.MessageSender
@ -135,6 +134,7 @@ class BbbWebApiGWApp(
metadata: java.util.Map[String, String], metadata: java.util.Map[String, String],
guestPolicy: String, guestPolicy: String,
authenticatedGuest: java.lang.Boolean, authenticatedGuest: java.lang.Boolean,
allowPromoteGuestToModerator: java.lang.Boolean,
waitingGuestUsersTimeout: java.lang.Long, waitingGuestUsersTimeout: java.lang.Long,
meetingLayout: String, meetingLayout: String,
welcomeMsgTemplate: String, welcomeMsg: String, welcomeMsgForModerators: String, welcomeMsgTemplate: String, welcomeMsg: String, welcomeMsgForModerators: String,
@ -222,6 +222,7 @@ class BbbWebApiGWApp(
guestPolicy = guestPolicy, meetingLayout = meetingLayout, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), guestPolicy = guestPolicy, meetingLayout = meetingLayout, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(),
allowModsToEjectCameras = allowModsToEjectCameras.booleanValue(), allowModsToEjectCameras = allowModsToEjectCameras.booleanValue(),
authenticatedGuest = authenticatedGuest.booleanValue(), authenticatedGuest = authenticatedGuest.booleanValue(),
allowPromoteGuestToModerator = allowPromoteGuestToModerator.booleanValue(),
waitingGuestUsersTimeout = waitingGuestUsersTimeout.longValue() waitingGuestUsersTimeout = waitingGuestUsersTimeout.longValue()
) )
val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap) val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap)

View File

@ -127,16 +127,17 @@ create view "v_meeting_voiceSettings" as select * from meeting_voice;
create table "meeting_usersPolicies" ( create table "meeting_usersPolicies" (
"meetingId" varchar(100) primary key references "meeting"("meetingId") ON DELETE CASCADE, "meetingId" varchar(100) primary key references "meeting"("meetingId") ON DELETE CASCADE,
"maxUsers" integer, "maxUsers" integer,
"maxUserConcurrentAccesses" integer, "maxUserConcurrentAccesses" integer,
"webcamsOnlyForModerator" boolean, "webcamsOnlyForModerator" boolean,
"userCameraCap" integer, "userCameraCap" integer,
"guestPolicy" varchar(100), "guestPolicy" varchar(100),
"guestLobbyMessage" text, "guestLobbyMessage" text,
"meetingLayout" varchar(100), "meetingLayout" varchar(100),
"allowModsToUnmuteUsers" boolean, "allowModsToUnmuteUsers" boolean,
"allowModsToEjectCameras" boolean, "allowModsToEjectCameras" boolean,
"authenticatedGuest" boolean "authenticatedGuest" boolean,
"allowPromoteGuestToModerator" boolean
); );
create index "idx_meeting_usersPolicies_meetingId" on "meeting_usersPolicies"("meetingId"); create index "idx_meeting_usersPolicies_meetingId" on "meeting_usersPolicies"("meetingId");
@ -152,6 +153,7 @@ SELECT "meeting_usersPolicies"."meetingId",
"meeting_usersPolicies"."allowModsToUnmuteUsers", "meeting_usersPolicies"."allowModsToUnmuteUsers",
"meeting_usersPolicies"."allowModsToEjectCameras", "meeting_usersPolicies"."allowModsToEjectCameras",
"meeting_usersPolicies"."authenticatedGuest", "meeting_usersPolicies"."authenticatedGuest",
"meeting_usersPolicies"."allowPromoteGuestToModerator",
"meeting"."isBreakout" is false "moderatorsCanMuteAudio", "meeting"."isBreakout" is false "moderatorsCanMuteAudio",
"meeting"."isBreakout" is false and "meeting_usersPolicies"."allowModsToUnmuteUsers" is true "moderatorsCanUnmuteAudio" "meeting"."isBreakout" is false and "meeting_usersPolicies"."allowModsToUnmuteUsers" is true "moderatorsCanUnmuteAudio"
FROM "meeting_usersPolicies" FROM "meeting_usersPolicies"

View File

@ -8,6 +8,7 @@ select_permissions:
- allowModsToEjectCameras - allowModsToEjectCameras
- allowModsToUnmuteUsers - allowModsToUnmuteUsers
- authenticatedGuest - authenticatedGuest
- allowPromoteGuestToModerator
- guestLobbyMessage - guestLobbyMessage
- guestPolicy - guestPolicy
- maxUserConcurrentAccesses - maxUserConcurrentAccesses

View File

@ -48,6 +48,7 @@ export interface UsersPolicies {
allowModsToEjectCameras: boolean; allowModsToEjectCameras: boolean;
allowModsToUnmuteUsers: boolean; allowModsToUnmuteUsers: boolean;
authenticatedGuest: boolean; authenticatedGuest: boolean;
allowPromoteGuestToModerator: boolean;
guestPolicy: string; guestPolicy: string;
maxUserConcurrentAccesses: number; maxUserConcurrentAccesses: number;
maxUsers: number; maxUsers: number;

View File

@ -20,6 +20,7 @@ subscription MeetingPermissions {
allowModsToEjectCameras allowModsToEjectCameras
allowModsToUnmuteUsers allowModsToUnmuteUsers
authenticatedGuest authenticatedGuest
allowPromoteGuestToModerator
guestPolicy guestPolicy
maxUserConcurrentAccesses maxUserConcurrentAccesses
maxUsers maxUsers

View File

@ -55,14 +55,14 @@ export const generateActionsPermissions = (
&& !isSubjectUserModerator && !isSubjectUserModerator
&& !isDialInUser && !isDialInUser
&& !isBreakout && !isBreakout
&& !(isSubjectUserGuest && usersPolicies?.authenticatedGuest); && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest && !usersPolicies?.allowPromoteGuestToModerator);
const allowedToDemote = amIModerator const allowedToDemote = amIModerator
&& !amISubjectUser && !amISubjectUser
&& isSubjectUserModerator && isSubjectUserModerator
&& !isDialInUser && !isDialInUser
&& !isBreakout && !isBreakout
&& !(isSubjectUserGuest && usersPolicies?.authenticatedGuest); && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest && !usersPolicies?.allowPromoteGuestToModerator);
const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED; const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED;

View File

@ -160,6 +160,9 @@ defaultGuestPolicy=ALWAYS_ACCEPT
# Enables or disables authenticated guest # Enables or disables authenticated guest
authenticatedGuest=true authenticatedGuest=true
# Allows moderators to promote guests to moderators when authenticatedGuest is enabled
defaultAllowPromoteGuestToModerator=false
#--------------------------------------------------- #---------------------------------------------------
# Default Meeting Layout # Default Meeting Layout
# Accepted values are the standard layouts: CUSTOM_LAYOUT, SMART_LAYOUT, PRESENTATION_FOCUS, VIDEO_FOCUS # Accepted values are the standard layouts: CUSTOM_LAYOUT, SMART_LAYOUT, PRESENTATION_FOCUS, VIDEO_FOCUS

View File

@ -161,6 +161,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="defaultAvatarURL" value="${defaultAvatarURL}"/> <property name="defaultAvatarURL" value="${defaultAvatarURL}"/>
<property name="defaultGuestPolicy" value="${defaultGuestPolicy}"/> <property name="defaultGuestPolicy" value="${defaultGuestPolicy}"/>
<property name="authenticatedGuest" value="${authenticatedGuest}"/> <property name="authenticatedGuest" value="${authenticatedGuest}"/>
<property name="defaultAllowPromoteGuestToModerator" value="${defaultAllowPromoteGuestToModerator}"/>
<property name="waitingGuestUsersTimeout" value="${waitingGuestUsersTimeout}"/> <property name="waitingGuestUsersTimeout" value="${waitingGuestUsersTimeout}"/>
<property name="defaultMeetingLayout" value="${defaultMeetingLayout}"/> <property name="defaultMeetingLayout" value="${defaultMeetingLayout}"/>
<property name="meetingExpireIfNoUserJoinedInMinutes" value="${meetingExpireIfNoUserJoinedInMinutes}"/> <property name="meetingExpireIfNoUserJoinedInMinutes" value="${meetingExpireIfNoUserJoinedInMinutes}"/>