From 377154357d3cdb24e308327cbe8fd06e45ad201c Mon Sep 17 00:00:00 2001 From: Sellara <147769367+Sella-GH@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:30:41 +0200 Subject: [PATCH] Add check if user is permitted to use this AzuraCast command --- .../Checks/AzuraCastDiscordPermCheck.cs | 93 +++++++++++++++++++ .../AzuraCastDiscordPermCheckAttribute.cs | 9 ++ AzzyBot-Next/Services/DiscordBotService.cs | 11 +++ .../Utilities/Enums/AzuraCastDiscordPerm.cs | 10 ++ 4 files changed, 123 insertions(+) create mode 100644 AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheck.cs create mode 100644 AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheckAttribute.cs create mode 100644 AzzyBot-Next/Utilities/Enums/AzuraCastDiscordPerm.cs diff --git a/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheck.cs b/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheck.cs new file mode 100644 index 00000000..f46fd2b0 --- /dev/null +++ b/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheck.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using AzzyBot.Database; +using AzzyBot.Database.Entities; +using AzzyBot.Services; +using AzzyBot.Utilities.Encryption; +using DSharpPlus.Commands; +using DSharpPlus.Commands.ContextChecks; +using DSharpPlus.Commands.Processors.SlashCommands; +using DSharpPlus.Entities; + +namespace AzzyBot; + +public class AzuraCastDiscordPermCheck(DbActions dbActions, DiscordBotService discordBotService) : IContextCheck +{ + private readonly DbActions _dbActions = dbActions; + private readonly DiscordBotService _botService = discordBotService; + + public async ValueTask ExecuteCheckAsync(AzuraCastDiscordPermCheckAttribute attribute, CommandContext context) + { + ArgumentNullException.ThrowIfNull(attribute, nameof(attribute)); + ArgumentNullException.ThrowIfNull(context, nameof(context)); + ArgumentNullException.ThrowIfNull(context.Guild, nameof(context.Guild)); + ArgumentNullException.ThrowIfNull(context.Member, nameof(context.Member)); + + if (context is SlashCommandContext ctx) + { + switch (ctx.Interaction.ResponseState) + { + case DiscordInteractionResponseState.Unacknowledged: + await context.DeferResponseAsync(); + return null; + + case DiscordInteractionResponseState.Replied: + return "Already replied"; + } + } + + int stationId = Convert.ToInt32(context.Arguments.Single(o => o.Key.Name is "station_id" && o.Value is not null).Value, CultureInfo.InvariantCulture); + ulong guildId = context.Guild.Id; + GuildsEntity guild = await _dbActions.GetGuildAsync(guildId); + if (guild is null) + return "Guild is null!"; + + AzuraCastEntity? azuraCast = guild.AzuraCast; + if (azuraCast is null) + return "AzuraCast is null!"; + + AzuraCastStationEntity? station = azuraCast.Stations.FirstOrDefault(s => s.StationId == stationId); + if (station is null) + return "Station is null!"; + + string userId = context.User.Id.ToString(CultureInfo.InvariantCulture); + IEnumerable userRoles = context.Member.Roles; + switch (attribute.Perm) + { + case AzuraCastDiscordPerm.InstanceOwner: + if (userId == Crypto.Decrypt(azuraCast.InstanceOwner)) + return null; + + break; + + case AzuraCastDiscordPerm.InstanceAdminGroup: + if (userRoles.Contains(_botService.GetDiscordRole(guild.UniqueId, azuraCast.InstanceAdminGroup))) + return null; + + break; + + case AzuraCastDiscordPerm.StationOwner: + if (userId == Crypto.Decrypt(station.StationOwner)) + return null; + + break; + + case AzuraCastDiscordPerm.StationAdminGroup: + if (userRoles.Contains(_botService.GetDiscordRole(guild.UniqueId, station.StationAdminGroup))) + return null; + + break; + + case AzuraCastDiscordPerm.StationDJGroup: + if (userRoles.Contains(_botService.GetDiscordRole(guild.UniqueId, station.StationDjGroup))) + return null; + + break; + } + + return "No permission"; + } +} diff --git a/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheckAttribute.cs b/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheckAttribute.cs new file mode 100644 index 00000000..bd6535b4 --- /dev/null +++ b/AzzyBot-Next/Commands/Checks/AzuraCastDiscordPermCheckAttribute.cs @@ -0,0 +1,9 @@ +using System; +using DSharpPlus.Commands.ContextChecks; + +namespace AzzyBot; + +public class AzuraCastDiscordPermCheckAttribute : ContextCheckAttribute +{ + public AzuraCastDiscordPerm Perm { get; set; } +} diff --git a/AzzyBot-Next/Services/DiscordBotService.cs b/AzzyBot-Next/Services/DiscordBotService.cs index b982dd6c..df5f6de7 100644 --- a/AzzyBot-Next/Services/DiscordBotService.cs +++ b/AzzyBot-Next/Services/DiscordBotService.cs @@ -81,6 +81,17 @@ public IReadOnlyDictionary GetDiscordGuilds return member; } + public DiscordRole? GetDiscordRole(ulong guildId, ulong roleId) + { + DiscordGuild? guild = GetDiscordGuild(guildId); + DiscordRole? role = null; + + if (guild is not null) + role = guild.GetRole(roleId); + + return role; + } + public async Task LogExceptionAsync(Exception ex, DateTime timestamp, ulong guildId = 0, string? info = null) { ArgumentNullException.ThrowIfNull(ex, nameof(ex)); diff --git a/AzzyBot-Next/Utilities/Enums/AzuraCastDiscordPerm.cs b/AzzyBot-Next/Utilities/Enums/AzuraCastDiscordPerm.cs new file mode 100644 index 00000000..e1499b8c --- /dev/null +++ b/AzzyBot-Next/Utilities/Enums/AzuraCastDiscordPerm.cs @@ -0,0 +1,10 @@ +namespace AzzyBot; + +public enum AzuraCastDiscordPerm +{ + InstanceOwner, + InstanceAdminGroup, + StationOwner, + StationAdminGroup, + StationDJGroup +}