/// <inheritdoc />
        public async Task AddClaimMapping(IGuildUser user, ClaimMappingType type, AuthorizationClaim claim)
        {
            RequireAuthenticatedUser();
            RequireClaims(AuthorizationClaim.AuthorizationConfigure);

            using (var transaction = await ClaimMappingRepository.BeginCreateTransactionAsync())
            {
                if (await ClaimMappingRepository.AnyAsync(new ClaimMappingSearchCriteria()
                {
                    Types = new[] { type },
                    GuildId = user.Guild.Id,
                    UserId = user.Id,
                    Claims = new[] { claim },
                    IsDeleted = false,
                }))
                {
                    throw new InvalidOperationException($"A claim mapping of type {type} to claim {claim} for user {user.GetDisplayName()} already exists");
                }

                await ClaimMappingRepository.CreateAsync(new ClaimMappingCreationData()
                {
                    GuildId     = user.Guild.Id,
                    Type        = type,
                    UserId      = user.Id,
                    Claim       = claim,
                    CreatedById = CurrentUserId.Value
                });

                transaction.Commit();
            }
        }
Esempio n. 2
0
        /// <inheritdoc />
        public async Task AutoConfigureGuildAsync(IGuild guild)
        {
            if (await ClaimMappingRepository.AnyAsync(guild.Id))
            {
                return;
            }

            await UserService.TrackUserAsync(DiscordClient.CurrentUser);

            foreach (var claim in Enum.GetValues(typeof(AuthorizationClaim)).Cast <AuthorizationClaim>())
            {
                foreach (var role in guild.Roles.Where(x => x.Permissions.Administrator))
                {
                    await ClaimMappingRepository.CreateAsync(new ClaimMappingCreationData()
                    {
                        Type        = ClaimMappingType.Granted,
                        GuildId     = guild.Id,
                        RoleId      = role.Id,
                        UserId      = null,
                        Claim       = claim,
                        CreatedById = DiscordClient.CurrentUser.Id
                    });
                }

                await ClaimMappingRepository.CreateAsync(new ClaimMappingCreationData()
                {
                    Type        = ClaimMappingType.Granted,
                    GuildId     = guild.Id,
                    RoleId      = null,
                    UserId      = DiscordClient.CurrentUser.Id,
                    Claim       = claim,
                    CreatedById = DiscordClient.CurrentUser.Id
                });
            }
        }
        /// <inheritdoc />
        public async Task ModifyClaimMapping(ulong roleId, AuthorizationClaim claim, ClaimMappingType?newType)
        {
            RequireAuthenticatedUser();
            RequireClaims(AuthorizationClaim.AuthorizationConfigure);

            var foundClaims = await ClaimMappingRepository.SearchBriefsAsync(new ClaimMappingSearchCriteria
            {
                Claims  = new[] { claim },
                RoleIds = new[] { roleId },
                GuildId = CurrentGuildId
            });

            using (var transaction = await ClaimMappingRepository.BeginCreateTransactionAsync())
            {
                foreach (var existing in foundClaims)
                {
                    await ClaimMappingRepository.TryDeleteAsync(existing.Id, CurrentUserId.Value);
                }

                if (newType.HasValue)
                {
                    await ClaimMappingRepository.CreateAsync(new ClaimMappingCreationData()
                    {
                        GuildId     = CurrentGuildId.Value,
                        Type        = newType.Value,
                        RoleId      = roleId,
                        Claim       = claim,
                        CreatedById = CurrentUserId.Value
                    });
                }

                transaction.Commit();
            }
        }
