Esempio n. 1
0
        private async Task PutGroupMembersMailNickname(CSEntryChange csentry, string teamID)
        {
            if (csentry.HasAttributeChange("mailNickname"))
            {
                Group group = new Group();
                group.MailNickname = csentry.GetValueAdd <string>("mailNickname");

                try
                {
                    await GraphHelperGroups.UpdateGroup(this.client, teamID, group, this.token);

                    logger.Info($"{csentry.DN}: Updated group {teamID}");
                }
                catch (ServiceException ex)
                {
                    if (MicrosoftTeamsMAConfigSection.Configuration.DeleteAddConflictingGroup && ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.IndexOf("mailNickname", 0, StringComparison.Ordinal) > 0)
                    {
                        string mailNickname = csentry.GetValueAdd <string>("mailNickname");
                        logger.Warn($"{csentry.DN}: Deleting group with conflicting mailNickname '{mailNickname}'");
                        string existingGroup = await GraphHelperGroups.GetGroupIdByMailNickname(this.client, mailNickname, this.token);

                        await GraphHelperGroups.DeleteGroup(this.client, existingGroup, this.token);

                        await Task.Delay(TimeSpan.FromSeconds(MicrosoftTeamsMAConfigSection.Configuration.PostGroupCreateDelay), this.token);

                        await GraphHelperGroups.UpdateGroup(this.client, teamID, group, this.token);

                        logger.Info($"{csentry.DN}: Updated group {group.Id}");
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            IList <string> members = csentry.GetValueAdds <string>("member") ?? new List <string>();
            IList <string> owners  = csentry.GetValueAdds <string>("owner") ?? new List <string>();

            if (owners.Count > 0)
            {
                // Remove the first owner, as we already added them during team creation
                string initialOwner = owners[0];
                owners.RemoveAt(0);

                // Teams API unhelpfully adds the initial owner as a member as well, so we need to undo that.
                await GraphHelperGroups.RemoveGroupMembers(this.client, teamID, new List <string> {
                    initialOwner
                }, false, this.token);
            }

            if (owners.Count > 100)
            {
                throw new UnsupportedAttributeModificationException($"The group creation request {csentry.DN} contained more than 100 owners");
            }

            await this.ApplyMembership(teamID, teamID, members, owners);
        }
        private async Task <Group> CreateGroup(CSEntryChange csentry)
        {
            Group group = new Group();

            group.DisplayName     = csentry.GetValueAdd <string>("displayName") ?? throw new UnexpectedDataException("The group must have a displayName");
            group.GroupTypes      = new[] { "Unified" };
            group.MailEnabled     = true;
            group.Description     = csentry.GetValueAdd <string>("description");
            group.MailNickname    = csentry.GetValueAdd <string>("mailNickname") ?? throw new UnexpectedDataException("The group must have a mailNickname");
            group.SecurityEnabled = false;
            group.AdditionalData  = new Dictionary <string, object>();
            group.Id         = csentry.DN;
            group.Visibility = csentry.GetValueAdd <string>("visibility");

            IList <string> members = csentry.GetValueAdds <string>("member") ?? new List <string>();
            IList <string> owners  = csentry.GetValueAdds <string>("owner") ?? new List <string>();

            IList <string> deferredMembers = new List <string>();
            IList <string> createOpMembers = new List <string>();

            IList <string> deferredOwners = new List <string>();
            IList <string> createOpOwners = new List <string>();

            int memberCount = 0;

            if (owners.Count > 100)
            {
                throw new UnexpectedDataException($"The group creation request {csentry.DN} contained more than 100 owners");
            }

            foreach (string owner in owners)
            {
                if (memberCount >= MaxReferencesPerCreateRequest)
                {
                    deferredOwners.Add(owner);
                }
                else
                {
                    createOpOwners.Add($"https://graph.microsoft.com/v1.0/users/{owner}");
                    memberCount++;
                }
            }

            foreach (string member in members)
            {
                if (memberCount >= MaxReferencesPerCreateRequest)
                {
                    deferredMembers.Add(member);
                }
                else
                {
                    createOpMembers.Add($"https://graph.microsoft.com/v1.0/users/{member}");
                    memberCount++;
                }
            }

            if (createOpMembers.Count > 0)
            {
                group.AdditionalData.Add("*****@*****.**", createOpMembers.ToArray());
            }

            if (createOpOwners.Count > 0)
            {
                group.AdditionalData.Add("*****@*****.**", createOpOwners.ToArray());
            }

            logger.Trace($"{csentry.DN}: Creating group {group.MailNickname} with {createOpMembers.Count} members and {createOpOwners.Count} owners (Deferring {deferredMembers.Count} members and {deferredOwners.Count} owners until after group creation)");

            logger.Trace($"{csentry.DN}: Group data: {JsonConvert.SerializeObject(group)}");

            Group result;

            try
            {
                result = await GraphHelperGroups.CreateGroup(this.client, group, this.token);
            }
            catch (ServiceException ex)
            {
                if (MicrosoftTeamsMAConfigSection.Configuration.DeleteAddConflictingGroup && ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.IndexOf("mailNickname", 0, StringComparison.Ordinal) > 0)
                {
                    string mailNickname = csentry.GetValueAdd <string>("mailNickname");
                    logger.Warn($"{csentry.DN}: Delete/Adding conflicting group with mailNickname '{mailNickname}'");

                    string existingGroup = await GraphHelperGroups.GetGroupIdByMailNickname(this.client, mailNickname, this.token);

                    await GraphHelperGroups.DeleteGroup(this.client, existingGroup, this.token);

                    await Task.Delay(TimeSpan.FromSeconds(MicrosoftTeamsMAConfigSection.Configuration.PostGroupCreateDelay));

                    result = await GraphHelperGroups.CreateGroup(this.client, group, this.token);
                }
                else
                {
                    throw;
                }
            }

            logger.Info($"{csentry.DN}: Created group {group.Id}");

            await Task.Delay(TimeSpan.FromSeconds(MicrosoftTeamsMAConfigSection.Configuration.PostGroupCreateDelay), this.token);

            try
            {
                await this.ProcessDeferredMembership(deferredMembers, result, deferredOwners, csentry.DN);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"{csentry.DN}: An exception occurred while modifying the membership, rolling back the group by deleting it");
                await Task.Delay(TimeSpan.FromSeconds(5), this.token);

                await GraphHelperGroups.DeleteGroup(this.client, csentry.DN, CancellationToken.None);

                logger.Info($"{csentry.DN}: The group was deleted");
                throw;
            }

            return(result);
        }