From bd03e898c7057957efd6bf8b56d30ffb5dcac3ea Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Tue, 25 Aug 2020 21:58:52 +0200 Subject: [PATCH] Add endpoints for CustomCommands --- ChaosBot/Discord/DiscordConnect.cs | 4 +- ChaosBot/WebServer/App/CustomCommandApi.cs | 81 +++++++++++++++++++ .../WebServer/Models/CustomCommandRequest.cs | 18 +++++ .../WebServer/Services/CheckPermissions.cs | 45 +++++++++++ 4 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 ChaosBot/WebServer/App/CustomCommandApi.cs create mode 100644 ChaosBot/WebServer/Models/CustomCommandRequest.cs create mode 100644 ChaosBot/WebServer/Services/CheckPermissions.cs diff --git a/ChaosBot/Discord/DiscordConnect.cs b/ChaosBot/Discord/DiscordConnect.cs index 03f5bb3..9571d96 100644 --- a/ChaosBot/Discord/DiscordConnect.cs +++ b/ChaosBot/Discord/DiscordConnect.cs @@ -13,7 +13,7 @@ namespace ChaosBot.Discord { public class DiscordConnect { - private static DiscordSocketClient _client; + public static DiscordSocketClient _client = null; private static ILogger _logger = Program.Logger; public static async Task StartUp() @@ -24,7 +24,7 @@ namespace ChaosBot.Discord { // get the client and assign to client // you get the services via GetRequiredService - var client = services.GetRequiredService(); + DiscordSocketClient client = services.GetRequiredService(); _client = client; // setup logging and the ready event diff --git a/ChaosBot/WebServer/App/CustomCommandApi.cs b/ChaosBot/WebServer/App/CustomCommandApi.cs new file mode 100644 index 0000000..97d351b --- /dev/null +++ b/ChaosBot/WebServer/App/CustomCommandApi.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using ChaosBot.Discord; +using ChaosBot.Models; +using ChaosBot.WebServer.Models; +using ChaosBot.WebServer.Services; +using Discord.WebSocket; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace ChaosBot.WebServer.App +{ + [ApiController] + [Route("/api/custom-commands")] + public class CustomCommandApi : Controller + { + [HttpGet] + [Route("{guildId}")] + public async Task GetCustomCommands([FromRoute]ulong guildId) + { + if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + return result; + + await using ChaosbotContext dbContext = new ChaosbotContext(); + + IQueryable customCommandsQuery = dbContext.CustomCommands; + List customCommands = customCommandsQuery + .Where(cc => cc.DiscordGuildId == guildId) + .ToList(); + + return Json(customCommands); + } + + [HttpPost] + [Route("{guildId}")] + public async Task UpsertCustomCommands([FromRoute]ulong guildId, [FromBody]CustomCommandRequest customCommandRequest) + { + if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + return result; + + await using ChaosbotContext dbContext = new ChaosbotContext(); + + CustomCommand customCommand = new CustomCommand + { + DiscordGuildId = guildId, + Command = customCommandRequest.Command, + Type = customCommandRequest.Type, + Content = customCommandRequest.Content + }; + await dbContext.CustomCommands.Upsert(customCommand) + .On(cc => new {cc.DiscordGuildId, cc.Command}).RunAsync(); + await dbContext.SaveChangesAsync(); + + return NoContent(); + } + + [HttpDelete] + [Route("{guildId}")] + public async Task DeleteCustomCommands([FromRoute]ulong guildId, [FromBody]CustomCommandRequest customCommandRequest) + { + if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + return result; + + await using ChaosbotContext dbContext = new ChaosbotContext(); + + CustomCommand customCommand = new CustomCommand + { + DiscordGuildId = guildId, + Command = customCommandRequest.Command, + Type = customCommandRequest.Type, + Content = customCommandRequest.Content + }; + dbContext.CustomCommands.Remove(customCommand); + await dbContext.SaveChangesAsync(); + + return NoContent(); + } + } +} \ No newline at end of file diff --git a/ChaosBot/WebServer/Models/CustomCommandRequest.cs b/ChaosBot/WebServer/Models/CustomCommandRequest.cs new file mode 100644 index 0000000..48ab183 --- /dev/null +++ b/ChaosBot/WebServer/Models/CustomCommandRequest.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using ChaosBot.Models; + +namespace ChaosBot.WebServer.Models +{ + #region Required + public class CustomCommandRequest + { + [Required] + [MaxLength(128)] + public string Command { get; set; } + [Required] + public CustomCommandType Type { get; set; } + [Required] + public string Content { get; set; } + } + #endregion +} \ No newline at end of file diff --git a/ChaosBot/WebServer/Services/CheckPermissions.cs b/ChaosBot/WebServer/Services/CheckPermissions.cs new file mode 100644 index 0000000..83c6c41 --- /dev/null +++ b/ChaosBot/WebServer/Services/CheckPermissions.cs @@ -0,0 +1,45 @@ +using System; +using System.Linq; +using ChaosBot.Discord; +using Discord.WebSocket; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace ChaosBot.WebServer.Services +{ + public static class CheckPermissions + { + private static readonly AccessTokenCache Cache = WebServer.Cache; + + public static bool GetResult(HttpRequest request, ulong guildId, out IActionResult result) + { + result = null; + + if (!request.Cookies.TryGetValue("access_token", out string accessToken)) + result = new UnauthorizedObjectResult("No access_token cookie sent"); + + SocketGuild guild = DiscordConnect._client.GetGuild(guildId); + if (guild == null) + { + result = new NotFoundObjectResult("Bot is not part of that guild"); + } + else + { + if (!Cache.HasKey(accessToken)) + { + result = new NotFoundObjectResult("Could not find your access token in cache, please logout and log back in."); + } + else + { + SocketGuildUser user = guild.GetUser(Convert.ToUInt64(Cache.Get(accessToken))); + if (user == null) + result = new NotFoundObjectResult("Bot could not find you in that guild"); + else if (!user.GuildPermissions.Administrator && !user.GuildPermissions.ManageGuild) + result = new UnauthorizedObjectResult("You have invalid permissions on the guild. Need at least ManageGuild"); + } + } + + return result == null; + } + } +} \ No newline at end of file