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;
return false;
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);