diff --git a/ChaosBot/WebServer/App/CustomCommandApi.cs b/ChaosBot/WebServer/App/CustomCommandApi.cs index 86d5e7d..7009411 100644 --- a/ChaosBot/WebServer/App/CustomCommandApi.cs +++ b/ChaosBot/WebServer/App/CustomCommandApi.cs @@ -16,11 +16,20 @@ namespace ChaosBot.WebServer.App [Route("/api/custom-commands")] public class CustomCommandApi : Controller { + private readonly AccessTokenCache _accessTokenCache; + + public CustomCommandApi( + AccessTokenCache accessTokenCache + ) + { + _accessTokenCache = accessTokenCache; + } + [HttpGet] [Route("{guildId}")] public async Task GetCustomCommands([FromRoute]ulong guildId) { - if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result)) return result; await using ChaosbotContext dbContext = new ChaosbotContext(); @@ -39,7 +48,7 @@ namespace ChaosBot.WebServer.App [Route("{guildId}")] public async Task UpsertCustomCommands([FromRoute]ulong guildId, [FromBody]CustomCommandRequest customCommandRequest) { - if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result)) return result; await using ChaosbotContext dbContext = new ChaosbotContext(); @@ -62,7 +71,7 @@ namespace ChaosBot.WebServer.App [Route("{guildId}/{command}")] public async Task DeleteCustomCommands([FromRoute]ulong guildId, [FromRoute]string command) { - if (!CheckPermissions.GetResult(Request, guildId, out IActionResult result)) + if (!CheckPermissions.GetResult(_accessTokenCache, Request, guildId, out IActionResult result)) return result; await using ChaosbotContext dbContext = new ChaosbotContext(); diff --git a/ChaosBot/WebServer/App/DiscordController.cs b/ChaosBot/WebServer/App/DiscordController.cs index 0e298e0..48e6247 100644 --- a/ChaosBot/WebServer/App/DiscordController.cs +++ b/ChaosBot/WebServer/App/DiscordController.cs @@ -6,6 +6,7 @@ using System.Net.Http.Headers; using System.Threading.Tasks; using ChaosBot.Discord; using ChaosBot.Repositories; +using ChaosBot.WebServer.Services; using Discord; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; @@ -17,8 +18,20 @@ namespace ChaosBot.WebServer.App [Route("/api/discord")] public class DiscordController : Controller { - private static readonly AccessTokenCache Cache = WebServer.Cache; - private static readonly HttpClient client = new HttpClient(); + private readonly AccessTokenCache _accessTokenCache; + private static HttpClient _httpClient; + private readonly DiscordInviteGenerator _inviteGenerator; + + public DiscordController( + AccessTokenCache accessTokenCache, + DiscordInviteGenerator inviteGenerator, + HttpClient httpClient + ) + { + _accessTokenCache = accessTokenCache; + _inviteGenerator = inviteGenerator; + _httpClient = httpClient; + } [HttpGet] public async Task Index(string code = null) @@ -41,14 +54,14 @@ namespace ChaosBot.WebServer.App }; FormUrlEncodedContent content = new FormUrlEncodedContent(values); - HttpResponseMessage response = await client.PostAsync("https://discord.com/api/oauth2/token", content); + HttpResponseMessage response = await _httpClient.PostAsync("https://discord.com/api/oauth2/token", content); string responseString = await response.Content.ReadAsStringAsync(); DiscordOauthResponse responseObject = JsonConvert.DeserializeObject(responseString); DiscordUserResponse userResponse = GetDiscordUser(responseObject.access_token); - if (Cache.HasKey(responseObject.access_token)) - Cache.Remove(responseObject.access_token); - Cache.Add(responseObject.access_token, userResponse.id, DateTime.Now.AddSeconds(responseObject.expires_in)); + if (_accessTokenCache.HasKey(responseObject.access_token)) + _accessTokenCache.Remove(responseObject.access_token); + _accessTokenCache.Add(responseObject.access_token, userResponse.id, DateTime.Now.AddSeconds(responseObject.expires_in)); return LocalRedirect($"/#/?access_token={responseObject.access_token}"); } @@ -56,20 +69,7 @@ namespace ChaosBot.WebServer.App [HttpGet("invite")] public IActionResult Invite() { - string clientId = Program.AppSettingsHandler.GetValue("Discord:ClientId"); - const ulong permissions = - 0x00000020 + // MANAGE_CHANNELS - 0x04000000 + // CHANGE_NICKNAME - 0x00010000 + // READ_MESSAGE_HISTORY - 0x00000800 + // SEND_MESSAGES - 0x00002000 + // MANAGE_MESSAGES - 0x00008000 + // ATTACH_FILES - 0x00040000 + // USE_EXTERNAL_EMOJIS - 0x00000040 + // ADD_REACTIONS - 0x00000400 // VIEW_CHANNEL - ; - - return Redirect($"https://discord.com/oauth2/authorize?client_id={clientId}&scope=bot&permissions={permissions}"); + return Redirect(_inviteGenerator.Generate()); } [HttpGet("user")] @@ -95,7 +95,7 @@ namespace ChaosBot.WebServer.App { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - response = client.SendAsync(requestMessage).GetAwaiter().GetResult(); + response = _httpClient.SendAsync(requestMessage).GetAwaiter().GetResult(); } string responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); List userResponse = JsonConvert.DeserializeObject>(responseString); @@ -117,7 +117,7 @@ namespace ChaosBot.WebServer.App { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - response = client.SendAsync(requestMessage).GetAwaiter().GetResult(); + response = _httpClient.SendAsync(requestMessage).GetAwaiter().GetResult(); } string responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); diff --git a/ChaosBot/WebServer/Services/CheckPermissions.cs b/ChaosBot/WebServer/Services/CheckPermissions.cs index 83c6c41..b1ddcc0 100644 --- a/ChaosBot/WebServer/Services/CheckPermissions.cs +++ b/ChaosBot/WebServer/Services/CheckPermissions.cs @@ -9,9 +9,7 @@ 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) + public static bool GetResult(AccessTokenCache accessTokenCache, HttpRequest request, ulong guildId, out IActionResult result) { result = null; @@ -25,13 +23,13 @@ namespace ChaosBot.WebServer.Services } else { - if (!Cache.HasKey(accessToken)) + if (!accessTokenCache.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))); + SocketGuildUser user = guild.GetUser(Convert.ToUInt64(accessTokenCache.Get(accessToken))); if (user == null) result = new NotFoundObjectResult("Bot could not find you in that guild"); else if (!user.GuildPermissions.Administrator && !user.GuildPermissions.ManageGuild) @@ -42,4 +40,4 @@ namespace ChaosBot.WebServer.Services return result == null; } } -} \ No newline at end of file +} diff --git a/ChaosBot/WebServer/Services/DiscordInviteGenerator.cs b/ChaosBot/WebServer/Services/DiscordInviteGenerator.cs new file mode 100644 index 0000000..088c616 --- /dev/null +++ b/ChaosBot/WebServer/Services/DiscordInviteGenerator.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Configuration; + +namespace ChaosBot.WebServer.Services +{ + public class DiscordInviteGenerator + { + public string Generate() + { + string clientId = Program.AppSettingsHandler.GetValue("Discord:ClientId"); + const ulong permissions = + 0x00000020 + // MANAGE_CHANNELS + 0x04000000 + // CHANGE_NICKNAME + 0x00010000 + // READ_MESSAGE_HISTORY + 0x00000800 + // SEND_MESSAGES + 0x00002000 + // MANAGE_MESSAGES + 0x00008000 + // ATTACH_FILES + 0x00040000 + // USE_EXTERNAL_EMOJIS + 0x00000040 + // ADD_REACTIONS + 0x00000400 // VIEW_CHANNEL + ; + + return $"https://discord.com/oauth2/authorize?client_id={clientId}&scope=bot&permissions={permissions}"; + } + } +} diff --git a/ChaosBot/WebServer/Startup.cs b/ChaosBot/WebServer/Startup.cs index 5ebac57..42ac686 100644 --- a/ChaosBot/WebServer/Startup.cs +++ b/ChaosBot/WebServer/Startup.cs @@ -1,3 +1,5 @@ +using System.Net.Http; +using ChaosBot.WebServer.Services; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -28,7 +30,10 @@ namespace ChaosBot.WebServer }); services - .AddSingleton(sp => new AccessTokenCache()); + .AddSingleton(sp => new AccessTokenCache()) + .AddSingleton(sp => new DiscordInviteGenerator()) + .AddSingleton(sp => new HttpClient()) + ; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline diff --git a/ChaosBot/WebServer/WebServer.cs b/ChaosBot/WebServer/WebServer.cs index 276152d..2d7d8dd 100644 --- a/ChaosBot/WebServer/WebServer.cs +++ b/ChaosBot/WebServer/WebServer.cs @@ -11,8 +11,6 @@ namespace ChaosBot.WebServer { public static class WebServer { - public static readonly AccessTokenCache Cache = new AccessTokenCache(); - public static void Start(string[] args) { CreateHostBuilder(args).Build().Run(); @@ -44,4 +42,4 @@ namespace ChaosBot.WebServer .UseStartup(); }); } -} \ No newline at end of file +}