From 0bbef12ac7d6c347bc0bfea223484ac96f820675 Mon Sep 17 00:00:00 2001
From: Pedro Beschorner Marin <pedrobmarin@gmail.com>
Date: Tue, 9 Apr 2019 17:52:48 -0300
Subject: [PATCH] Authenticated guests feature controlled at bbb-web properties

---
 .../bigbluebutton/core/AppsTestFixtures.scala |  3 +-
 .../common2/domain/Meeting2x.scala            |  2 +-
 .../bigbluebutton/common2/TestFixtures.scala  |  3 +-
 .../org/bigbluebutton/api/MeetingService.java |  2 +-
 .../api/ParamsProcessorUtil.java              |  6 ++++
 .../org/bigbluebutton/api/domain/Meeting.java | 36 +++++++++++++++++++
 .../bigbluebutton/api2/IBbbWebApiGWApp.java   |  2 +-
 .../bigbluebutton/api2/domain/UsersProp2.java |  3 ++
 .../bigbluebutton/api2/BbbWebApiGWApp.scala   |  4 +--
 .../meetings/server/modifiers/addMeeting.js   |  1 +
 .../ui/components/waiting-users/component.jsx |  9 ++++-
 .../ui/components/waiting-users/container.jsx |  4 +++
 .../grails-app/conf/bigbluebutton.properties  |  3 ++
 .../grails-app/conf/spring/resources.xml      |  1 +
 14 files changed, 71 insertions(+), 8 deletions(-)

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 d82f2d8815..98311aa9bd 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
@@ -39,6 +39,7 @@ trait AppsTestFixtures {
   val maxUsers = 25
   val guestPolicy = "ALWAYS_ASK"
   val allowModsToUnmuteUsers = false
+  val authenticatedGuest = false
 
   val red5DeskShareIPTestFixture = "127.0.0.1"
   val red5DeskShareAppTestFixtures = "red5App"
@@ -58,7 +59,7 @@ trait AppsTestFixtures {
     modOnlyMessage = modOnlyMessage)
   val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart)
   val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator,
-    guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers)
+    guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, authenticatedGuest = authenticatedGuest)
   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 287a8c1e62..67f842e615 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
@@ -26,7 +26,7 @@ case class WelcomeProp(welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMe
 
 case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean)
 
-case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String, allowModsToUnmuteUsers: Boolean)
+case class UsersProp(maxUsers: Int, webcamsOnlyForModerator: Boolean, guestPolicy: String, allowModsToUnmuteUsers: Boolean, authenticatedGuest: 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 158a4a324c..127f0e6cb6 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
@@ -35,6 +35,7 @@ trait TestFixtures {
   val allowModsToUnmuteUsers = false
   val keepEvents = false
   val guestPolicy = "ALWAYS_ASK"
+  val authenticatedGuest = false
   val metadata: collection.immutable.Map[String, String] = Map("foo" -> "bar", "bar" -> "baz", "baz" -> "foo")
 
   val meetingProp = MeetingProp(name = meetingName, extId = externalMeetingId, intId = meetingId,
@@ -51,7 +52,7 @@ trait TestFixtures {
     modOnlyMessage = modOnlyMessage)
   val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart)
   val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator,
-    guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers)
+    guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers, authenticatedGuest = authenticatedGuest)
   val metadataProp = new MetadataProp(metadata)
   val screenshareProps = ScreenshareProps(screenshareConf = "FixMe!", red5ScreenshareIp = "fixMe!",
     red5ScreenshareApp = "fixMe!")
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 54d3034e77..f09b5366ce 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
@@ -396,7 +396,7 @@ public class MeetingService implements MessageListener {
             m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), m.getAllowStartStopRecording(),
             m.getWebcamsOnlyForModerator(), m.getModeratorPassword(), m.getViewerPassword(), m.getCreateTime(),
             formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(),
-            m.getGuestPolicy(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getModeratorOnlyMessage(),
+            m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), m.getModeratorOnlyMessage(),
             m.getDialNumber(), m.getMaxUsers(),
             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 732ea5fefc..9ad48b113c 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 defaultConfigURL;
     private String defaultGuestPolicy;
+    private Boolean authenticatedGuest;
     private int defaultMeetingDuration;
     private boolean disableRecordingDefault;
     private boolean autoStartRecording;
@@ -485,6 +486,7 @@ public class ParamsProcessorUtil {
                 .withWelcomeMessageTemplate(welcomeMessageTemplate)
                 .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout)
                 .withGuestPolicy(guestPolicy)
+                .withAuthenticatedGuest(authenticatedGuest)
 				.withBreakoutRoomsParams(breakoutParams)
 				.withLockSettingsParams(lockSettingsParams)
 				.withAllowDuplicateExtUserid(defaultAllowDuplicateExtUserid)
@@ -956,6 +958,10 @@ public class ParamsProcessorUtil {
 		this.defaultGuestPolicy =  guestPolicy;
 	}
 
