forked from EllieBotDevs/elliebot
184 lines
No EOL
5.7 KiB
C#
184 lines
No EOL
5.7 KiB
C#
#nullable disable
|
|
using Microsoft.EntityFrameworkCore;
|
|
using EllieBot.Common.ModuleBehaviors;
|
|
using EllieBot.Modules.Permissions.Common;
|
|
using EllieBot.Db.Models;
|
|
|
|
namespace EllieBot.Modules.Permissions.Services;
|
|
|
|
public class PermissionService : IExecPreCommand, IEService
|
|
{
|
|
public int Priority { get; } = 0;
|
|
|
|
//guildid, root permission
|
|
public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } = new();
|
|
|
|
private readonly DbService _db;
|
|
private readonly CommandHandler _cmd;
|
|
private readonly IBotStrings _strings;
|
|
private readonly IMessageSenderService _sender;
|
|
|
|
public PermissionService(
|
|
DiscordSocketClient client,
|
|
DbService db,
|
|
CommandHandler cmd,
|
|
IBotStrings strings,
|
|
IMessageSenderService sender)
|
|
{
|
|
_db = db;
|
|
_cmd = cmd;
|
|
_strings = strings;
|
|
_sender = sender;
|
|
|
|
using var uow = _db.GetDbContext();
|
|
foreach (var x in uow.Set<GuildConfig>().PermissionsForAll(client.Guilds.ToArray().Select(x => x.Id).ToList()))
|
|
{
|
|
Cache.TryAdd(x.GuildId,
|
|
new()
|
|
{
|
|
Verbose = x.VerbosePermissions,
|
|
PermRole = x.PermissionRole,
|
|
Permissions = new(x.Permissions)
|
|
});
|
|
}
|
|
}
|
|
|
|
public PermissionCache GetCacheFor(ulong guildId)
|
|
{
|
|
if (!Cache.TryGetValue(guildId, out var pc))
|
|
{
|
|
using (var uow = _db.GetDbContext())
|
|
{
|
|
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.Permissions));
|
|
UpdateCache(config);
|
|
}
|
|
|
|
Cache.TryGetValue(guildId, out pc);
|
|
if (pc is null)
|
|
throw new("Cache is null.");
|
|
}
|
|
|
|
return pc;
|
|
}
|
|
|
|
public async Task AddPermissions(ulong guildId, params Permissionv2[] perms)
|
|
{
|
|
await using var uow = _db.GetDbContext();
|
|
var config = uow.GcWithPermissionsFor(guildId);
|
|
//var orderedPerms = new PermissionsCollection<Permissionv2>(config.Permissions);
|
|
var max = config.Permissions.Max(x => x.Index); //have to set its index to be the highest
|
|
foreach (var perm in perms)
|
|
{
|
|
perm.Index = ++max;
|
|
config.Permissions.Add(perm);
|
|
}
|
|
|
|
await uow.SaveChangesAsync();
|
|
UpdateCache(config);
|
|
}
|
|
|
|
public void UpdateCache(GuildConfig config)
|
|
=> Cache.AddOrUpdate(config.GuildId,
|
|
new PermissionCache
|
|
{
|
|
Permissions = new(config.Permissions),
|
|
PermRole = config.PermissionRole,
|
|
Verbose = config.VerbosePermissions
|
|
},
|
|
(_, old) =>
|
|
{
|
|
old.Permissions = new(config.Permissions);
|
|
old.PermRole = config.PermissionRole;
|
|
old.Verbose = config.VerbosePermissions;
|
|
return old;
|
|
});
|
|
|
|
public async Task<bool> ExecPreCommandAsync(ICommandContext ctx, string moduleName, CommandInfo command)
|
|
{
|
|
var guild = ctx.Guild;
|
|
var msg = ctx.Message;
|
|
var user = ctx.User;
|
|
var channel = ctx.Channel;
|
|
var commandName = command.Name.ToLowerInvariant();
|
|
|
|
if (guild is null)
|
|
return false;
|
|
|
|
var resetCommand = commandName == "resetperms";
|
|
|
|
var pc = GetCacheFor(guild.Id);
|
|
if (!resetCommand
|
|
&& !pc.Permissions.CheckPermissions(msg.Author, msg.Channel, commandName, moduleName, out var index))
|
|
{
|
|
if (pc.Verbose)
|
|
{
|
|
try
|
|
{
|
|
await _sender.Response(channel)
|
|
.Error(_strings.GetText(strs.perm_prevent(index + 1,
|
|
Format.Bold(pc.Permissions[index]
|
|
.GetCommand(_cmd.GetPrefix(guild), (SocketGuild)guild))),
|
|
guild.Id))
|
|
.SendAsync();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
if (moduleName == nameof(Permissions))
|
|
{
|
|
if (user is not IGuildUser guildUser)
|
|
return true;
|
|
|
|
if (guildUser.GuildPermissions.Administrator)
|
|
return false;
|
|
|
|
var permRole = pc.PermRole;
|
|
if (!ulong.TryParse(permRole, out var rid))
|
|
rid = 0;
|
|
string returnMsg;
|
|
IRole role;
|
|
if (string.IsNullOrWhiteSpace(permRole) || (role = guild.GetRole(rid)) is null)
|
|
{
|
|
returnMsg = "You need Admin permissions in order to use permission commands.";
|
|
if (pc.Verbose)
|
|
{
|
|
try { await _sender.Response(channel).Error(returnMsg).SendAsync(); }
|
|
catch { }
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if (!guildUser.RoleIds.Contains(rid))
|
|
{
|
|
returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
|
|
if (pc.Verbose)
|
|
{
|
|
try { await _sender.Response(channel).Error(returnMsg).SendAsync(); }
|
|
catch { }
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public async Task Reset(ulong guildId)
|
|
{
|
|
await using var uow = _db.GetDbContext();
|
|
var config = uow.GcWithPermissionsFor(guildId);
|
|
config.Permissions = Permissionv2.GetDefaultPermlist;
|
|
await uow.SaveChangesAsync();
|
|
UpdateCache(config);
|
|
}
|
|
} |