Added FilterList
Several upcoming features will be making use of the same whitelist and blacklist filtering concept that RegexResponder currently uses.
This commit is contained in:
parent
bd46c53a02
commit
8d228a4d7c
4 changed files with 96 additions and 56 deletions
|
@ -7,8 +7,6 @@ using System.Linq;
|
|||
|
||||
namespace Noikoio.RegexBot.ConfigItem
|
||||
{
|
||||
enum FilterType { None, Whitelist, Blacklist }
|
||||
|
||||
/// <summary>
|
||||
/// Represents a structure in bot configuration that contains a list of
|
||||
/// channels, roles, and users.
|
||||
|
@ -70,7 +68,7 @@ namespace Noikoio.RegexBot.ConfigItem
|
|||
/// </summary>
|
||||
/// <param name="msg">An incoming message.</param>
|
||||
/// <returns>
|
||||
/// True if the <see cref="SocketMessage"/> occurred within a channel specified in this list,
|
||||
/// True if '<paramref name="msg"/>' occurred within a channel specified in this list,
|
||||
/// or if the message author belongs to one or more roles in this list, or if the user itself
|
||||
/// is defined within this list.
|
||||
/// </returns>
|
||||
|
@ -125,28 +123,5 @@ namespace Noikoio.RegexBot.ConfigItem
|
|||
// No match.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method for reading whitelist and blacklist filtering lists.
|
||||
/// </summary>
|
||||
/// <param name="section">
|
||||
/// A JSON object which presumably contains an array named "whitelist" or "blacklist".
|
||||
/// </param>
|
||||
public static (FilterType, EntityList) GetFilterList(JObject section)
|
||||
{
|
||||
var mode = FilterType.None;
|
||||
EntityList list;
|
||||
if (section["whitelist"] != null) mode = FilterType.Whitelist;
|
||||
if (section["blacklist"] != null)
|
||||
{
|
||||
if (mode == FilterType.Whitelist)
|
||||
throw new RuleImportException("Cannot have whitelist AND blacklist defined.");
|
||||
mode = FilterType.Blacklist;
|
||||
}
|
||||
if (mode == FilterType.None) list = new EntityList(); // might even be fine to keep it null?
|
||||
else list = new EntityList(section[mode == FilterType.Whitelist ? "whitelist" : "blacklist"]);
|
||||
|
||||
return (mode, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
91
ConfigItem/FilterList.cs
Normal file
91
ConfigItem/FilterList.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using Discord.WebSocket;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Noikoio.RegexBot.ConfigItem
|
||||
{
|
||||
enum FilterType { None, Whitelist, Blacklist }
|
||||
|
||||
/// <summary>
|
||||
/// Represents whitelist/blacklist configuration, including exemptions.
|
||||
/// </summary>
|
||||
struct FilterList
|
||||
{
|
||||
FilterType _type;
|
||||
EntityList _filterList;
|
||||
EntityList _exemptions;
|
||||
|
||||
public FilterType FilterMode => _type;
|
||||
public EntityList FilterEntities => _filterList;
|
||||
public EntityList FilterExemptions => _exemptions;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the
|
||||
/// </summary>
|
||||
/// <param name="conf">
|
||||
/// A JSON object which presumably contains an array named "whitelist" or "blacklist",
|
||||
/// and optionally one named "exempt".
|
||||
/// </param>
|
||||
/// <exception cref="RuleImportException">
|
||||
/// Thrown if both "whitelist" and "blacklist" definitions were found, if
|
||||
/// "exempt" was found without a corresponding "whitelist" or "blacklist",
|
||||
/// or if there was an issue parsing an EntityList within these definitions.
|
||||
/// </exception>
|
||||
public FilterList(JObject conf)
|
||||
{
|
||||
_type = FilterType.None;
|
||||
|
||||
if (conf["whitelist"] != null) _type = FilterType.Whitelist;
|
||||
if (conf["blacklist"] != null)
|
||||
{
|
||||
if (_type != FilterType.None)
|
||||
throw new RuleImportException("Cannot have both 'whitelist' and 'blacklist' values defined.");
|
||||
_type = FilterType.Blacklist;
|
||||
}
|
||||
if (_type == FilterType.None)
|
||||
{
|
||||
_filterList = null;
|
||||
_exemptions = null;
|
||||
if (conf["exempt"] != null)
|
||||
throw new RuleImportException("Cannot have 'exempt' defined if no corresponding " +
|
||||
"'whitelist' or 'blacklist' has been defined in the same section.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_filterList = new EntityList(conf[_type == FilterType.Whitelist ? "whitelist" : "blacklist"]);
|
||||
_exemptions = new EntityList(conf["exempt"]); // EntityList constructor checks for null value
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the parameters of '<paramref name="msg"/>' are a match with filtering
|
||||
/// rules defined in this instance.
|
||||
/// </summary>
|
||||
/// <param name="msg">An incoming message.</param>
|
||||
/// <returns>
|
||||
/// True if the user or channel specified by '<paramref name="msg"/>' is filtered by
|
||||
/// the configuration defined in this instance.
|
||||
/// </returns>
|
||||
public bool IsFiltered(SocketMessage msg)
|
||||
{
|
||||
if (FilterMode == FilterType.None) return false;
|
||||
|
||||
bool inFilter = FilterEntities.ExistsInList(msg);
|
||||
|
||||
if (FilterMode == FilterType.Whitelist)
|
||||
{
|
||||
if (!inFilter) return true;
|
||||
return FilterExemptions.ExistsInList(msg);
|
||||
}
|
||||
else if (FilterMode == FilterType.Blacklist)
|
||||
{
|
||||
if (!inFilter) return false;
|
||||
return !FilterExemptions.ExistsInList(msg);
|
||||
}
|
||||
|
||||
throw new Exception("this shouldn't happen");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -128,7 +128,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
|
|||
// Moderator bypass check
|
||||
if (rule.AllowModBypass == true && srv.Moderators.ExistsInList(msg)) return;
|
||||
// Individual rule filtering check
|
||||
if (IsFiltered(rule, msg)) return;
|
||||
if (rule.Filter.IsFiltered(msg)) return;
|
||||
|
||||
// And finally, pattern matching checks
|
||||
bool success = false;
|
||||
|
@ -221,26 +221,6 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
|
|||
return result.ToString();
|
||||
}
|
||||
|
||||
private bool IsFiltered(RuleConfig r, SocketMessage m)
|
||||
{
|
||||
if (r.FilterMode == FilterType.None) return false;
|
||||
|
||||
bool inFilter = r.FilterList.ExistsInList(m);
|
||||
|
||||
if (r.FilterMode == FilterType.Whitelist)
|
||||
{
|
||||
if (!inFilter) return true;
|
||||
return r.FilterExemptions.ExistsInList(m);
|
||||
}
|
||||
else if (r.FilterMode == FilterType.Blacklist)
|
||||
{
|
||||
if (!inFilter) return false;
|
||||
return !r.FilterExemptions.ExistsInList(m);
|
||||
}
|
||||
|
||||
return false; // this shouldn't happen™
|
||||
}
|
||||
|
||||
private string[] SplitParams(string cmd, int? limit = null)
|
||||
{
|
||||
if (limit.HasValue)
|
||||
|
|
|
@ -15,9 +15,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
|
|||
private string _displayName;
|
||||
private IEnumerable<Regex> _regex;
|
||||
private IEnumerable<string> _responses;
|
||||
private FilterType _filtermode;
|
||||
private EntityList _filterlist;
|
||||
private EntityList _filterexempt;
|
||||
private FilterList _filter;
|
||||
private int? _minLength;
|
||||
private int? _maxLength;
|
||||
private bool _modBypass;
|
||||
|
@ -26,9 +24,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
|
|||
public string DisplayName => _displayName;
|
||||
public IEnumerable<Regex> Regex => _regex;
|
||||
public IEnumerable<string> Responses => _responses;
|
||||
public FilterType FilterMode => _filtermode;
|
||||
public EntityList FilterList => _filterlist;
|
||||
public EntityList FilterExemptions => _filterexempt;
|
||||
public FilterList Filter => _filter;
|
||||
public int? MinLength => _minLength;
|
||||
public int? MaxLength => _maxLength;
|
||||
public bool AllowModBypass => _modBypass;
|
||||
|
@ -131,9 +127,7 @@ namespace Noikoio.RegexBot.Feature.RegexResponder
|
|||
_responses = responses.ToArray();
|
||||
|
||||
// (white|black)list filtering
|
||||
(_filtermode, _filterlist) = EntityList.GetFilterList(ruleconf);
|
||||
// filtering exemptions
|
||||
_filterexempt = new EntityList(ruleconf["exempt"]);
|
||||
_filter = new FilterList(ruleconf);
|
||||
|
||||
// moderator bypass toggle - true by default, must be explicitly set to false
|
||||
bool? modoverride = ruleconf["AllowModBypass"]?.Value<bool>();
|
||||
|
|
Loading…
Reference in a new issue