spirit ban, permission checkers, permissions almost done

This commit is contained in:
Master Kwoth 2016-02-12 01:56:55 +01:00
parent c1fb5397ce
commit fdd5824580
11 changed files with 253 additions and 27 deletions

View File

@ -16,8 +16,28 @@ namespace NadekoBot.Classes.Permissions {
public PermissionChecker() { }
public bool CanRun(Command command, User user, Channel channel, out string error) {
error = string.Empty;
error = null;
try {
//is it a permission command?
if (command.Text == "Permissions")
// if it is, check if the user has the correct role
// if yes return true, if no return false
if (user.Server.IsOwner || user.HasRole(PermissionHelper.ValidateRole(user.Server, PermissionsHandler.GetServerPermissionsRoleName(user.Server))))
return true;
else
throw new Exception("You do not have necessary role to change permissions.");
var permissionType = PermissionsHandler.GetPermissionBanType(command, user, channel);
if (permissionType == PermissionsHandler.PermissionBanType.None)
return true;
throw new InvalidOperationException($"Cannot run this command: {permissionType}");
} catch (Exception ex) {
if (PermissionsHandler._permissionsDict[user.Server].Verbose) //if verbose - print errors
channel.SendMessage(ex.Message);
return false;
}
}
}
}

View File

@ -59,6 +59,9 @@ namespace NadekoBot.Classes {
internal static Role ValidateRole(Server server, string roleName) {
if (string.IsNullOrWhiteSpace(roleName))
throw new ArgumentNullException(nameof(roleName));
if (roleName.Trim() == "everyone")
roleName = "@everyone";
var role = server.FindRoles(roleName).FirstOrDefault();
if (role == null)
throw new NullReferenceException("That role does not exist.");

View File

@ -14,12 +14,20 @@ namespace NadekoBot.Classes.Permissions {
public static ConcurrentDictionary<Server, ServerPermissions> _permissionsDict =
new ConcurrentDictionary<Server, ServerPermissions>();
public enum PermissionBanType {
None, ServerBanCommand, ServerBanModule,
ChannelBanCommand, ChannelBanModule, RoleBanCommand,
RoleBanModule, UserBanCommand, UserBanModule
}
public static void Initialize() {
Console.WriteLine("Reading from the permission files.");
Directory.CreateDirectory("data/permissions");
foreach (var file in Directory.EnumerateFiles("data/permissions/")) {
try {
var strippedFileName = file.Substring(file.LastIndexOf('/') + 1, file.LastIndexOf(".json") - file.LastIndexOf('/') - 1);
var strippedFileName = Path.GetFileNameWithoutExtension(file);
var id = ulong.Parse(strippedFileName);
var server = NadekoBot.client.GetServer(id);
if (server == null)
@ -34,6 +42,110 @@ namespace NadekoBot.Classes.Permissions {
Console.WriteLine("Permission initialization complete.");
}
internal static Permissions GetRolePermissionsById(Server server, ulong id) {
if (!_permissionsDict.ContainsKey(server))
return null;
Permissions toReturn;
_permissionsDict[server].RolePermissions.TryGetValue(id, out toReturn);
return toReturn;
}
internal static Permissions GetUserPermissionsById(Server server, ulong id) {
if (!_permissionsDict.ContainsKey(server))
return null;
Permissions toReturn;
_permissionsDict[server].UserPermissions.TryGetValue(id, out toReturn);
return toReturn;
}
internal static Permissions GetChannelPermissionsById(Server server, ulong id) {
if (!_permissionsDict.ContainsKey(server))
return null;
Permissions toReturn;
_permissionsDict[server].ChannelPermissions.TryGetValue(id, out toReturn);
return toReturn;
}
internal static Permissions GetServerPermissions(Server server) {
if (!_permissionsDict.ContainsKey(server))
return null;
return _permissionsDict[server].Permissions;
}
internal static PermissionBanType GetPermissionBanType(Command command, User user, Channel channel) {
var server = user.Server;
if (!_permissionsDict.ContainsKey(server)) {
_permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name));
}
bool val;
Permissions perm;
//server
if (_permissionsDict[server].Permissions.modules.TryGetValue(command.Category, out val) && val == false)
return PermissionBanType.ServerBanModule;
if (_permissionsDict[server].Permissions.commands.TryGetValue(command.Text, out val) && val == false)
return PermissionBanType.ServerBanCommand;
//channel
if (_permissionsDict[server].ChannelPermissions.TryGetValue(channel.Id, out perm) &&
perm.modules.TryGetValue(command.Category, out val) && val == false)
return PermissionBanType.ChannelBanModule;
if (_permissionsDict[server].ChannelPermissions.TryGetValue(channel.Id, out perm) &&
perm.commands.TryGetValue(command.Text, out val) && val == false)
return PermissionBanType.ChannelBanCommand;
//ROLE PART - TWO CASES
// FIRST CASE:
// IF EVERY ROLE USER HAS IS BANNED FROM THE MODULE,
// THAT MEANS USER CANNOT RUN THIS COMMAND
// IF AT LEAST ONE ROLE EXIST THAT IS NOT BANNED,
// USER CAN RUN THE COMMAND
bool foundNotBannedRole = false;
foreach (var role in user.Roles) {
//if every role is banned from using the module -> rolebanmodule
if (_permissionsDict[server].RolePermissions.TryGetValue(role.Id, out perm) &&
perm.modules.TryGetValue(command.Category, out val) && val == false)
continue;
else {
foundNotBannedRole = true;
break;
}
}
if (!foundNotBannedRole)
return PermissionBanType.RoleBanModule;
// SECOND CASE:
// IF EVERY ROLE USER HAS IS BANNED FROM THE COMMAND,
// THAT MEANS USER CANNOT RUN THAT COMMAND
// IF AT LEAST ONE ROLE EXISTS THAT IS NOT BANNED,
// USER CAN RUN THE COMMAND
foundNotBannedRole = false;
foreach (var role in user.Roles) {
//if every role is banned from using the module -> rolebanmodule
if (_permissionsDict[server].RolePermissions.TryGetValue(role.Id, out perm) &&
perm.commands.TryGetValue(command.Text, out val) && val == false)
continue;
else {
foundNotBannedRole = true;
break;
}
}
if (!foundNotBannedRole)
return PermissionBanType.RoleBanCommand;
//user
if (_permissionsDict[server].UserPermissions.TryGetValue(user.Id, out perm) &&
perm.modules.TryGetValue(command.Category, out val) && val == false)
return PermissionBanType.UserBanModule;
if (_permissionsDict[server].UserPermissions.TryGetValue(user.Id, out perm) &&
perm.commands.TryGetValue(command.Text, out val) && val == false)
return PermissionBanType.UserBanCommand;
return PermissionBanType.None;
}
private static void WriteServerToJson(Server server) {
string pathToFile = $"data/permissions/{server.Id}.json";
File.WriteAllText(pathToFile, Newtonsoft.Json.JsonConvert.SerializeObject(_permissionsDict[server], Newtonsoft.Json.Formatting.Indented));
@ -46,6 +158,13 @@ namespace NadekoBot.Classes.Permissions {
}
}
public static string GetServerPermissionsRoleName(Server server) {
if (!_permissionsDict.ContainsKey(server)) {
_permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name));
}
return _permissionsDict[server].PermissionsControllerRole;
}
public static void SetServerModulePermission(Server server, string moduleName, bool value) {
if (!_permissionsDict.ContainsKey(server)) {
_permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name));
@ -194,13 +313,32 @@ namespace NadekoBot.Classes.Permissions {
modules = new Dictionary<string, bool>();
commands = new Dictionary<string, bool>();
}
public override string ToString() {
string toReturn = "";
var bannedModules = modules.Where(kvp => kvp.Value == false);
if (bannedModules.Count() > 0) {
toReturn += "`Banned Modules:`\n";
foreach (var m in bannedModules) {
toReturn += $"\t`[x] {m.Key}`\n";
}
}
var bannedCommands = commands.Where(kvp => kvp.Value == false);
if (bannedCommands.Count() > 0) {
toReturn += "`Banned Commands:`\n";
foreach (var c in bannedCommands) {
toReturn += $"\t`[x] {c.Key}`\n";
}
}
return toReturn;
}
}
public class ServerPermissions {
/// <summary>
/// The guy who can edit the permissions
/// </summary>
public string PermissionsControllerRoleName { get; set; }
public string PermissionsControllerRole { get; set; }
/// <summary>
/// Does it print the error when a restriction occurs
/// </summary>
@ -220,7 +358,7 @@ namespace NadekoBot.Classes.Permissions {
public ServerPermissions(ulong id, string name) {
Id = id;
PermissionsControllerRoleName = "PermissionsKing";
PermissionsControllerRole = "Nadeko";
Verbose = true;
Permissions = new Permissions(name);

View File

@ -44,6 +44,8 @@ namespace NadekoBot.Modules {
manager.CreateCommands(NadekoBot.botMention, cgb => {
var client = manager.Client;
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(cmd => cmd.Init(cgb));
cgb.CreateCommand("uptime")

View File

@ -18,6 +18,8 @@ namespace NadekoBot.Modules
{
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(com => com.Init(cgb));
cgb.CreateCommand("$raffle")

View File

@ -28,6 +28,8 @@ namespace NadekoBot.Modules
{
commands.ForEach(cmd => cmd.Init(cgb));
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
cgb.CreateCommand(">choose")
.Description("Chooses a thing from a list of things\n**Usage**: >choose Get up;Sleep more;Sleep even more")
.Parameter("list", Discord.Commands.ParameterType.Unparsed)

View File

@ -28,7 +28,9 @@ namespace NadekoBot.Modules {
var client = NadekoBot.client;
manager.CreateCommands("!m", cgb => {
//queue all more complex commands
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(cmd => cmd.Init(cgb));
cgb.CreateCommand("n")

View File

@ -16,6 +16,9 @@ namespace NadekoBot.Modules {
public override void Install(ModuleManager manager) {
manager.CreateCommands("", cgb => {
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
cgb.CreateCommand("~hentai")
.Description("Shows a random NSFW hentai image from gelbooru and danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Parameter("tag", ParameterType.Unparsed)
@ -27,7 +30,7 @@ namespace NadekoBot.Modules {
await e.Send(":heart: Danbooru: " + await SearchHelper.GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~danbooru")
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~danbooru yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");
@ -36,7 +39,7 @@ namespace NadekoBot.Modules {
await e.Send(await SearchHelper.GetDanbooruImageLink(tag));
});
cgb.CreateCommand("~gelbooru")
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~hentai yuri")
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered.\n**Usage**: ~gelbooru yuri")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e => {
string tag = e.GetArg("tag");

View File

@ -8,7 +8,7 @@ using PermsHandler = NadekoBot.Classes.Permissions.PermissionsHandler;
namespace NadekoBot.Modules {
class PermissionModule : DiscordModule
{
string trigger = "*";
string prefix = "*";
public PermissionModule() : base()
{
//Empty for now
@ -21,11 +21,65 @@ namespace NadekoBot.Modules {
commands.ForEach(cmd => cmd.Init(cgb));
cgb.CreateCommand(trigger + "ssm").Alias(trigger + "setservermodule")
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
cgb.CreateCommand(prefix + "serverperms")
.Description("Shows banned permissions for this server.")
.Do(async e => {
var perms = PermsHandler.GetServerPermissions(e.Server);
if (perms == null)
await e.Send("No permissions set.");
await e.Send(perms.ToString());
});
cgb.CreateCommand(prefix + "roleperms")
.Description("Shows banned permissions for a certain role. No argument means for everyone.")
.Parameter("role", ParameterType.Unparsed)
.Do(async e => {
var arg = e.GetArg("role");
var role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role"));
var perms = PermsHandler.GetRolePermissionsById(e.Server, role.Id);
if (perms == null)
await e.Send("No permissions set.");
await e.Send(perms.ToString());
});
cgb.CreateCommand(prefix + "channelperms")
.Description("Shows banned permissions for a certain channel. No argument means for this channel.")
.Parameter("channel", ParameterType.Unparsed)
.Do(async e => {
var arg = e.GetArg("channel");
var channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel"));
var perms = PermsHandler.GetChannelPermissionsById(e.Server, channel.Id);
if (perms == null)
await e.Send("No permissions set.");
await e.Send(perms.ToString());
});
cgb.CreateCommand(prefix + "userperms")
.Description("Shows banned permissions for a certain user. No argument means for yourself.")
.Parameter("user", ParameterType.Unparsed)
.Do(async e => {
var arg = e.GetArg("user");
Discord.User user;
if (string.IsNullOrWhiteSpace(e.GetArg("user")))
user = e.User;
else
user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user"));
var perms = PermsHandler.GetUserPermissionsById(e.Server, user.Id);
if (perms == null)
await e.Send("No permissions set.");
await e.Send(perms.ToString());
});
cgb.CreateCommand(prefix + "sm").Alias(prefix + "servermodule")
.Parameter("module", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Description("Sets a module's permission at the server level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -46,11 +100,10 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "ssc").Alias(trigger + "setservercommand")
cgb.CreateCommand(prefix + "sc").Alias(prefix + "servercommand")
.Parameter("command", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Description("Sets a command's permission at the server level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -71,12 +124,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "srm").Alias(trigger + "setrolemodule")
cgb.CreateCommand(prefix + "rm").Alias(prefix + "rolemodule")
.Parameter("module", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("role", ParameterType.Unparsed)
.Description("Sets a module's permission at the role level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -98,12 +150,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "src").Alias(trigger + "setrolecommand")
cgb.CreateCommand(prefix + "rc").Alias(prefix + "rolecommand")
.Parameter("command", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("role",ParameterType.Unparsed)
.Description("Sets a command's permission at the role level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -125,12 +176,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "scm").Alias(trigger + "setchannelmodule")
cgb.CreateCommand(prefix + "cm").Alias(prefix + "channelmodule")
.Parameter("module", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("channel", ParameterType.Unparsed)
.Description("Sets a module's permission at the channel level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -152,12 +202,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "scc").Alias(trigger + "setchannelcommand")
cgb.CreateCommand(prefix + "cc").Alias(prefix + "channelcommand")
.Parameter("command", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("channel", ParameterType.Unparsed)
.Description("Sets a command's permission at the channel level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -179,12 +228,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "sum").Alias(trigger + "setusermodule")
cgb.CreateCommand(prefix + "um").Alias(prefix + "usermodule")
.Parameter("module", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("user", ParameterType.Unparsed)
.Description("Sets a module's permission at the user level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try
@ -206,12 +254,11 @@ namespace NadekoBot.Modules {
}
});
cgb.CreateCommand(trigger + "suc").Alias(trigger + "setusercommand")
cgb.CreateCommand(prefix + "uc").Alias(prefix + "usercommand")
.Parameter("command", ParameterType.Required)
.Parameter("bool", ParameterType.Required)
.Parameter("user", ParameterType.Unparsed)
.Description("Sets a command's permission at the user level.")
// .AddCheck() -> fix this
.Do(async e =>
{
try

View File

@ -21,6 +21,8 @@ namespace NadekoBot.Modules {
manager.CreateCommands("", cgb => {
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
commands.ForEach(cmd => cmd.Init(cgb));
cgb.CreateCommand("~yt")

View File

@ -132,8 +132,12 @@ namespace NadekoBot {
private static async void Client_MessageReceived(object sender, MessageEventArgs e) {
if (e.Server != null || e.User.Id == client.CurrentUser.Id) return;
if (PollCommand.ActivePolls.SelectMany(kvp => kvp.Key.Users.Select(u=>u.Id)).Contains(e.User.Id)) return;
//just ban this trash AutoModerator
if (e.User.Id == 105309315895693312)
// just ban this trash AutoModerator
// and cancer christmass spirit
// and crappy shotaslave
if (e.User.Id == 105309315895693312 ||
e.User.Id == 119174277298782216 ||
e.User.Id == 143515953525817344)
return; // FU
try {
@ -151,6 +155,7 @@ namespace NadekoBot {
await OwnerPrivateChannel.SendMessage(e.User + ": ```\n" + e.Message.Text + "\n```");
if (!repliedRecently) {
repliedRecently = true;
await e.Send("**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nYou can type `-h` or `-help` or `@MyName help` in any of the channels I am in and I will send you a message with my commands.\n Or you can find out what i do here: https://github.com/Kwoth/NadekoBot\nYou can also just send me an invite link to a server and I will join it.\nIf you don't want me on your server, you can simply ban me ;(\nBot Creator's server: https://discord.gg/0ehQwTK2RBhxEi0X");
Timer t = new Timer();
t.Interval = 2000;