Esempio n. 4
0
        /// <inheritdoc />
        public async Task OnAuthenticatedAsync(ulong guildId, IEnumerable <ulong> roleIds, ulong userId)
        {
            CurrentGuildId = guildId;
            CurrentUserId  = userId;

            var claims = new HashSet <AuthorizationClaim>();

            foreach (var claimMapping in (await ClaimMappingRepository
                                          .SearchBriefsAsync(new ClaimMappingSearchCriteria()
            {
                GuildId = guildId,
                RoleIds = roleIds.ToArray(),
                UserId = userId,
                IsRescinded = false
            }))
                     // Evaluate role mappings (userId is null) first, to give user mappings precedence.
                     .OrderBy(x => x.UserId)
                     // Evaluate granted mappings first, to give denied mappings precedence.
                     .ThenBy(x => x.Type))
            {
                if (claimMapping.Type == ClaimMappingType.Granted)
                {
                    claims.Add(claimMapping.Claim);
                }
                else
                {
                    claims.Remove(claimMapping.Claim);
                }
            }

            CurrentClaims = claims;
        }
        public ActionResult AddClaimMapping()
        {
            // TODO: sanitize input and add AntiForgeryToken
            var incomingClaimType = this.Request.Form["IncomingClaimType"];
            var incomingValue     = this.Request.Form["IncomingValue"];
            var roleName          = this.Request.Form["NewRole"];
            var organization      = ClaimHelper.GetCurrentUserClaim(Fabrikam.ClaimTypes.Organization).Value;

            var claimMappingsRepository = new ClaimMappingRepository();
            var role = claimMappingsRepository.GetRoleByName(roleName);

            if (this.ValidateClaimMapping(incomingClaimType, incomingValue, role, organization, claimMappingsRepository))
            {
                claimMappingsRepository.SaveClaimMapping(
                    new ClaimMapping
                {
                    IncomingClaimType = incomingClaimType,
                    IncomingValue     = incomingValue,
                    OutputRole        = role,
                    Organization      = organization
                });
            }

            return(this.ClaimMappings());
        }
Esempio n. 6
0
        /// <inheritdoc />
        public async Task RemoveClaimMappingAsync(IGuildUser user, ClaimMappingType type, AuthorizationClaim claim)
        {
            RequireClaims(AuthorizationClaim.AuthorizationConfigure);

            using (var transaction = await ClaimMappingRepository.BeginDeleteTransactionAsync())
            {
                var mappingIds = await ClaimMappingRepository.SearchIdsAsync(new ClaimMappingSearchCriteria()
                {
                    Types     = new[] { type },
                    GuildId   = user.Guild.Id,
                    UserId    = user.Id,
                    Claims    = new[] { claim },
                    IsDeleted = false,
                });

                if (!mappingIds.Any())
                {
                    throw new InvalidOperationException($"A claim mapping of type {type} to claim {claim} for user {user.GetDisplayName()} does not exist");
                }

                await ClaimMappingRepository.TryDeleteAsync(mappingIds.First(), CurrentUserId.Value);

                transaction.Commit();
            }
        }
Esempio n. 7
0
        /// <inheritdoc />
        public async Task AutoConfigureGuildAsync(IGuild guild)
        {
            if (await ClaimMappingRepository.AnyAsync(new ClaimMappingSearchCriteria()
            {
                GuildId = guild.Id,
                IsDeleted = false,
            }))
            {
                return;
            }

            // Need the bot user to exist, before we start adding claims, created by the bot user.
            await UserService.TrackUserAsync(DiscordClient.CurrentUser);

            using (var transaction = await ClaimMappingRepository.BeginCreateTransactionAsync())
            {
                foreach (var claim in Enum.GetValues(typeof(AuthorizationClaim)).Cast <AuthorizationClaim>())
                {
                    foreach (var role in guild.Roles.Where(x => x.Permissions.Administrator))
                    {
                        await ClaimMappingRepository.CreateAsync(new ClaimMappingCreationData()
                        {
                            Type        = ClaimMappingType.Granted,
                            GuildId     = guild.Id,
                            RoleId      = role.Id,
                            UserId      = null,
                            Claim       = claim,
                            CreatedById = DiscordClient.CurrentUser.Id
                        });
                    }
                }

                transaction.Commit();
            }
        }
Esempio n. 8
0
        private async Task <IReadOnlyCollection <AuthorizationClaim> > LookupPosessedClaimsAsync(ulong guildId, IEnumerable <ulong> roleIds, ulong userId, IEnumerable <AuthorizationClaim> claimsFilter = null)
        {
            var posessedClaims = new HashSet <AuthorizationClaim>();

            foreach (var claimMapping in (await ClaimMappingRepository
                                          .SearchBriefsAsync(new ClaimMappingSearchCriteria()
            {
                GuildId = guildId,
                RoleIds = roleIds.ToArray(),
                UserId = userId,
                Claims = claimsFilter?.ToArray(),
                IsDeleted = false
            }))
                     // Evaluate role mappings (userId is null) first, to give user mappings precedence.
                     .OrderBy(x => x.UserId)
                     // Order putting @everyone last
                     .ThenByDescending(x => x.RoleId == guildId)
                     // Evaluate granted mappings first, to give denied mappings precedence.
                     .ThenBy(x => x.Type))
            {
                if (claimMapping.Type == ClaimMappingType.Granted)
                {
                    posessedClaims.Add(claimMapping.Claim);
                }
                else
                {
                    posessedClaims.Remove(claimMapping.Claim);
                }
            }

            return(posessedClaims);
        }
 /// <inheritdoc />
 public async Task UnConfigureGuildAsync(IGuild guild)
 {
     foreach (var claimMappingId in await ClaimMappingRepository.SearchIdsAsync(new ClaimMappingSearchCriteria()
     {
         GuildId = guild.Id,
         IsDeleted = false
     }))
     {
         await ClaimMappingRepository.TryDeleteAsync(claimMappingId, DiscordClient.CurrentUser.Id);
     }
 }
