示例#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);
        }
示例#2
0
        private async Task <CSEntryChangeResult> PutCSEntryChangeAdd(CSEntryChange csentry)
        {
            string teamid = null;

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

                if (owners.Count == 0)
                {
                    throw new InvalidProvisioningStateException("At least one owner is required to create a team");
                }

                teamid = await this.CreateTeam(csentry, this.betaClient, owners.First());

                await this.PutGroupMembersMailNickname(csentry, teamid);
            }
            catch
            {
                try
                {
                    if (teamid != null)
                    {
                        logger.Error($"{csentry.DN}: An exception occurred while creating the team, rolling back by deleting it");
                        await Task.Delay(TimeSpan.FromSeconds(MicrosoftTeamsMAConfigSection.Configuration.PostGroupCreateDelay), this.token);

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

                        logger.Info($"{csentry.DN}: The group was deleted");
                    }
                }
                catch (Exception ex2)
                {
                    logger.Error(ex2, $"{csentry.DN}: An exception occurred while rolling back the team");
                }

                throw;
            }

            List <AttributeChange> anchorChanges = new List <AttributeChange>();

            anchorChanges.Add(AttributeChange.CreateAttributeAdd("id", teamid));

            return(CSEntryChangeResult.Create(csentry.Identifier, anchorChanges, MAExportError.Success));
        }
        private async Task <CSEntryChangeResult> PutCSEntryChangeDelete(CSEntryChange csentry)
        {
            try
            {
                await GraphHelperGroups.DeleteGroup(this.client, csentry.DN, this.token);
            }
            catch (ServiceException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    logger.Warn($"The request to delete the group {csentry.DN} failed because the group doesn't exist");
                }
                else
                {
                    throw;
                }
            }

            return(CSEntryChangeResult.Create(csentry.Identifier, null, MAExportError.Success));
        }
        private async Task <CSEntryChangeResult> PutCSEntryChangeAdd(CSEntryChange csentry)
        {
            Group result = null;

            try
            {
                result = await this.CreateGroup(csentry);

                await this.CreateTeam(csentry, result.Id);
            }
            catch
            {
                try
                {
                    if (result != null)
                    {
                        logger.Error($"{csentry.DN}: An exception occurred while creating the team, rolling back the group by deleting it");
                        await Task.Delay(TimeSpan.FromSeconds(MicrosoftTeamsMAConfigSection.Configuration.PostGroupCreateDelay));

                        await GraphHelperGroups.DeleteGroup(this.client, result.Id, CancellationToken.None);

                        logger.Info($"{csentry.DN}: The group was deleted");
                    }
                }
                catch (Exception ex2)
                {
                    logger.Error(ex2, $"{csentry.DN}: An exception occurred while rolling back the team");
                }

                throw;
            }

            List <AttributeChange> anchorChanges = new List <AttributeChange>();

            anchorChanges.Add(AttributeChange.CreateAttributeAdd("id", result.Id));

            return(CSEntryChangeResult.Create(csentry.Identifier, anchorChanges, MAExportError.Success));
        }
示例#5
0
        private async Task <CSEntryChangeResult> PutCSEntryChangeDelete(CSEntryChange csentry)
        {
            try
            {
                string teamid = csentry.GetAnchorValueOrDefault <string>("id");
                await GraphHelperGroups.DeleteGroup(this.client, teamid, this.token);

                logger.Info($"The team {teamid} was deleted");
            }
            catch (ServiceException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    logger.Warn($"The request to delete the team {csentry.DN} failed because the group doesn't exist");
                }
                else
                {
                    throw;
                }
            }

            return(CSEntryChangeResult.Create(csentry.Identifier, null, MAExportError.Success));
        }
        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);
        }