/// <summary> /// Creates a ban infraction for the user if they do not already have one. /// </summary> /// <param name="guild">The guild that the user was banned from.</param> /// <param name="user">The user who was banned.</param> /// <returns> /// A <see cref="Task"/> that will complete when the operation completes. /// </returns> private async Task TryCreateBanInfractionAsync(ISocketUser user, ISocketGuild guild) { if (await _moderationService.AnyInfractionsAsync(GetBanSearchCriteria(guild, user))) { return; } var restGuild = await _restClient.GetGuildAsync(guild.Id); var auditLogs = (await restGuild.GetAuditLogsAsync(10) .FlattenAsync()) .Where(x => x.Action == ActionType.Ban && x.Data is BanAuditLogData) .Select(x => (Entry: x, Data: (BanAuditLogData)x.Data)); var banLog = auditLogs.FirstOrDefault(x => x.Data.Target.Id == user.Id); var reason = string.IsNullOrWhiteSpace(banLog.Entry.Reason) ? $"Banned by {banLog.Entry.User.GetFullUsername()}." : banLog.Entry.Reason; var guildUser = guild.GetUser(banLog.Entry.User.Id); await _authorizationService.OnAuthenticatedAsync(guildUser); await _moderationService.CreateInfractionAsync(guild.Id, banLog.Entry.User.Id, InfractionType.Ban, user.Id, reason, null); }
/// <summary> /// Creates a ban infraction for the user if they do not already have one. /// </summary> /// <param name="guild">The guild that the user was banned from.</param> /// <param name="user">The user who was banned.</param> /// <returns> /// A <see cref="Task"/> that will complete when the operation completes. /// </returns> private async Task TryCreateBanInfractionAsync(ISocketUser user, ISocketGuild guild) { if (await _moderationService.AnyInfractionsAsync(GetBanSearchCriteria(guild, user))) { return; } var restGuild = await _restClient.GetGuildAsync(guild.Id); var allAudits = await restGuild.GetAuditLogsAsync(10).FlattenAsync(); var banLog = allAudits .Where(x => x.Action == ActionType.Ban && x.Data is BanAuditLogData) .Select(x => (Entry: x, Data: (BanAuditLogData)x.Data)) .FirstOrDefault(x => x.Data.Target.Id == user.Id); // We're in a scenario in where the guild does not have a Discord audit of the // ban MODiX just received, if that's the case something has gone wrong and we // need to investigate. if (banLog.Data is null || banLog.Entry is null) { // Snapshot the most amount of information possible about this event // to log this incident and investigate further var mostRecentAudit = allAudits.OrderByDescending(x => x.CreatedAt).FirstOrDefault(); Log.Error("No ban audit found when handling {message} for user {userId}, in guild {guild} - " + "the most recent audit was created at {mostRecentAuditTime}: {mostRecentAuditAction} for user: {mostRecentAuditUserId}", nameof(UserBannedNotification), user.Id, guild.Id, mostRecentAudit?.CreatedAt, mostRecentAudit?.Action, mostRecentAudit?.User.Id); return; } var reason = string.IsNullOrWhiteSpace(banLog.Entry.Reason) ? $"Banned by {banLog.Entry.User.GetFullUsername()}." : banLog.Entry.Reason; var guildUser = guild.GetUser(banLog.Entry.User.Id); await _authorizationService.OnAuthenticatedAsync(guildUser); await _moderationService.CreateInfractionAsync(guild.Id, banLog.Entry.User.Id, InfractionType.Ban, user.Id, reason, null); }
/// <summary> /// Creates a ban infraction for the user if they do not already have one. /// </summary> /// <param name="guild">The guild that the user was banned from.</param> /// <param name="user">The user who was banned.</param> /// <returns> /// A <see cref="Task"/> that will complete when the operation completes. /// </returns> private async Task TryCreateBanInfractionAsync(IGuild guild, IUser user) { if (await _moderationService.AnyInfractionsAsync(GetBanSearchCriteria(guild, user))) { return; } var restGuild = await _restClient.GetGuildAsync(guild.Id); var auditLogs = (await restGuild.GetAuditLogsAsync(10) .FlattenAsync()) .Where(x => x.Action == ActionType.Ban) .Select(x => (Entry: x, Data: (BanAuditLogData)x.Data)); var banLog = auditLogs.FirstOrDefault(x => x.Data.Target.Id == user.Id); var reason = string.IsNullOrWhiteSpace(banLog.Entry.Reason) ? $"Banned by {banLog.Entry.User.GetDisplayNameWithDiscriminator()}." : banLog.Entry.Reason; await _moderationService.CreateInfractionAsync(guild.Id, banLog.Entry.User.Id, InfractionType.Ban, user.Id, reason, null); }
/// <summary> /// Mutes the user if they have an active mute infraction in the guild. /// </summary> /// <param name="guild">The guild that the user joined.</param> /// <param name="user">The user who joined the guild.</param> /// <returns> /// A <see cref="Task"/> that will complete when the operation completes. /// </returns> private async Task TryMuteUserAsync(ISocketGuildUser guildUser) { var userHasActiveMuteInfraction = await _moderationService.AnyInfractionsAsync(new InfractionSearchCriteria() { GuildId = guildUser.GuildId, IsDeleted = false, IsRescinded = false, SubjectId = guildUser.Id, Types = new[] { InfractionType.Mute }, }); if (!userHasActiveMuteInfraction) { Log.Debug("User {0} was not muted, because they do not have any active mute infractions.", guildUser.Id); return; } var muteRole = await _moderationService.GetOrCreateDesignatedMuteRoleAsync(guildUser.Guild, _discordSocketClient.CurrentUser.Id); Log.Debug("User {0} was muted, because they have an active mute infraction.", guildUser.Id); await guildUser.AddRoleAsync(muteRole); }