DeukBot4/DeukBot4/MessageHandlers/Permissions/PermissionValidator.cs

111 lines
3.7 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DeukBot4.Database;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using Discord;
using Discord.WebSocket;
namespace DeukBot4.MessageHandlers.Permissions
{
public static class PermissionValidator
{
private static readonly ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, PermissionLevel>> PermissionCache =
new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, PermissionLevel>>();
private static async Task<PermissionLevel> GetDatabasePermissionLevelForRole(ulong serverId, ulong roleId)
{
if (PermissionCache.TryGetValue(serverId, out var serverPermissions))
{
if (serverPermissions.TryGetValue(roleId, out var permissions))
{
return permissions;
}
}
else
{
PermissionCache.TryAdd(serverId, new ConcurrentDictionary<ulong, PermissionLevel>());
}
serverPermissions = PermissionCache[serverId];
try
{
var permission = await DatabaseRolePermissions.GetRolePermission(serverId, roleId);
serverPermissions.TryAdd(serverId, permission);
return permission;
}
catch(Exception e)
{
await Logger.LogError(e.ToString());
return PermissionLevel.Everyone;
}
}
public static void UpdateCache(ulong serverId, ulong roleId, PermissionLevel level)
{
if (PermissionCache.TryGetValue(serverId, out var serverPermissions))
{
if (serverPermissions.ContainsKey(roleId))
{
serverPermissions[roleId] = level;
}
else
{
serverPermissions.TryAdd(roleId, level);
}
}
}
private static async Task<PermissionLevel> GetDatabasePermissionLevel(ulong serverId, ulong[] roles)
{
var highestRole = (PermissionLevel)sbyte.MinValue;
foreach (var role in roles)
{
var perms = await GetDatabasePermissionLevelForRole(serverId, role);
if (perms > highestRole)
{
highestRole = perms;
}
}
if (highestRole == (PermissionLevel) sbyte.MinValue)
{
return PermissionLevel.Everyone;
}
return highestRole;
}
public static async Task<PermissionLevel> GetUserPermissionLevel(SocketMessage message)
{
return await GetUserPermissionLevel(message.Channel, message.Author);
}
public static async Task<PermissionLevel> GetUserPermissionLevel(ISocketMessageChannel channel, SocketUser user)
{
if (user.Id == Program.Settings.OwnerId)
{
return PermissionLevel.BotCreator;
}
if (user.IsBot)
{
return PermissionLevel.Bot;
}
if (!(channel is IGuildChannel serverChannel))
return PermissionLevel.Everyone;
if (serverChannel.Guild.OwnerId == user.Id)
return PermissionLevel.ServerOwner;
if (!(user is IGuildUser guildUser))
return PermissionLevel.Everyone;
var perms = await GetDatabasePermissionLevel(serverChannel.GuildId, guildUser.RoleIds.ToArray());
return perms;
}
}
}