From 1db5b7056d673148dc0ee051a1539078028d8553 Mon Sep 17 00:00:00 2001 From: defnotken Date: Wed, 29 Oct 2025 17:23:07 -0500 Subject: [PATCH] Initial Bot Cleanup + Profile Toggling --- .../Controllers/GroupController.cs | 56 +++++ .../Controllers/UserController.cs | 36 ++- .../LightlessSyncServer/Startup.cs | 1 - .../Discord/MareModule.cs | 213 ++++++++++++------ 4 files changed, 238 insertions(+), 68 deletions(-) create mode 100644 LightlessSyncServer/LightlessSyncServer/Controllers/GroupController.cs diff --git a/LightlessSyncServer/LightlessSyncServer/Controllers/GroupController.cs b/LightlessSyncServer/LightlessSyncServer/Controllers/GroupController.cs new file mode 100644 index 0000000..9099aed --- /dev/null +++ b/LightlessSyncServer/LightlessSyncServer/Controllers/GroupController.cs @@ -0,0 +1,56 @@ +using LightlessSync.API.Dto.Group; +using LightlessSync.API.Routes; +using LightlessSyncShared.Data; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LightlessSyncServer.Controllers; + +[Route(LightlessAuth.Group)] +[Authorize(Policy = "Internal")] +public class GroupController : Controller +{ + protected readonly ILogger Logger; + protected readonly IDbContextFactory LightlessDbContextFactory; + + public GroupController(ILogger logger, IDbContextFactory lightlessDbContext) + { + Logger = logger; + LightlessDbContextFactory = lightlessDbContext; + } + + [Route(LightlessAuth.Disable_Profile)] + [HttpPost] + public async Task DisableGroupProfile([FromBody] GroupProfileAvailabilityRequest request) + { + using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync(); + + Logger.LogInformation("Disabling profile for group with GID {GID}", request.GID); + + var group = await dbContext.GroupProfiles.FirstOrDefaultAsync(f => f.GroupGID == request.GID); + if (group != null) + { + group.ProfileDisabled = true; + } + + await dbContext.SaveChangesAsync(); + } + + [Route(LightlessAuth.Enable_Profile)] + [HttpPost] + public async Task EnableGroupProfile([FromBody] GroupProfileAvailabilityRequest request) + { + using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync(); + + Logger.LogInformation("Disabling profile for group with GID {GID}", request.GID); + + var group = await dbContext.GroupProfiles.FirstOrDefaultAsync(f => f.GroupGID == request.GID); + if (group != null) + { + group.ProfileDisabled = false; + } + + await dbContext.SaveChangesAsync(); + } +} \ No newline at end of file diff --git a/LightlessSyncServer/LightlessSyncServer/Controllers/UserController.cs b/LightlessSyncServer/LightlessSyncServer/Controllers/UserController.cs index 0084566..d73adbb 100644 --- a/LightlessSyncServer/LightlessSyncServer/Controllers/UserController.cs +++ b/LightlessSyncServer/LightlessSyncServer/Controllers/UserController.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LightlessSyncAuthService.Controllers; +namespace LightlessSyncServer.Controllers; [Route(LightlessAuth.User)] [Authorize(Policy = "Internal")] @@ -96,4 +96,38 @@ public class UserController : Controller await dbContext.SaveChangesAsync(); } + + [Route(LightlessAuth.Disable_Profile)] + [HttpPost] + public async Task DisableGroupProfile([FromBody] UserProfileAvailabilityRequest request) + { + using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync(); + + Logger.LogInformation("Disabling profile for user with uid {UID}", request.UID); + + var user = await dbContext.UserProfileData.FirstOrDefaultAsync(f => f.UserUID == request.UID); + if (user != null) + { + user.ProfileDisabled = true; + } + + await dbContext.SaveChangesAsync(); + } + + [Route(LightlessAuth.Enable_Profile)] + [HttpPost] + public async Task EnableGroupProfile([FromBody] UserProfileAvailabilityRequest request) + { + using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync(); + + Logger.LogInformation("Enabling profile for user with uid {UID}", request.UID); + + var user = await dbContext.UserProfileData.FirstOrDefaultAsync(f => f.UserUID == request.UID); + if (user != null) + { + user.ProfileDisabled = true; + } + + await dbContext.SaveChangesAsync(); + } } \ No newline at end of file diff --git a/LightlessSyncServer/LightlessSyncServer/Startup.cs b/LightlessSyncServer/LightlessSyncServer/Startup.cs index 3b9ba70..5578334 100644 --- a/LightlessSyncServer/LightlessSyncServer/Startup.cs +++ b/LightlessSyncServer/LightlessSyncServer/Startup.cs @@ -1,6 +1,5 @@ using AspNetCoreRateLimit; using LightlessSync.API.SignalR; -using LightlessSyncAuthService.Controllers; using LightlessSyncServer.Controllers; using LightlessSyncServer.Configuration; using LightlessSyncServer.Hubs; diff --git a/LightlessSyncServer/LightlessSyncServices/Discord/MareModule.cs b/LightlessSyncServer/LightlessSyncServices/Discord/MareModule.cs index 48d1c03..3c974e2 100644 --- a/LightlessSyncServer/LightlessSyncServices/Discord/MareModule.cs +++ b/LightlessSyncServer/LightlessSyncServices/Discord/MareModule.cs @@ -1,15 +1,17 @@ using Discord; using Discord.Interactions; +using LightlessSync.API.Data.Enum; +using LightlessSync.API.Dto.Group; +using LightlessSync.API.Dto.User; using LightlessSyncShared.Data; +using LightlessSyncShared.Models; +using LightlessSyncShared.Services; +using LightlessSyncShared.Utils; +using LightlessSyncShared.Utils.Configuration; using Microsoft.EntityFrameworkCore; using Prometheus; -using LightlessSyncShared.Models; -using LightlessSyncShared.Utils; -using LightlessSyncShared.Services; using StackExchange.Redis; -using LightlessSync.API.Data.Enum; -using LightlessSyncShared.Utils.Configuration; -using LightlessSync.API.Dto.User; +using System.Net.Http.Json; namespace LightlessSyncServices.Discord; @@ -110,10 +112,10 @@ public class LightlessModule : InteractionModuleBase var testUri = new Uri(_lightlessServicesConfiguration.GetValue (nameof(ServicesConfiguration.MainServerAddress)), "/msgc/sendMessage"); - await c.PostAsJsonAsync( + using (await c.PostAsJsonAsync( new Uri(_lightlessServicesConfiguration.GetValue(nameof(ServicesConfiguration.MainServerAddress)), "/msgc/sendMessage"), new ClientMessage(messageType, message, uid ?? string.Empty) - ).ConfigureAwait(false); + ).ConfigureAwait(false)) { } var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); if (uid == null && discordChannelForMessages != null) @@ -146,20 +148,47 @@ public class LightlessModule : InteractionModuleBase } } - [SlashCommand("unbanbydiscord", "ADMIN ONLY: Unban a user by their discord ID")] - public async Task UnbanByDiscord([Summary("discord_id", "Discord ID to unban")] string discordId) + [SlashCommand("serviceunban", "ADMIN ONLY: Unban a user by their discord ID or user ID [CHOOSE ONE ONLY]")] + public async Task ServiceUnban( + [Summary("discord_id", "Discord ID to unban")] string? discordId, + [Summary("uid", "UID to unban")] string? uid + ) { _logger.LogInformation("SlashCommand:{userId}:{Method}:{params}", - Context.Interaction.User.Id, nameof(UnbanByDiscord), - string.Join(",", new[] { $"{nameof(discordId)}:{discordId}" })); + Context.Interaction.User.Id, nameof(ServiceUnban), + string.Join(",", new[] { $"{nameof(discordId)}:{discordId}", $"{nameof(uid)}:{uid}" })); + try { using HttpClient c = new HttpClient(); - + c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token); - await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue - (nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanDiscord"), new UnbanRequest(string.Empty, discordId)) - .ConfigureAwait(false); + + string endpoint; + UnbanRequest unbanRequest; + + if (!string.IsNullOrEmpty(uid)) + { + endpoint = "/user/unbanUID"; + unbanRequest = new UnbanRequest(uid, string.Empty); + } + else if (!string.IsNullOrEmpty(discordId)) + { + endpoint = "/user/unbanDiscord"; + unbanRequest = new UnbanRequest(string.Empty, discordId); + } + else + { + await RespondAsync("You must provide either a UID or Discord ID.", ephemeral: true).ConfigureAwait(false); + return; + } + + using (await c.PostAsJsonAsync( + new Uri(_lightlessServicesConfiguration.GetValue(nameof(ServicesConfiguration.MainServerAddress)), endpoint), + unbanRequest).ConfigureAwait(false)) + { + } + var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); if (discordChannelForMessages != null) { @@ -168,10 +197,12 @@ public class LightlessModule : InteractionModuleBase { var embedColor = Color.Blue; + String idToUse = !string.IsNullOrEmpty(uid) ? uid : discordId; + EmbedBuilder eb = new(); eb.WithTitle("Unban Alert!"); eb.WithColor(embedColor); - eb.WithDescription(discordId + " has been unbanned"); + eb.WithDescription(idToUse + " has been unbanned"); await discordChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); } @@ -188,64 +219,20 @@ public class LightlessModule : InteractionModuleBase } } - [SlashCommand("unbanbyuid", "ADMIN ONLY: Unban a user by their uid")] - public async Task UnbanByUID([Summary("uid", "uid to unban")] string uid) + [SlashCommand("serviceban", "ADMIN ONLY: ban a user by their uid")] + public async Task ServiceBan([Summary("uid", "uid to ban")] string uid) { _logger.LogInformation("SlashCommand:{userId}:{Method}:{params}", - Context.Interaction.User.Id, nameof(UnbanByUID), - string.Join(",", new[] { $"{nameof(uid)}:{uid}" })); - try - { - using HttpClient c = new HttpClient(); - var testUri = new Uri(_lightlessServicesConfiguration.GetValue - (nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanDiscord"); - - c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token); - await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue - (nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanUID"), new UnbanRequest(uid, string.Empty)) - .ConfigureAwait(false); - var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); - if (discordChannelForMessages != null) - { - var discordChannel = await Context.Guild.GetChannelAsync(discordChannelForMessages.Value).ConfigureAwait(false) as IMessageChannel; - if (discordChannel != null) - { - var embedColor = Color.Blue; - - EmbedBuilder eb = new(); - eb.WithTitle("Unban Alert!"); - eb.WithColor(embedColor); - eb.WithDescription(uid + " has been unbanned"); - - await discordChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); - } - } - - await RespondAsync("Message sent", ephemeral: true).ConfigureAwait(false); - } - catch (Exception ex) - { - EmbedBuilder eb = new(); - eb.WithTitle("An error occured"); - eb.WithDescription("Please report this: " + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine); - await RespondAsync(embeds: new Embed[] { eb.Build() }, ephemeral: true).ConfigureAwait(false); - } - } - - [SlashCommand("markforban", "ADMIN ONLY: ban a user by their uid")] - public async Task MarkUidForBan([Summary("uid", "uid to ban")] string uid) - { - _logger.LogInformation("SlashCommand:{userId}:{Method}:{params}", - Context.Interaction.User.Id, nameof(MarkUidForBan), + Context.Interaction.User.Id, nameof(ServiceBan), string.Join(",", new[] { $"{nameof(uid)}:{uid}" })); try { using HttpClient c = new HttpClient(); c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token); - await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue + using (await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue (nameof(ServicesConfiguration.MainServerAddress)), "/user/ban"), new BanRequest(uid)) - .ConfigureAwait(false); + .ConfigureAwait(false)) { } var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); if (discordChannelForMessages != null) { @@ -274,6 +261,100 @@ public class LightlessModule : InteractionModuleBase } } + [SlashCommand("Toggle User Profile", "ADMIN ONLY: disable a user profile by their uid")] + public async Task ToggleUserProfile( + [Summary("uid", "uid to disable")] string uid, + [Summary("toggle", "Enable or Disable the profile")] + [Choice("Enable", "Enable")] + [Choice("Disable", "Disable")] string toggle + ) + { + _logger.LogInformation("SlashCommand:{userId}:{Method}:{params}", + Context.Interaction.User.Id, nameof(ToggleUserProfile), + string.Join(",", new[] { $"{nameof(uid)}:{uid}" })); + try + { + using HttpClient c = new HttpClient(); + c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token); + string endpoint = string.Equals(toggle, "Enable", StringComparison.Ordinal) ? "/user/enableProfile" : "/user/disableProfile"; + using (await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue + (nameof(ServicesConfiguration.MainServerAddress)), endpoint), new UserProfileAvailabilityRequest(uid)) + .ConfigureAwait(false)) { } + var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); + if (discordChannelForMessages != null) + { + var discordChannel = await Context.Guild.GetChannelAsync(discordChannelForMessages.Value).ConfigureAwait(false) as IMessageChannel; + if (discordChannel != null) + { + var embedColor = Color.Blue; + var action = string.Equals(toggle, "Enable", StringComparison.Ordinal) ? "enabled" : "disabled"; + + EmbedBuilder eb = new(); + eb.WithTitle($"Profile {action}"); + eb.WithColor(embedColor); + eb.WithDescription($"{uid}'s profile has been {action}"); + + await discordChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); + } + } + await RespondAsync("Message sent", ephemeral: true).ConfigureAwait(false); + } + catch (Exception ex) + { + EmbedBuilder eb = new(); + eb.WithTitle("An error occured"); + eb.WithDescription("Please report this: " + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine); + await RespondAsync(embeds: new Embed[] { eb.Build() }, ephemeral: true).ConfigureAwait(false); + } + } + + [SlashCommand("Toggle Group Profile", "ADMIN ONLY: toggle a group profile by their gid")] + public async Task ToggleGroupProfile( + [Summary("gid", "gid to disable")] string gid, + [Summary("toggle", "Enable or Disable the profile")] + [Choice("Enable", "Enable")] + [Choice("Disable", "Disable")] string toggle + ) + { + _logger.LogInformation("SlashCommand:{userId}:{Method}:{params}", + Context.Interaction.User.Id, nameof(ToggleUserProfile), + string.Join(",", new[] { $"{nameof(gid)}:{gid}" })); + try + { + using HttpClient c = new HttpClient(); + c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token); + string endpoint = string.Equals(toggle, "Enable", StringComparison.Ordinal) ? "/group/enableProfile" : "/group/disableProfile"; + using (await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue + (nameof(ServicesConfiguration.MainServerAddress)), endpoint), new GroupProfileAvailabilityRequest(gid)) + .ConfigureAwait(false)) { } + var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault(nameof(ServicesConfiguration.DiscordChannelForMessages), null); + if (discordChannelForMessages != null) + { + var discordChannel = await Context.Guild.GetChannelAsync(discordChannelForMessages.Value).ConfigureAwait(false) as IMessageChannel; + if (discordChannel != null) + { + var embedColor = Color.Blue; + var action = string.Equals(toggle, "Enable", StringComparison.Ordinal) ? "enabled" : "disabled"; + + EmbedBuilder eb = new(); + eb.WithTitle($"Profile {action}"); + eb.WithColor(embedColor); + eb.WithDescription($"{gid}'s profile has been {action}"); + + await discordChannel.SendMessageAsync(embed: eb.Build()).ConfigureAwait(false); + } + } + await RespondAsync("Message sent", ephemeral: true).ConfigureAwait(false); + } + catch (Exception ex) + { + EmbedBuilder eb = new(); + eb.WithTitle("An error occured"); + eb.WithDescription("Please report this: " + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace + Environment.NewLine); + await RespondAsync(embeds: new Embed[] { eb.Build() }, ephemeral: true).ConfigureAwait(false); + } + } + public async Task HandleUserAdd(string desiredUid, ulong discordUserId) { var embed = new EmbedBuilder();