+	public void setAuthenticatedGuest(Boolean value) {
+		this.authenticatedGuest = value;
+	}
+
 	public void setClientLogoutTimerInMinutes(Integer value) {
 		clientLogoutTimerInMinutes = value;
 	}
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 f11e00d2b0..1b4e1a6afb 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
@@ -68,6 +68,7 @@ public class Meeting {
 	private String defaultAvatarURL;
 	private String defaultConfigToken;
 	private String guestPolicy = GuestPolicy.ASK_MODERATOR;
+	private Boolean authenticatedGuest = false;
 	private boolean userHasJoined = false;
 	private Map<String, String> metadata;
 	private Map<String, Object> userCustomData;
@@ -125,6 +126,7 @@ public class Meeting {
         createdTime = builder.createdTime;
         isBreakout = builder.isBreakout;
         guestPolicy = builder.guestPolicy;
+        authenticatedGuest = builder.authenticatedGuest;
         breakoutRoomsParams = builder.breakoutRoomsParams;
         lockSettingsParams = builder.lockSettingsParams;
         allowDuplicateExtUserid = builder.allowDuplicateExtUserid;
@@ -362,8 +364,36 @@ public class Meeting {
     	return guestPolicy;
 	}
 
+	public void setAuthenticatedGuest(Boolean authGuest) {
+		authenticatedGuest = authGuest;
+	}
+
+	public Boolean getAuthenticatedGuest() {
+		return authenticatedGuest;
+	}
+
+  private String getUnauthenticatedGuestStatus(Boolean guest) {
+		if (guest) {
+			switch(guestPolicy) {
+				case GuestPolicy.ALWAYS_ACCEPT:
+				case GuestPolicy.ALWAYS_ACCEPT_AUTH:
+					return GuestPolicy.ALLOW;
+				case GuestPolicy.ASK_MODERATOR:
+					return GuestPolicy.WAIT;
+				case GuestPolicy.ALWAYS_DENY:
+					return GuestPolicy.DENY;
+				default:
+					return GuestPolicy.DENY;
+			}
+		} else {
+			return GuestPolicy.ALLOW;
+		}
+	}
 
 	public String calcGuestStatus(String role, Boolean guest, Boolean authned) {
+		// Good ol' Mconf guest status
+		if (!authenticatedGuest) return getUnauthenticatedGuestStatus(guest);
+
 		// Allow moderators all the time.
 		if (ROLE_MODERATOR.equals(role)) {
 			return GuestPolicy.ALLOW;
@@ -670,6 +700,7 @@ public class Meeting {
     	private long createdTime;
     	private boolean isBreakout;
     	private String guestPolicy;
+    	private Boolean authenticatedGuest;
     	private BreakoutRoomsParams breakoutRoomsParams;
     	private LockSettingsParams lockSettingsParams;
 		private Boolean allowDuplicateExtUserid;
@@ -791,6 +822,11 @@ public class Meeting {
     		guestPolicy = policy;
     		return  this;
 		}
+    
+    	public Builder withAuthenticatedGuest(Boolean authGuest) {
+    		authenticatedGuest = authGuest;
+    		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 4f9576646d..76b12060b8 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
@@ -19,7 +19,7 @@ public interface IBbbWebApiGWApp {
                      Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator,
                      String moderatorPass, String viewerPass, Long createTime,
                      String createDate, Boolean isBreakout, Integer sequence, Boolean freejoin, Map<String, String> metadata,
-                     String guestPolicy, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
+                     String guestPolicy, Boolean authenticatedGuest, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage,
                      String dialNumber, Integer maxUsers,
                      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 bcb7016d80..5c5a3fe069 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
@@ -5,6 +5,7 @@ import java.util.Map;
 
 public class UsersProp2 {
     public final String guestPolicy;
+    public final boolean authenticatedGuest;
     public final boolean userHasJoined;
     public final boolean webcamsOnlyForModerator;
     public final int maxUsers;
@@ -15,6 +16,7 @@ public class UsersProp2 {
     public UsersProp2(int maxUsers,
                       boolean webcamsOnlyForModerator,
                       String guestPolicy,
+                      boolean authenticatedGuest,
                       boolean userHasJoined,
                       Map<String, String> userCustomData,
                       Map<String, User2> users,
@@ -22,6 +24,7 @@ public class UsersProp2 {
         this.maxUsers = maxUsers;
         this.webcamsOnlyForModerator = webcamsOnlyForModerator;
         this.guestPolicy = guestPolicy;
+        this.authenticatedGuest = authenticatedGuest;
         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 ca536f6ac2..01ce305861 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
@@ -127,7 +127,7 @@ class BbbWebApiGWApp(
                     viewerPass: String, 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,
+                    metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean,
                     welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String,
                     dialNumber: String, maxUsers: java.lang.Integer,
                     meetingExpireIfNoUserJoinedInMinutes:   java.lang.Integer,
@@ -172,7 +172,7 @@ class BbbWebApiGWApp(
       modOnlyMessage = modOnlyMessage)
     val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber, muteOnStart = muteOnStart.booleanValue())
     val usersProp = UsersProp(maxUsers = maxUsers.intValue(), webcamsOnlyForModerator = webcamsOnlyForModerator.booleanValue(),
-      guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue())
+      guestPolicy = guestPolicy, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), authenticatedGuest = authenticatedGuest.booleanValue())
     val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap)
     val screenshareProps = ScreenshareProps(
       screenshareConf = voiceBridge + screenshareConfSuffix,
diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
index 389d816a62..9acea4e998 100755
--- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
+++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js
@@ -35,6 +35,7 @@ export default function addMeeting(meeting) {
     usersProp: {
       webcamsOnlyForModerator: Boolean,
       guestPolicy: String,
+      authenticatedGuest: Boolean,
       maxUsers: Number,
       allowModsToUnmuteUsers: Boolean,
     },
diff --git a/bigbluebutton-html5/imports/ui/components/waiting-users/component.jsx b/bigbluebutton-html5/imports/ui/components/waiting-users/component.jsx
index 658ec84000..62e87853f2 100755
--- a/bigbluebutton-html5/imports/ui/components/waiting-users/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/waiting-users/component.jsx
@@ -1,3 +1,4 @@
+import _ from 'lodash';
 import React, { useEffect, useState } from 'react';
 import { Session } from 'meteor/session';
 import { defineMessages, injectIntl } from 'react-intl';
@@ -148,6 +149,7 @@ const WaitingUsers = (props) => {
     guestUsers,
     guestUsersCall,
     changeGuestPolicy,
+    authenticatedGuest,
   } = props;
 
   const onCheckBoxChange = (e) => {
@@ -173,7 +175,7 @@ const WaitingUsers = (props) => {
     />
   );
 
-  const buttonsData = [
+  const authGuestButtonsData = [
     {
       messageId: intlMessages.allowAllAuthenticated,
       action: () => guestUsersCall(authenticatedUsers, ALLOW_STATUS),
@@ -189,6 +191,9 @@ const WaitingUsers = (props) => {
       key: 'allow-all-guest',
       policy: 'ALWAYS_ACCEPT',
     },
+  ];
+
+  const guestButtonsData = [
     {
       messageId: intlMessages.allowEveryone,
       action: () => guestUsersCall([...guestUsers, ...authenticatedUsers], ALLOW_STATUS),
@@ -203,6 +208,8 @@ const WaitingUsers = (props) => {
     },
   ];
 
+  const buttonsData = authenticatedGuest ? _.concat(authGuestButtonsData , guestButtonsData) : guestButtonsData;
+
   return (
     <div
       data-test="note"
diff --git a/bigbluebutton-html5/imports/ui/components/waiting-users/container.jsx b/bigbluebutton-html5/imports/ui/components/waiting-users/container.jsx
index b3fe25c21d..7e6e879ae4 100644
--- a/bigbluebutton-html5/imports/ui/components/waiting-users/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/waiting-users/container.jsx
@@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
 import { withTracker } from 'meteor/react-meteor-data';
 import Auth from '/imports/ui/services/auth';
 import GuestUsers from '/imports/api/guest-users/';
+import Meetings from '/imports/api/meetings';
 import Service from './service';
 import WaitingComponent from './component';
 
@@ -30,10 +31,13 @@ export default withTracker(() => {
     denied: false,
   }).fetch();
 
+  const authenticatedGuest = Meetings.findOne({ meetingId: Auth.meetingID }).usersProp.authenticatedGuest;
+
   return {
     guestUsers,
     authenticatedUsers,
     guestUsersCall: Service.guestUsersCall,
     changeGuestPolicy: Service.changeGuestPolicy,
+    authenticatedGuest,
   };
 })(WaitingContainer);
diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
index 6979e3fb5d..1fc1c8e9e6 100755
--- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
+++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties
@@ -148,6 +148,9 @@ defaultDialAccessNumber=613-555-1234
 #
 defaultGuestPolicy=ALWAYS_ACCEPT
 
+# Enables or disables authenticated guest
+authenticatedGuest=false
+
 #
 #----------------------------------------------------
 # Default welcome message to display when the participant joins the web
diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml
index 34d77afe8b..c03ef9d2a8 100755
--- a/bigbluebutton-web/grails-app/conf/spring/resources.xml
+++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml
@@ -139,6 +139,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         <property name="defaultAvatarURL" value="${defaultAvatarURL}"/>
         <property name="defaultConfigURL" value="${defaultConfigURL}"/>
         <property name="defaultGuestPolicy" value="${defaultGuestPolicy}"/>
+        <property name="authenticatedGuest" value="${authenticatedGuest}"/>
         <property name="meetingExpireIfNoUserJoinedInMinutes" value="${meetingExpireIfNoUserJoinedInMinutes}"/>
         <property name="meetingExpireWhenLastUserLeftInMinutes" value="${meetingExpireWhenLastUserLeftInMinutes}"/>
         <property name="userInactivityInspectTimerInMinutes" value="${userInactivityInspectTimerInMinutes}"/>
-- 
GitLab