Esempio n. 10
0
 /// <inheritdoc />
 public async Task <IReadOnlyCollection <AuthorizationClaim> > GetGuildRoleClaimsAsync(IRole guildRole)
 {
     return((await ClaimMappingRepository.SearchBriefsAsync(new ClaimMappingSearchCriteria
     {
         RoleIds = new[] { guildRole.Id },
         IsDeleted = false,
         Types = new[] { ClaimMappingType.Granted },
         GuildId = guildRole.Guild.Id
     }))
            .Select(d => d.Claim)
            .ToList());
 }
        public ActionResult ClaimMappings()
        {
            var claimMappingsRepository = new ClaimMappingRepository();
            var organization            = ClaimHelper.GetCurrentUserClaim(Fabrikam.ClaimTypes.Organization).Value;
            var model = new ClaimMappingListViewModel
            {
                ClaimMappings     = claimMappingsRepository.GetClaimMappingsByOrganization(organization),
                OutputRoles       = claimMappingsRepository.GetAllRoles(),
                IncomingClaimType = new[] { ClaimTypes.Name, AllOrganizations.ClaimTypes.Group }
            };

            return(this.View("ClaimMappings", model));
        }
        private static (ModixContext, ClaimMappingRepository) BuildTestContext()
        {
            var modixContext = TestDataContextFactory.BuildTestDataContext(x =>
            {
                x.Users.AddRange(Users.Entities.Clone());
                x.GuildUsers.AddRange(GuildUsers.Entities.Clone());
                x.ClaimMappings.AddRange(ClaimMappings.Entities.Clone());
                x.ConfigurationActions.AddRange(ConfigurationActions.Entities.Where(y => !(y.ClaimMappingId is null)).Clone());
            });

            var uut = new ClaimMappingRepository(modixContext);

            return(modixContext, uut);
        }
Esempio n. 13
0
        /// <inheritdoc />
        public async Task RemoveClaimMapping(IRole role, ClaimMappingType type, AuthorizationClaim claim)
        {
            RequireAuthenticatedUser();
            RequireClaims(AuthorizationClaim.AuthorizationConfigure);

            var mappingIds = (await ClaimMappingRepository.SearchIdsAsync(new ClaimMappingSearchCriteria()
            {
                Types = new[] { type },
                GuildId = role.Guild.Id,
                RoleIds = new[] { role.Id },
                Claims = new[] { claim },
                IsDeleted = false,
            }));

            if (!mappingIds.Any())
            {
                throw new InvalidOperationException($"A claim mapping of type {type} to claim {claim} for role {role.Name} does not exist");
            }

            await ClaimMappingRepository.TryDeleteAsync(mappingIds.First(), CurrentUserId.Value);
        }
        private bool ValidateClaimMapping(string incomingClaimType, string incomingValue, Role role, string organization, ClaimMappingRepository repository)
        {
            bool valid = true;

            if (string.IsNullOrEmpty(incomingClaimType))
            {
                this.ViewData.ModelState.AddModelError("IncomingClaimType", @"The Incoming Claim Type field is required.");
                valid = false;
            }

            if (string.IsNullOrEmpty(incomingValue))
            {
                this.ViewData.ModelState.AddModelError("IncomingValue", @"The Incoming Value field is required.");
                this.ModelState.SetModelValue("IncomingValue",
                                              new ValueProviderResult(this.ValueProvider.GetValue("IncomingValue") != null ? this.ValueProvider.GetValue("IncomingValue").AttemptedValue : string.Empty, string.Empty, CultureInfo.CurrentCulture));
                valid = false;
            }

            if (role == null)
            {
                this.ViewData.ModelState.AddModelError("RoleRequired", @"The OutputRole field is required.");
                valid = false;
            }
            else
            {
                var existingMapping = repository.GetClaimMapping(incomingClaimType, incomingValue, role, organization);
                if (existingMapping != null)
                {
                    this.ViewData.ModelState.AddModelError("DuplicatedMapping", @"A Claim Mapping already exists for this parameters.");
                    valid = false;
                }
            }

            return(valid);
        }