示例#1
0
        private async Task DoRescindInfractionAsync(InfractionSummary infraction)
        {
            if (infraction == null)
            {
                throw new InvalidOperationException("Infraction does not exist");
            }

            await InfractionRepository.TryRescindAsync(infraction.Id, AuthorizationService.CurrentUserId.Value);

            var guild = await GuildService.GetGuildAsync(infraction.GuildId);

            var subject = await UserService.GetGuildUserAsync(guild.Id, infraction.Subject.Id);

            switch (infraction.Type)
            {
            case InfractionType.Mute:
                await subject.RemoveRoleAsync(
                    await GetOrCreateMuteRoleInGuildAsync(guild));

                break;

            case InfractionType.Ban:
                await guild.RemoveBanAsync(subject);

                break;

            default:
                throw new InvalidOperationException($"{infraction.Type} infractions cannot be rescinded.");
            }
        }
示例#2
0
        /// <inheritdoc />
        public async Task DeleteInfractionAsync(long infractionId)
        {
            AuthorizationService.RequireAuthenticatedUser();
            AuthorizationService.RequireClaims(AuthorizationClaim.ModerationDelete);

            var infraction = await InfractionRepository.ReadSummaryAsync(infractionId);

            if (infraction == null)
            {
                throw new InvalidOperationException($"Infraction {infractionId} does not exist");
            }

            await InfractionRepository.TryDeleteAsync(infraction.Id, AuthorizationService.CurrentUserId.Value);

            var guild = await GuildService.GetGuildAsync(infraction.GuildId);

            var subject = await UserService.GetGuildUserAsync(guild.Id, infraction.Subject.Id);

            switch (infraction.Type)
            {
            case InfractionType.Mute:
                await subject.RemoveRoleAsync(
                    await GetOrCreateMuteRoleInGuildAsync(guild));

                break;

            case InfractionType.Ban:
                await guild.RemoveBanAsync(subject);

                break;
            }
        }
示例#3
0
        private async Task DoDiscordUnBanAsync(ulong subjectId)
        {
            AuthorizationService.RequireAuthenticatedGuild();
            AuthorizationService.RequireAuthenticatedUser();

            var guild = await GuildService.GetGuildAsync(AuthorizationService.CurrentGuildId.Value);

            var subject = await UserService.GetGuildUserAsync(guild.Id, subjectId);

            if (!(await guild.GetBansAsync()).Any(x => x.User.Id == subject.Id))
            {
                throw new InvalidOperationException($"Discord user {subjectId} is not currently banned");
            }

            await guild.AddBanAsync(subject);
        }
示例#4
0
        private async Task DoDiscordUnMuteAsync(ulong subjectId)
        {
            AuthorizationService.RequireAuthenticatedGuild();
            AuthorizationService.RequireAuthenticatedUser();

            var guild = await GuildService.GetGuildAsync(AuthorizationService.CurrentGuildId.Value);

            var muteRole = await GetOrCreateMuteRoleAsync(guild);

            var subject = await UserService.GetGuildUserAsync(guild.Id, subjectId);

            if (!subject.RoleIds.Contains(muteRole.Id))
            {
                throw new InvalidOperationException($"Discord user {subjectId} is not currently muted");
            }

            await subject.AddRoleAsync(muteRole);
        }
示例#5
0
        /// <inheritdoc />
        public async Task CreateInfractionAsync(InfractionType type, ulong subjectId, string reason, TimeSpan?duration)
        {
            AuthorizationService.RequireAuthenticatedGuild();
            AuthorizationService.RequireAuthenticatedUser();
            AuthorizationService.RequireClaims(_createInfractionClaimsByType[type]);

            var guild = await GuildService.GetGuildAsync(AuthorizationService.CurrentGuildId.Value);

            var subject = await UserService.GetGuildUserAsync(guild.Id, subjectId);

            if (reason == null)
            {
                throw new ArgumentNullException(nameof(reason));
            }

            if (((type == InfractionType.Notice) || (type == InfractionType.Warning)) &&
                string.IsNullOrWhiteSpace(reason))
            {
                throw new InvalidOperationException($"{type.ToString()} infractions require a reason to be given");
            }

            using (var transaction = await InfractionRepository.BeginCreateTransactionAsync())
            {
                if ((type == InfractionType.Mute) || (type == InfractionType.Ban))
                {
                    if (await InfractionRepository.AnyAsync(new InfractionSearchCriteria()
                    {
                        GuildId = guild.Id,
                        Types = new[] { type },
                        SubjectId = subject.Id,
                        IsRescinded = false,
                        IsDeleted = false
                    }))
                    {
                        throw new InvalidOperationException($"Discord user {subjectId} already has an active {type} infraction");
                    }
                }

                await InfractionRepository.CreateAsync(
                    new InfractionCreationData()
                {
                    GuildId     = guild.Id,
                    Type        = type,
                    SubjectId   = subjectId,
                    Reason      = reason,
                    Duration    = duration,
                    CreatedById = AuthorizationService.CurrentUserId.Value
                });

                transaction.Commit();
            }

            // TODO: Implement ModerationSyncBehavior to listen for mutes and bans that happen directly in Discord, instead of through bot commands,
            // and to read the Discord Audit Log to check for mutes and bans that were missed during downtime, and add all such actions to
            // the Infractions and ModerationActions repositories.
            // Note that we'll need to upgrade to the latest Discord.NET version to get access to the audit log.

            // Assuming that our Infractions repository is always correct, regarding the state of the Discord API.
            switch (type)
            {
            case InfractionType.Mute:
                await subject.AddRoleAsync(
                    await GetOrCreateMuteRoleInGuildAsync(guild));

                break;

            case InfractionType.Ban:
                await guild.AddBanAsync(subject, reason : reason);

                break;
            }
        }