diff --git a/NadekoBot/Classes/PermissionHelper.cs b/NadekoBot/Classes/PermissionHelper.cs deleted file mode 100644 index 45afc075..00000000 --- a/NadekoBot/Classes/PermissionHelper.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Discord.Commands; -using Discord.Modules; -using NadekoBot.Extensions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - - -namespace NadekoBot.Classes -{ - static class PermissionHelper - { - public static bool ValidateBool(string passedArg) - { - if (string.IsNullOrEmpty(passedArg.Trim())) - { - throw new System.ArgumentException("No value supplied! Missing argument"); - } - switch (passedArg.ToLower()) - { - case "t": - case "true": - case "enable": - return true; - case "f": - case "false": - case "disable": - return false; - default: - throw new System.ArgumentException("Did not receive a valid boolean value"); - } - } - - internal static bool ValidateModule(string mod) - { - if (string.IsNullOrWhiteSpace(mod)) - throw new ArgumentNullException(nameof(mod)); - foreach (var m in NadekoBot.client.Modules().Modules) { - if(m.Name.ToLower().Equals(mod)) - return true; - } - return false; - } - - internal static bool ValidateCommand(string commandText) - { - if (string.IsNullOrWhiteSpace(commandText)) - throw new ArgumentNullException(nameof(commandText)); - foreach (var com in NadekoBot.client.Commands().AllCommands) { - if (com.Text == commandText) - return true; - } - return false; - } - } -} diff --git a/NadekoBot/Classes/PermissionCheckers/PermissionChecker.cs b/NadekoBot/Classes/Permissions/PermissionChecker.cs similarity index 100% rename from NadekoBot/Classes/PermissionCheckers/PermissionChecker.cs rename to NadekoBot/Classes/Permissions/PermissionChecker.cs diff --git a/NadekoBot/Classes/Permissions/PermissionHelper.cs b/NadekoBot/Classes/Permissions/PermissionHelper.cs new file mode 100644 index 00000000..c596d89f --- /dev/null +++ b/NadekoBot/Classes/Permissions/PermissionHelper.cs @@ -0,0 +1,86 @@ +using Discord.Commands; +using Discord.Modules; +using NadekoBot.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Discord; + +namespace NadekoBot.Classes { + static class PermissionHelper { + public static bool ValidateBool(string passedArg) { + if (string.IsNullOrWhiteSpace(passedArg)) { + throw new ArgumentException("No value supplied! Missing argument"); + } + switch (passedArg.ToLower()) { + case "1": + case "t": + case "true": + case "enable": + case "allow": + case "unban": + return true; + case "0": + case "f": + case "false": + case "disable": + case "disallow": + case "ban": + return false; + default: + throw new ArgumentException("Did not receive a valid boolean value"); + } + } + + internal static string ValidateModule(string mod) { + if (string.IsNullOrWhiteSpace(mod)) + throw new ArgumentNullException(nameof(mod)); + + foreach (var m in NadekoBot.client.Modules().Modules) { + if (m.Name.ToLower().Equals(mod.ToLower())) + return m.Name; + } + throw new ArgumentException("That module does not exist."); + } + + internal static string ValidateCommand(string commandText) { + if (string.IsNullOrWhiteSpace(commandText)) + throw new ArgumentNullException(nameof(commandText)); + + foreach (var com in NadekoBot.client.Commands().AllCommands) { + if (com.Text.ToLower().Equals(commandText.ToLower())) + return com.Text; + } + throw new NullReferenceException("That command does not exist."); + } + + internal static Role ValidateRole(Server server, string roleName) { + if (string.IsNullOrWhiteSpace(roleName)) + throw new ArgumentNullException(nameof(roleName)); + var role = server.FindRoles(roleName).FirstOrDefault(); + if (role == null) + throw new NullReferenceException("That role does not exist."); + return role; + } + + internal static Channel ValidateChannel(Server server, string channelName) { + if (string.IsNullOrWhiteSpace(channelName)) + throw new ArgumentNullException(nameof(channelName)); + var channel = server.FindChannels(channelName).FirstOrDefault(); + if (channel == null) + throw new NullReferenceException("That channel does not exist."); + return channel; + } + + internal static User ValidateUser(Server server, string userName) { + if (string.IsNullOrWhiteSpace(userName)) + throw new ArgumentNullException(nameof(userName)); + var user = server.FindUsers(userName).FirstOrDefault(); + if (user == null) + throw new NullReferenceException("That user does not exist."); + return user; + } + } +} diff --git a/NadekoBot/Classes/PermissionCheckers/PermissionsHandler.cs b/NadekoBot/Classes/Permissions/PermissionsHandler.cs similarity index 75% rename from NadekoBot/Classes/PermissionCheckers/PermissionsHandler.cs rename to NadekoBot/Classes/Permissions/PermissionsHandler.cs index 2f9b074f..92fc0a00 100644 --- a/NadekoBot/Classes/PermissionCheckers/PermissionsHandler.cs +++ b/NadekoBot/Classes/Permissions/PermissionsHandler.cs @@ -14,6 +14,26 @@ namespace NadekoBot.Classes.Permissions { public static ConcurrentDictionary _permissionsDict = new ConcurrentDictionary(); + 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 id = ulong.Parse(strippedFileName); + var server = NadekoBot.client.GetServer(id); + if (server == null) + throw new ArgumentException("Server does not exist"); + + var data = Newtonsoft.Json.JsonConvert.DeserializeObject(File.ReadAllText(file)); + _permissionsDict.TryAdd(server, data); + } catch (Exception ex){ + Console.WriteLine($"Failed getting server with id: {file}\nReason: {ex.Message}"); + } + } + Console.WriteLine("Permission initialization complete."); + } + 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)); @@ -28,7 +48,7 @@ namespace NadekoBot.Classes.Permissions { public static void SetServerModulePermission(Server server, string moduleName, bool value) { if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } var modules = _permissionsDict[server].Permissions.modules; if (modules.ContainsKey(moduleName)) @@ -40,7 +60,7 @@ namespace NadekoBot.Classes.Permissions { public static void SetServerCommandPermission(Server server, string commandName, bool value) { if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } var commands = _permissionsDict[server].Permissions.commands; if (commands.ContainsKey(commandName)) @@ -53,12 +73,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetChannelModulePermission(Channel channel, string moduleName, bool value) { var server = channel.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if(!_permissionsDict[server].ChannelPermissions.ContainsKey(channel.Id.ToString())) - _permissionsDict[server].ChannelPermissions.Add(channel.Id.ToString(), new Permissions(channel.Name)); + if(!_permissionsDict[server].ChannelPermissions.ContainsKey(channel.Id)) + _permissionsDict[server].ChannelPermissions.Add(channel.Id, new Permissions(channel.Name)); - var modules = _permissionsDict[server].ChannelPermissions[channel.Id.ToString()].modules; + var modules = _permissionsDict[server].ChannelPermissions[channel.Id].modules; if (modules.ContainsKey(moduleName)) modules[moduleName] = value; @@ -70,12 +90,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetChannelCommandPermission(Channel channel, string commandName, bool value) { var server = channel.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if (!_permissionsDict[server].ChannelPermissions.ContainsKey(channel.Id.ToString())) - _permissionsDict[server].ChannelPermissions.Add(channel.Id.ToString(), new Permissions(channel.Name)); + if (!_permissionsDict[server].ChannelPermissions.ContainsKey(channel.Id)) + _permissionsDict[server].ChannelPermissions.Add(channel.Id, new Permissions(channel.Name)); - var commands = _permissionsDict[server].ChannelPermissions[channel.Id.ToString()].commands; + var commands = _permissionsDict[server].ChannelPermissions[channel.Id].commands; if (commands.ContainsKey(commandName)) commands[commandName] = value; @@ -87,12 +107,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetRoleModulePermission(Role role, string moduleName, bool value) { var server = role.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if (!_permissionsDict[server].RolePermissions.ContainsKey(role.Id.ToString())) - _permissionsDict[server].RolePermissions.Add(role.Id.ToString(), new Permissions(role.Name)); + if (!_permissionsDict[server].RolePermissions.ContainsKey(role.Id)) + _permissionsDict[server].RolePermissions.Add(role.Id, new Permissions(role.Name)); - var modules = _permissionsDict[server].RolePermissions[role.Id.ToString()].modules; + var modules = _permissionsDict[server].RolePermissions[role.Id].modules; if (modules.ContainsKey(moduleName)) modules[moduleName] = value; @@ -104,12 +124,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetRoleCommandPermission(Role role, string commandName, bool value) { var server = role.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if (!_permissionsDict[server].RolePermissions.ContainsKey(role.Id.ToString())) - _permissionsDict[server].RolePermissions.Add(role.Id.ToString(), new Permissions(role.Name)); + if (!_permissionsDict[server].RolePermissions.ContainsKey(role.Id)) + _permissionsDict[server].RolePermissions.Add(role.Id, new Permissions(role.Name)); - var commands = _permissionsDict[server].RolePermissions[role.Id.ToString()].commands; + var commands = _permissionsDict[server].RolePermissions[role.Id].commands; if (commands.ContainsKey(commandName)) commands[commandName] = value; @@ -121,12 +141,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetUserModulePermission(User user, string moduleName, bool value) { var server = user.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if (!_permissionsDict[server].UserPermissions.ContainsKey(user.Id.ToString())) - _permissionsDict[server].UserPermissions.Add(user.Id.ToString(), new Permissions(user.Name)); + if (!_permissionsDict[server].UserPermissions.ContainsKey(user.Id)) + _permissionsDict[server].UserPermissions.Add(user.Id, new Permissions(user.Name)); - var modules = _permissionsDict[server].UserPermissions[user.Id.ToString()].modules; + var modules = _permissionsDict[server].UserPermissions[user.Id].modules; if (modules.ContainsKey(moduleName)) modules[moduleName] = value; @@ -138,12 +158,12 @@ namespace NadekoBot.Classes.Permissions { public static void SetUserCommandPermission(User user, string commandName, bool value) { var server = user.Server; if (!_permissionsDict.ContainsKey(server)) { - _permissionsDict.TryAdd(server, new ServerPermissions(server.Id.ToString(), server.Name)); + _permissionsDict.TryAdd(server, new ServerPermissions(server.Id, server.Name)); } - if (!_permissionsDict[server].UserPermissions.ContainsKey(user.Id.ToString())) - _permissionsDict[server].UserPermissions.Add(user.Id.ToString(), new Permissions(user.Name)); + if (!_permissionsDict[server].UserPermissions.ContainsKey(user.Id)) + _permissionsDict[server].UserPermissions.Add(user.Id, new Permissions(user.Name)); - var commands = _permissionsDict[server].UserPermissions[user.Id.ToString()].commands; + var commands = _permissionsDict[server].UserPermissions[user.Id].commands; if (commands.ContainsKey(commandName)) commands[commandName] = value; @@ -159,7 +179,7 @@ namespace NadekoBot.Classes.Permissions { /// /// Name of the parent object whose permissions these are /// - public string ParentName { get; set; } + public string Name { get; set; } /// /// Module name with allowed/disallowed /// @@ -170,7 +190,7 @@ namespace NadekoBot.Classes.Permissions { public Dictionary commands { get; set; } public Permissions(string name) { - ParentName = name; + Name = name; modules = new Dictionary(); commands = new Dictionary(); } @@ -188,25 +208,25 @@ namespace NadekoBot.Classes.Permissions { /// /// The id of the thing (user/server/channel) /// - public string Id { get; set; } //a string because of the role name. + public ulong Id { get; set; } //a string because of the role name. /// /// Permission object bound to the id of something/role name /// public Permissions Permissions { get; set; } - public Dictionary UserPermissions { get; set; } - public Dictionary ChannelPermissions { get; set; } - public Dictionary RolePermissions { get; set; } + public Dictionary UserPermissions { get; set; } + public Dictionary ChannelPermissions { get; set; } + public Dictionary RolePermissions { get; set; } - public ServerPermissions(string id, string name) { + public ServerPermissions(ulong id, string name) { Id = id; PermissionsControllerRoleName = "PermissionsKing"; Verbose = true; Permissions = new Permissions(name); - UserPermissions = new Dictionary(); - ChannelPermissions = new Dictionary(); - RolePermissions = new Dictionary(); + UserPermissions = new Dictionary(); + ChannelPermissions = new Dictionary(); + RolePermissions = new Dictionary(); } } } \ No newline at end of file diff --git a/NadekoBot/Modules/Permissions.cs b/NadekoBot/Modules/Permissions.cs index 3fffd4ae..8c2478e6 100644 --- a/NadekoBot/Modules/Permissions.cs +++ b/NadekoBot/Modules/Permissions.cs @@ -3,6 +3,7 @@ using Discord.Modules; using Discord.Commands; using NadekoBot.Extensions; using NadekoBot.Classes; +using PermsHandler = NadekoBot.Classes.Permissions.PermissionsHandler; namespace NadekoBot.Modules { class PermissionModule : DiscordModule @@ -29,9 +30,10 @@ namespace NadekoBot.Modules { { try { - PermissionHelper.ValidateModule(e.GetArg("module")); + string module = PermissionHelper.ValidateModule(e.GetArg("module")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + PermsHandler.SetServerModulePermission(e.Server, module, state); await e.Send("I'm setting " + e.GetArg("module") + " to " + state); } catch (ArgumentException exArg) @@ -53,9 +55,10 @@ namespace NadekoBot.Modules { { try { - PermissionHelper.ValidateCommand(e.GetArg("command")); + string command = PermissionHelper.ValidateCommand(e.GetArg("command")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + PermsHandler.SetServerCommandPermission(e.Server, command, state); await e.Send("I'm setting " + e.GetArg("command") + " to " + state); } catch (ArgumentException exArg) @@ -71,15 +74,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "srm").Alias(trigger + "setrolemodule") .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 { - PermissionHelper.ValidateModule(e.GetArg("module")); + string module = PermissionHelper.ValidateModule(e.GetArg("module")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.Role role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role")); + PermsHandler.SetRoleModulePermission(role, module, state); await e.Send("I'm setting " + e.GetArg("module") + " to " + state); } catch (ArgumentException exArg) @@ -95,15 +101,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "src").Alias(trigger + "setrolecommand") .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 { - PermissionHelper.ValidateCommand(e.GetArg("command")); + string command = PermissionHelper.ValidateCommand(e.GetArg("command")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.Role role = PermissionHelper.ValidateRole(e.Server, e.GetArg("role")); + PermsHandler.SetRoleCommandPermission(role, command, state); await e.Send("I'm setting " + e.GetArg("command") + " to " + state); } catch (ArgumentException exArg) @@ -119,15 +128,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "scm").Alias(trigger + "setchannelmodule") .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 { - PermissionHelper.ValidateModule(e.GetArg("module")); + string module = PermissionHelper.ValidateModule(e.GetArg("module")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.Channel channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel")); + PermsHandler.SetChannelModulePermission(channel, module, state); await e.Send("I'm setting " + e.GetArg("module") + " to " + state); } catch (ArgumentException exArg) @@ -143,15 +155,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "scc").Alias(trigger + "setchannelcommand") .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 { - PermissionHelper.ValidateCommand(e.GetArg("command")); + string command = PermissionHelper.ValidateCommand(e.GetArg("command")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.Channel channel = PermissionHelper.ValidateChannel(e.Server, e.GetArg("channel")); + PermsHandler.SetChannelCommandPermission(channel, command, state); await e.Send("I'm setting " + e.GetArg("command") + " to " + state); } catch (ArgumentException exArg) @@ -167,15 +182,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "sum").Alias(trigger + "setusermodule") .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 { - PermissionHelper.ValidateModule(e.GetArg("module")); + string module = PermissionHelper.ValidateModule(e.GetArg("module")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.User user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user")); + PermsHandler.SetUserModulePermission(user, module, state); await e.Send("I'm setting " + e.GetArg("module") + " to " + state); } catch (ArgumentException exArg) @@ -191,15 +209,18 @@ namespace NadekoBot.Modules { cgb.CreateCommand(trigger + "suc").Alias(trigger + "setusercommand") .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 { - PermissionHelper.ValidateModule(e.GetArg("command")); + string command = PermissionHelper.ValidateCommand(e.GetArg("command")); bool state = PermissionHelper.ValidateBool(e.GetArg("bool")); + Discord.User user = PermissionHelper.ValidateUser(e.Server, e.GetArg("user")); + PermsHandler.SetUserCommandPermission(user, command, state); await e.Send("I'm setting " + e.GetArg("command") + " to " + state); } catch (ArgumentException exArg) diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index 014b73a1..c2d4a97e 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -16,7 +16,7 @@ namespace NadekoBot { public static string botMention; public static string GoogleAPIKey = null; public static ulong OwnerID; - public static User OwnerUser = null; + public static Channel OwnerPrivateChannel = null; public static string password; public static string TrelloAppKey; public static bool ForwardMessages = false; @@ -107,11 +107,14 @@ namespace NadekoBot { Console.WriteLine(NadekoStats.Instance.GetStats()); Console.WriteLine("-----------------"); - foreach (var serv in client.Servers) { - if ((OwnerUser = serv.GetUser(OwnerID)) != null) - return; + try { + OwnerPrivateChannel = await client.CreatePrivateChannel(OwnerID); + } catch (Exception) { + Console.WriteLine("Failed creating private channel with the owner"); } + Classes.Permissions.PermissionsHandler.Initialize(); + client.ClientAPI.SendingRequest += (s, e) => { var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; @@ -144,8 +147,8 @@ namespace NadekoBot { } } - if (ForwardMessages && OwnerUser != null) - await OwnerUser.SendMessage(e.User + ": ```\n" + e.Message.Text + "\n```"); + if (ForwardMessages && OwnerPrivateChannel != null) + await OwnerPrivateChannel.SendMessage(e.User + ": ```\n" + e.Message.Text + "\n```"); if (!repliedRecently) { 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"); diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj index f66dfdcd..3b55ed5f 100644 --- a/NadekoBot/NadekoBot.csproj +++ b/NadekoBot/NadekoBot.csproj @@ -132,9 +132,9 @@ - - - + + + diff --git a/NadekoBot/bin/Debug/data/nadekobot.sqlite b/NadekoBot/bin/Debug/data/nadekobot.sqlite new file mode 100644 index 00000000..0910c5e1 Binary files /dev/null and b/NadekoBot/bin/Debug/data/nadekobot.sqlite differ