Invite filtering works
This commit is contained in:
parent
0df0eea6c0
commit
f7b3b67197
@ -177,6 +177,42 @@ namespace NadekoBot.Migrations
|
|||||||
b.ToTable("EightBallResponses");
|
b.ToTable("EightBallResponses");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<ulong>("ChannelId");
|
||||||
|
|
||||||
|
b.Property<int?>("GuildConfigId");
|
||||||
|
|
||||||
|
b.Property<int?>("GuildConfigId1");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GuildConfigId");
|
||||||
|
|
||||||
|
b.HasIndex("GuildConfigId1");
|
||||||
|
|
||||||
|
b.ToTable("FilterChannelId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int?>("GuildConfigId");
|
||||||
|
|
||||||
|
b.Property<string>("Word");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GuildConfigId");
|
||||||
|
|
||||||
|
b.ToTable("FilteredWord");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@ -230,6 +266,10 @@ namespace NadekoBot.Migrations
|
|||||||
|
|
||||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||||
|
|
||||||
|
b.Property<bool>("FilterInvites");
|
||||||
|
|
||||||
|
b.Property<bool>("FilterWords");
|
||||||
|
|
||||||
b.Property<ulong?>("GenerateCurrencyChannelId");
|
b.Property<ulong?>("GenerateCurrencyChannelId");
|
||||||
|
|
||||||
b.Property<ulong>("GreetMessageChannelId");
|
b.Property<ulong>("GreetMessageChannelId");
|
||||||
@ -576,6 +616,24 @@ namespace NadekoBot.Migrations
|
|||||||
.HasForeignKey("BotConfigId");
|
.HasForeignKey("BotConfigId");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||||
|
.WithMany("FilterInvitesChannelIds")
|
||||||
|
.HasForeignKey("GuildConfigId");
|
||||||
|
|
||||||
|
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||||
|
.WithMany("FilterWordsChannelIds")
|
||||||
|
.HasForeignKey("GuildConfigId1");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||||
|
.WithMany("FilteredWords")
|
||||||
|
.HasForeignKey("GuildConfigId");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||||
|
@ -13,6 +13,7 @@ using NadekoBot.Services.Database.Models;
|
|||||||
using NadekoBot.Modules.Permissions;
|
using NadekoBot.Modules.Permissions;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
|
using NadekoBot.Extensions;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
@ -33,14 +34,14 @@ namespace NadekoBot.Services
|
|||||||
_client.MessageReceived += MessageReceivedHandler;
|
_client.MessageReceived += MessageReceivedHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task MessageReceivedHandler(IMessage msg)
|
private async Task MessageReceivedHandler(IMessage msg)
|
||||||
{
|
{
|
||||||
var usrMsg = msg as IUserMessage;
|
var usrMsg = msg as IUserMessage;
|
||||||
if (usrMsg == null)
|
if (usrMsg == null)
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
|
|
||||||
if (usrMsg.Author.IsBot) //no bots
|
if (usrMsg.Author.IsBot) //no bots
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
|
|
||||||
var guild = (msg.Channel as ITextChannel)?.Guild;
|
var guild = (msg.Channel as ITextChannel)?.Guild;
|
||||||
|
|
||||||
@ -51,83 +52,124 @@ namespace NadekoBot.Services
|
|||||||
(bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == usrMsg.Author.Id))) != null)
|
(bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == usrMsg.Author.Id))) != null)
|
||||||
{
|
{
|
||||||
_log.Warn("Attempt was made to run a command by a blacklisted {0}, id: {1}", blacklistedItem.Type, blacklistedItem.ItemId);
|
_log.Warn("Attempt was made to run a command by a blacklisted {0}, id: {1}", blacklistedItem.Type, blacklistedItem.ItemId);
|
||||||
return Task.CompletedTask;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var throwaway = Task.Run(async () =>
|
if (guild != null)
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
if (Permissions.FilterCommands.InviteFilteringChannels.Contains(usrMsg.Channel.Id) ||
|
||||||
sw.Start();
|
Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id))
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
if (usrMsg.Content.IsDiscordInvite())
|
||||||
bool verbose = false;
|
|
||||||
Permission rootPerm = null;
|
|
||||||
string permRole = "";
|
|
||||||
if (guild != null)
|
|
||||||
{
|
{
|
||||||
using (var uow = DbHandler.UnitOfWork())
|
try
|
||||||
{
|
{
|
||||||
var config = uow.GuildConfigs.PermissionsFor(guild.Id);
|
await usrMsg.DeleteAsync().ConfigureAwait(false);
|
||||||
verbose = config.VerbosePermissions;
|
return;
|
||||||
rootPerm = config.RootPermission;
|
|
||||||
permRole = config.PermissionRole.Trim().ToLowerInvariant();
|
|
||||||
}
|
}
|
||||||
}
|
catch (HttpException ex)
|
||||||
|
|
||||||
|
|
||||||
var t = await ExecuteCommand(usrMsg, usrMsg.Content, guild, usrMsg.Author, rootPerm, permRole, MultiMatchHandling.Best);
|
|
||||||
var command = t.Item1;
|
|
||||||
var result = t.Item2;
|
|
||||||
sw.Stop();
|
|
||||||
var channel = (usrMsg.Channel as ITextChannel);
|
|
||||||
if (result.IsSuccess)
|
|
||||||
{
|
|
||||||
CommandExecuted(this, new CommandExecutedEventArgs(usrMsg, command));
|
|
||||||
_log.Info("Command Executed after {4}s\n\t" +
|
|
||||||
"User: {0}\n\t" +
|
|
||||||
"Server: {1}\n\t" +
|
|
||||||
"Channel: {2}\n\t" +
|
|
||||||
"Message: {3}",
|
|
||||||
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
|
||||||
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
|
||||||
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
|
||||||
usrMsg.Content, // {3}
|
|
||||||
sw.Elapsed.TotalSeconds // {4}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (!result.IsSuccess && result.Error != CommandError.UnknownCommand)
|
|
||||||
{
|
|
||||||
_log.Warn("Command Errored after {5}s\n\t" +
|
|
||||||
"User: {0}\n\t" +
|
|
||||||
"Server: {1}\n\t" +
|
|
||||||
"Channel: {2}\n\t" +
|
|
||||||
"Message: {3}\n\t" +
|
|
||||||
"Error: {4}",
|
|
||||||
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
|
||||||
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
|
||||||
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
|
||||||
usrMsg.Content,// {3}
|
|
||||||
result.ErrorReason, // {4}
|
|
||||||
sw.Elapsed.TotalSeconds // {5}
|
|
||||||
);
|
|
||||||
if (guild != null && command != null && result.Error == CommandError.Exception)
|
|
||||||
{
|
{
|
||||||
if (verbose)
|
_log.Warn("I do not have permission to filter invites in channel with id " + usrMsg.Channel.Id, ex);
|
||||||
await msg.Channel.SendMessageAsync(":warning: " + result.ErrorReason).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
var filteredWords = Permissions.FilterCommands.FilteredWordsForChannel(usrMsg.Channel.Id, guild.Id).Concat(Permissions.FilterCommands.FilteredWordsForServer(guild.Id));
|
||||||
|
var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
|
||||||
|
if (filteredWords.Any())
|
||||||
{
|
{
|
||||||
_log.Warn(ex, "Error in CommandHandler");
|
try
|
||||||
if(ex.InnerException != null)
|
{
|
||||||
_log.Warn(ex.InnerException, "Inner Exception of the error in CommandHandler");
|
await usrMsg.DeleteAsync().ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (HttpException ex)
|
||||||
|
{
|
||||||
|
_log.Warn("I do not have permission to filter words in channel with id " + usrMsg.Channel.Id, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
try
|
||||||
|
{
|
||||||
|
bool verbose = false;
|
||||||
|
Permission rootPerm = null;
|
||||||
|
string permRole = "";
|
||||||
|
if (guild != null)
|
||||||
|
{
|
||||||
|
using (var uow = DbHandler.UnitOfWork())
|
||||||
|
{
|
||||||
|
var config = uow.GuildConfigs.PermissionsFor(guild.Id);
|
||||||
|
verbose = config.VerbosePermissions;
|
||||||
|
rootPerm = config.RootPermission;
|
||||||
|
permRole = config.PermissionRole.Trim().ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var throwaway = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var t = await ExecuteCommand(usrMsg, usrMsg.Content, guild, usrMsg.Author, rootPerm, permRole, MultiMatchHandling.Best);
|
||||||
|
var command = t.Item1;
|
||||||
|
var result = t.Item2;
|
||||||
|
sw.Stop();
|
||||||
|
var channel = (usrMsg.Channel as ITextChannel);
|
||||||
|
if (result.IsSuccess)
|
||||||
|
{
|
||||||
|
CommandExecuted(this, new CommandExecutedEventArgs(usrMsg, command));
|
||||||
|
_log.Info("Command Executed after {4}s\n\t" +
|
||||||
|
"User: {0}\n\t" +
|
||||||
|
"Server: {1}\n\t" +
|
||||||
|
"Channel: {2}\n\t" +
|
||||||
|
"Message: {3}",
|
||||||
|
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
||||||
|
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
||||||
|
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
||||||
|
usrMsg.Content, // {3}
|
||||||
|
sw.Elapsed.TotalSeconds // {4}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (!result.IsSuccess && result.Error != CommandError.UnknownCommand)
|
||||||
|
{
|
||||||
|
_log.Warn("Command Errored after {5}s\n\t" +
|
||||||
|
"User: {0}\n\t" +
|
||||||
|
"Server: {1}\n\t" +
|
||||||
|
"Channel: {2}\n\t" +
|
||||||
|
"Message: {3}\n\t" +
|
||||||
|
"Error: {4}",
|
||||||
|
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
||||||
|
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
||||||
|
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
||||||
|
usrMsg.Content,// {3}
|
||||||
|
result.ErrorReason, // {4}
|
||||||
|
sw.Elapsed.TotalSeconds // {5}
|
||||||
|
);
|
||||||
|
if (guild != null && command != null && result.Error == CommandError.Exception)
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
await msg.Channel.SendMessageAsync(":warning: " + result.ErrorReason).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.Warn(ex, "Error in CommandHandler");
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
_log.Warn(ex.InnerException, "Inner Exception of the error in CommandHandler");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.Error(ex, "Error in the outter scope of the commandhandler.");
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
_log.Error(ex.InnerException, "Inner exception: ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Tuple<Command,IResult>> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, Permission rootPerm, string permRole, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) {
|
public async Task<Tuple<Command,IResult>> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, Permission rootPerm, string permRole, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) {
|
||||||
|
@ -46,5 +46,23 @@ namespace NadekoBot.Services.Database.Models
|
|||||||
public Permission RootPermission { get; set; }
|
public Permission RootPermission { get; set; }
|
||||||
public bool VerbosePermissions { get; set; }
|
public bool VerbosePermissions { get; set; }
|
||||||
public string PermissionRole { get; set; } = "Nadeko";
|
public string PermissionRole { get; set; } = "Nadeko";
|
||||||
|
|
||||||
|
//filtering
|
||||||
|
public bool FilterInvites { get; set; }
|
||||||
|
public HashSet<FilterChannelId> FilterInvitesChannelIds { get; set; }
|
||||||
|
|
||||||
|
public bool FilterWords { get; set; }
|
||||||
|
public HashSet<FilteredWord> FilteredWords { get; set; }
|
||||||
|
public HashSet<FilterChannelId> FilterWordsChannelIds { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilterChannelId :DbEntity
|
||||||
|
{
|
||||||
|
public ulong ChannelId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilteredWord :DbEntity
|
||||||
|
{
|
||||||
|
public string Word { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
.ThenInclude(gc => gc.Previous)
|
.ThenInclude(gc => gc.Previous)
|
||||||
.Include(gc => gc.RootPermission)
|
.Include(gc => gc.RootPermission)
|
||||||
.ThenInclude(gc => gc.Next)
|
.ThenInclude(gc => gc.Next)
|
||||||
|
.Include(gc => gc.FilterInvitesChannelIds)
|
||||||
|
.Include(gc => gc.FilterWordsChannelIds)
|
||||||
|
.Include(gc => gc.FilteredWords)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -37,6 +40,9 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
.ThenInclude(ls => ls.IgnoredChannels)
|
.ThenInclude(ls => ls.IgnoredChannels)
|
||||||
.Include(gc => gc.LogSetting)
|
.Include(gc => gc.LogSetting)
|
||||||
.ThenInclude(ls => ls.IgnoredVoicePresenceChannelIds)
|
.ThenInclude(ls => ls.IgnoredVoicePresenceChannelIds)
|
||||||
|
.Include(gc => gc.FilterInvitesChannelIds)
|
||||||
|
.Include(gc => gc.FilterWordsChannelIds)
|
||||||
|
.Include(gc => gc.FilteredWords)
|
||||||
.FirstOrDefault(c => c.GuildId == guildId);
|
.FirstOrDefault(c => c.GuildId == guildId);
|
||||||
|
|
||||||
if (config == null)
|
if (config == null)
|
||||||
|
@ -298,5 +298,10 @@ namespace NadekoBot.Extensions
|
|||||||
imageStream.Position = 0;
|
imageStream.Position = 0;
|
||||||
return imageStream;
|
return imageStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly Regex filterRegex = new Regex(@"(?:discord(?:\.gg|app\.com\/invite)\/(?<id>([\w]{16}|(?:[\w]+-?){3})))", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
public static bool IsDiscordInvite(this string str)
|
||||||
|
=> filterRegex.IsMatch(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,9 +40,11 @@ namespace Tests
|
|||||||
|
|
||||||
root.Prepend(new Permission() { SecondaryTargetName = "Added" });
|
root.Prepend(new Permission() { SecondaryTargetName = "Added" });
|
||||||
|
|
||||||
|
root = root.GetRoot();
|
||||||
|
|
||||||
Assert.Equal(11, root.Count());
|
Assert.Equal(11, root.Count());
|
||||||
|
|
||||||
Assert.Equal("Added", root.AsEnumerable().Last().SecondaryTargetName);
|
Assert.Equal("Added", root.AsEnumerable().First().SecondaryTargetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -87,15 +89,9 @@ namespace Tests
|
|||||||
|
|
||||||
Assert.Equal("3", removed.SecondaryTargetName);
|
Assert.Equal("3", removed.SecondaryTargetName);
|
||||||
Assert.Equal(9, root.Count());
|
Assert.Equal(9, root.Count());
|
||||||
|
Assert.Throws(typeof(IndexOutOfRangeException), () => { root.RemoveAt(0); });
|
||||||
var temp = root.Next;
|
Assert.Throws(typeof(IndexOutOfRangeException), () => { root.RemoveAt(9); });
|
||||||
removed = root.RemoveAt(0);
|
Assert.Throws(typeof(IndexOutOfRangeException), () => { root.RemoveAt(-1); });
|
||||||
|
|
||||||
Assert.Equal(8, temp.Count());
|
|
||||||
Assert.Equal(null, temp.Previous);
|
|
||||||
|
|
||||||
Assert.Throws(typeof(IndexOutOfRangeException), () => { temp.RemoveAt(8); });
|
|
||||||
Assert.Throws(typeof(IndexOutOfRangeException), () => { temp.RemoveAt(-1); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
Loading…
Reference in New Issue
Block a user