private SecurityContractDefaultConfigurationTeam RetrieveIndividualDefaultConfigTeam(TeamModel team)
        {
            logger.Debug($"Retrieving default configuration contract definition for Team [{team.Name}].");

            var contractTeam = new SecurityContractDefaultConfigurationTeam()
            {
                Uuid         = team.Id,
                Name         = team.Name,
                Description  = team.Description,
                Users        = new List <string>(),
                Teams        = new List <string>(),
                DataPolicies = new List <string>()
            };

            foreach (var teamDataPolicy in team.ApplicationDataPolicies.OrderBy(o => o.SysPeriod.LowerBound))
            {
                contractTeam.DataPolicies.Add(teamDataPolicy.ApplicationDataPolicy.Name);
            }

            foreach (var user in team.UserTeams.OrderBy(o => o.User.SysPeriod.LowerBound))
            {
                contractTeam.Users.Add(user.User.UserName);
            }

            foreach (var childTeam in team.ChildTeams.OrderBy(o => o.ChildTeam.SysPeriod.LowerBound))
            {
                contractTeam.Teams.Add(childTeam.ChildTeam.Name);
            }

            return(contractTeam);
        }
        public async Task ApplyDefaultTeam(SecurityContractDefaultConfigurationTeam defaultTeamToApply, Guid updatedById)
        {
            var  teamModel = new TeamModel();
            bool newTeam   = false;

            var existingTeam = await teamRepository.GetByNameAsync(defaultTeamToApply.Name, true);

            if (existingTeam == null)
            {
                logger.Debug($"No existing team with name '{defaultTeamToApply.Name}'. Creating a new team.");
                newTeam = true;

                // We can also bind the team's UUID here, but only if one is supplied. We should not bind it on any team updates, as UUIDs associated with teams cannot be changed!
                if (defaultTeamToApply.Uuid != Guid.Empty)
                {
                    teamModel.Id = defaultTeamToApply.Uuid;
                }
            }
            else
            {
                logger.Debug($"Existing team with name: '{defaultTeamToApply.Name}' found. Updating the existing team.");
                teamModel = existingTeam;
            }

            teamModel.Name        = defaultTeamToApply.Name;
            teamModel.Description = defaultTeamToApply.Description;
            teamModel.ChangedBy   = updatedById;
            teamModel.ChildTeams  = new List <TeamTeamModel>();

            // It is very important to do the team assignments first, as the udpated teams configuration may affect whether users are able to be assigned to the team (Users cannot be directly assgined to compound teams)!
            await AssignChildTeamsToTeam(defaultTeamToApply, teamModel, updatedById);
            await AssignUsersToTeamFromUserNameList(teamModel, defaultTeamToApply.Users, updatedById);
            await AssignDataPoliciesToTeamFromDataPolicyNameList(teamModel, defaultTeamToApply.DataPolicies, updatedById);

            if (newTeam)
            {
                logger.Debug($"Persisting new team with name: '{defaultTeamToApply.Name}' to the database.");
                await teamRepository.CreateAsync(teamModel);
            }
            else
            {
                logger.Debug($"Persisting updated existing team with name: '{defaultTeamToApply.Name}' to the database.");
                await teamRepository.UpdateAsync(teamModel);
            }
        }
        private async Task AssignChildTeamsToTeam(SecurityContractDefaultConfigurationTeam defaultTeamToApply, TeamModel teamModel, Guid updatedById)
        {
            if (defaultTeamToApply.Teams != null && defaultTeamToApply.Teams.Count > 0)
            {
                // Check that the current team has no users! Users cannot be in a parent team, so the existence of users in a team prevents child teams being added to it.
                if (teamModel.UserTeams != null && teamModel.UserTeams.Any())
                {
                    throw new ItemNotProcessableException($"Cannot have compound teams with users in them! Team '{teamModel.Name}' already has users assigned to it, so cannot assign child teams to it!");
                }

                foreach (var teamToAdd in defaultTeamToApply.Teams)
                {
                    logger.Debug($"Attempting to add child team: '{teamToAdd}' to team '{defaultTeamToApply.Name}'.");

                    // Ensure that the role exists.
                    var existingchildTeam = await teamRepository.GetByNameAsync(teamToAdd, true);

                    if (existingchildTeam == null)
                    {
                        throw new ItemNotFoundException($"Child team '{teamToAdd}' not found when attempting to assinging it to team '{defaultTeamToApply.Name}'.");
                    }

                    // check that we are not attempting to add a compound team as a child, as this is prohibited.
                    if (existingchildTeam.ChildTeams.Any())
                    {
                        throw new ItemNotProcessableException($"Team '{existingchildTeam.Name}' already contains child teams. Cannot add it as a child team of team '{teamModel.Name}'");
                    }

                    logger.Debug($"Child team '{existingchildTeam}' exists and is being assigned to role '{defaultTeamToApply.Name}'.");
                    teamModel.ChildTeams.Add(new TeamTeamModel
                    {
                        ParentTeam = teamModel,
                        ChildTeam  = existingchildTeam,
                        ChangedBy  = updatedById
                    });
                }
            }
        }