diff --git a/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/MeetingsController.java b/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/MeetingsController.java index 757058b2ebe..f16a2952729 100644 --- a/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/MeetingsController.java +++ b/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/MeetingsController.java @@ -19,16 +19,17 @@ import java.time.Instant; import java.time.format.DateTimeParseException; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Set; +import java.util.List; +import java.util.Collections; +import java.util.Collection; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.sakaiproject.authz.api.Member; +import org.sakaiproject.authz.api.SecurityService; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.meetings.api.MeetingService; import org.sakaiproject.meetings.api.model.AttendeeType; @@ -84,6 +85,9 @@ public class MeetingsController { @Autowired private MicrosoftCommonService microsoftCommonService; + + @Autowired + private SecurityService securityService; @Autowired private MicrosoftSynchronizationService microsoftSynchronizationService; @@ -390,8 +394,26 @@ public Meeting createMeeting(@RequestBody MeetingData data) throws MeetingsExcep // Online meeting creation with the selected provider String onlineMeetingId = null; String onlineMeetingUrl = null; + List coorganizerEmails = new ArrayList<>(); if (MS_TEAMS.equals(data.getProvider())) { - TeamsMeetingData meetingTeams = microsoftCommonService.createOnlineMeeting(user.getEmail(), meeting.getTitle(), meeting.getStartDate(), meeting.getEndDate()); + if (data.isCoorganizersEnabled()) { + List coorganizers = sakaiProxy.getSite(data.getSiteId()).getMembers() + .stream() + .filter(u -> { + boolean canUpdate = sakaiProxy.canUpdateSite("/site/" + data.getSiteId(), u.getUserId()); + log.debug("User: " + u.getUserId() + " canUpdate: " + canUpdate); + return canUpdate; + }) + .collect(Collectors.toList()); + + coorganizers.forEach(c -> log.debug("Filtered Coorganizer: " + c.getUserId())); + + coorganizerEmails = coorganizers.stream() + .map(member -> sakaiProxy.getUser(member.getUserId()).getEmail()) + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toList()); + } + TeamsMeetingData meetingTeams = microsoftCommonService.createOnlineMeeting(user.getEmail(), meeting.getTitle(), meeting.getStartDate(), meeting.getEndDate(), coorganizerEmails); onlineMeetingUrl = meetingTeams.getJoinUrl(); onlineMeetingId = meetingTeams.getId(); } diff --git a/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/data/MeetingData.java b/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/data/MeetingData.java index 52db322d5e2..6138d12bf8d 100644 --- a/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/data/MeetingData.java +++ b/meetings/tool/src/main/java/org/sakaiproject/meetings/controller/data/MeetingData.java @@ -43,5 +43,5 @@ public class MeetingData implements Serializable { private AttendeeType participantOption; private List groupSelection; private List participants; - + private boolean coorganizersEnabled; } diff --git a/meetings/tool/src/main/resources/create-meeting.properties b/meetings/tool/src/main/resources/create-meeting.properties index 4a63413121a..cc7ede52bc7 100644 --- a/meetings/tool/src/main/resources/create-meeting.properties +++ b/meetings/tool/src/main/resources/create-meeting.properties @@ -16,6 +16,7 @@ no_notification=None - No notification notifications=Notifications open_date=Open Date participants_selection=Participants selection +enable_coorganizers= Add site instructors as co-organizers save=Save section_availability=3. Availability section_meeting_information=1. Meeting Information diff --git a/meetings/tool/src/main/resources/create-meeting_ca.properties b/meetings/tool/src/main/resources/create-meeting_ca.properties index 32720811415..33f4242ad08 100644 --- a/meetings/tool/src/main/resources/create-meeting_ca.properties +++ b/meetings/tool/src/main/resources/create-meeting_ca.properties @@ -16,6 +16,7 @@ no_notification=No - Sense notificaci\u00F3 notifications=Notificacions open_date=Data d\u2019inici participants_selection=Selecci\u00F3 de participants +enable_coorganizers= Afegiu instructors del lloc com a coorganitzadors save=Desa section_availability=3. Disponibilitat section_meeting_information=1. Dades de la reuni\u00F3 diff --git a/meetings/tool/src/main/resources/create-meeting_es.properties b/meetings/tool/src/main/resources/create-meeting_es.properties index 8e9ce7e8b01..8917ec9cd24 100644 --- a/meetings/tool/src/main/resources/create-meeting_es.properties +++ b/meetings/tool/src/main/resources/create-meeting_es.properties @@ -15,7 +15,8 @@ ms_teams=Microsoft Teams no_notification=No - Sin notificaci\u00F3n notifications=Notificaciones open_date=Fecha de inicio -participants_selection=Selecci\u00F3n de participantes +participants_selection=Selecci\u00f3n de participantes +enable_coorganizers= A�ada instructores del sitio como coorganizadores save=Guardar section_availability=3. Disponibilidad section_meeting_information=1. Datos de la reuni\u00F3n diff --git a/meetings/tool/src/main/resources/create-meeting_eu.properties b/meetings/tool/src/main/resources/create-meeting_eu.properties index 6ae68214bc9..43f6abcc1a9 100644 --- a/meetings/tool/src/main/resources/create-meeting_eu.properties +++ b/meetings/tool/src/main/resources/create-meeting_eu.properties @@ -16,6 +16,7 @@ no_notification= Bat ere ez - Jakinarazpenik gabe notifications= Jakinarazpenak open_date= Hasteko data participants_selection= Partaideen hautaketa +enable_coorganizers= Gehitu guneko irakasleak ko-antolatzaile gisa save= Gorde section_availability= 3. Erabilgarritasuna section_meeting_information= 1. Bilerari buruzko informazioa diff --git a/meetings/ui/src/main/frontend/src/views/CreateMeeting.vue b/meetings/ui/src/main/frontend/src/views/CreateMeeting.vue index 5b2171b71c9..5639e19b10c 100644 --- a/meetings/ui/src/main/frontend/src/views/CreateMeeting.vue +++ b/meetings/ui/src/main/frontend/src/views/CreateMeeting.vue @@ -64,6 +64,19 @@ {{this.i18n.info_no_groups}} +
+
+ + +
+
@@ -172,6 +185,7 @@ export default { notificationType: "0", groups: [], participantOption: "SITE", + enableCoorganizers: false }, groups: [], participants: [], @@ -248,6 +262,7 @@ export default { participantOption: (this.formdata.participantOption === 'SITE' ? 1 : 2), groupSelection: this.formdata.groups, provider: this.formdata.confService, + coorganizersEnabled: this.formdata.enableCoorganizers }; let methodToCall = constants.toolPlacement; let restMethod = "POST"; diff --git a/microsoft-integration/api/src/java/org/sakaiproject/microsoft/api/MicrosoftCommonService.java b/microsoft-integration/api/src/java/org/sakaiproject/microsoft/api/MicrosoftCommonService.java index 2d9e763fdfc..e6c26810e24 100644 --- a/microsoft-integration/api/src/java/org/sakaiproject/microsoft/api/MicrosoftCommonService.java +++ b/microsoft-integration/api/src/java/org/sakaiproject/microsoft/api/MicrosoftCommonService.java @@ -139,7 +139,7 @@ public static enum PermissionRoles { READ, WRITE } boolean removeMemberFromChannel(String memberId, String teamId, String channelId) throws MicrosoftCredentialsException; // ---------------------------------------- ONLINE MEETINGS -------------------------------------------------- - TeamsMeetingData createOnlineMeeting(String userEmail, String subject, Instant startDate, Instant endDate) throws MicrosoftCredentialsException; + TeamsMeetingData createOnlineMeeting(String userEmail, String subject, Instant startDate, Instant endDate, List coorganizerEmails) throws MicrosoftCredentialsException; void updateOnlineMeeting(String userEmail, String meetingId, String subject, Instant startDate, Instant endDate) throws MicrosoftCredentialsException; List getOnlineMeetingRecordings(String onlineMeetingId, List teamIdsList, boolean force) throws MicrosoftCredentialsException; diff --git a/microsoft-integration/impl/src/main/java/org/sakaiproject/microsoft/impl/MicrosoftCommonServiceImpl.java b/microsoft-integration/impl/src/main/java/org/sakaiproject/microsoft/impl/MicrosoftCommonServiceImpl.java index 004b45cb30a..64af68998c6 100644 --- a/microsoft-integration/impl/src/main/java/org/sakaiproject/microsoft/impl/MicrosoftCommonServiceImpl.java +++ b/microsoft-integration/impl/src/main/java/org/sakaiproject/microsoft/impl/MicrosoftCommonServiceImpl.java @@ -1668,7 +1668,7 @@ public boolean removeMemberFromChannel(String memberId, String teamId, String ch * @param endDate * @return */ - public TeamsMeetingData createOnlineMeeting(String userEmail, String subject, Instant startDate, Instant endDate) throws MicrosoftCredentialsException { + public TeamsMeetingData createOnlineMeeting(String userEmail, String subject, Instant startDate, Instant endDate, List coorganizerEmails) throws MicrosoftCredentialsException { TeamsMeetingData result = null; // Get organizer user @@ -1689,6 +1689,29 @@ public TeamsMeetingData createOnlineMeeting(String userEmail, String subject, In MeetingParticipants participants = new MeetingParticipants(); participants.organizer = organizer; + // Coorganizers + List attendees = new ArrayList<>(); + if (coorganizerEmails != null) { + for (String coorganizerEmail : coorganizerEmails) { + if (!coorganizerEmail.equals(organizerUser.getEmail())) { + MicrosoftUser coorganizerUser = getUserByEmail(coorganizerEmail); + if (coorganizerUser != null) { + MeetingParticipantInfo coorganizer = new MeetingParticipantInfo(); + IdentitySet coorganizerIdentity = new IdentitySet(); + Identity coorganizerIden = new Identity(); + coorganizerIden.id = coorganizerUser.getId(); + coorganizerIden.displayName = coorganizerUser.getName(); + coorganizerIdentity.user = coorganizerIden; + coorganizer.identity = coorganizerIdentity; + coorganizer.role = OnlineMeetingRole.COORGANIZER; + attendees.add(coorganizer); + } + } + } + } + participants.attendees = attendees; + + // Lobby Settings LobbyBypassSettings lobbySettings = new LobbyBypassSettings(); lobbySettings.scope = LobbyBypassScope.ORGANIZATION;