Compare commits

...

18 Commits

Author SHA1 Message Date
defnotken
3d758f58f8 cleaning up logs 2025-09-05 16:52:06 -05:00
defnotken
9631f521bc DTOs 2025-09-05 16:41:00 -05:00
defnotken
f6b33425b5 Body fixes 2025-09-05 16:17:15 -05:00
defnotken
42ed164c54 Registering Controller 2025-09-05 16:02:00 -05:00
defnotken
9cd77d2b55 moving bancontroller 2025-09-05 15:20:43 -05:00
defnotken
332f7f7bb2 rewriting routs 2025-09-05 14:52:03 -05:00
defnotken
56bc277436 readding banned column 2025-09-05 14:29:37 -05:00
defnotken
176f0e7e56 push fix for banning scrubs 2025-09-05 14:14:37 -05:00
defnotken
b700f58d88 Lets try this 2025-09-05 14:04:11 -05:00
defnotken
232b3d535c submodule 2025-09-05 13:50:02 -05:00
defnotken
b5aa817d0b Ban and unban work 2025-09-05 13:27:09 -05:00
defnotken
7c81f880e1 Adding Auth to Unbans 2025-09-05 11:24:33 -05:00
defnotken
4f249a2db9 Merge branch 'master' into unbanbydiscord 2025-09-05 11:10:17 -05:00
5e37ff86e7 Merge pull request 'jwtfixes' (#1) from jwtfixes into master
Meow meow meow meow
2025-09-05 18:06:27 +02:00
defnotken
d27f5f3df0 I love auth 2025-09-05 11:05:09 -05:00
defnotken
d98062a4fe testing jwt 2025-09-05 11:00:13 -05:00
defnotken
3f76121e26 Unban work 2025-09-04 10:55:08 -05:00
defnotken
4feb64f015 Unban work 2025-09-04 10:54:52 -05:00
13 changed files with 1396 additions and 32 deletions

View File

@@ -121,6 +121,7 @@ public abstract class AuthControllerBase : Controller
{
CharacterIdentification = charaIdent,
Reason = "Autobanned CharacterIdent (" + uid + ")",
BannedUid = uid,
});
}

View File

@@ -3,8 +3,6 @@ using LightlessSyncShared.Metrics;
using LightlessSyncShared.Services;
using LightlessSyncShared.Utils;
using Microsoft.AspNetCore.Mvc.Controllers;
using StackExchange.Redis.Extensions.Core.Configuration;
using StackExchange.Redis.Extensions.System.Text.Json;
using StackExchange.Redis;
using System.Net;
using LightlessSyncAuthService.Services;
@@ -17,7 +15,6 @@ using LightlessSyncShared.Data;
using Microsoft.EntityFrameworkCore;
using Prometheus;
using LightlessSyncShared.Utils.Configuration;
using StackExchange.Redis.Extensions.Core.Abstractions;
namespace LightlessSyncAuthService;

View File

@@ -0,0 +1,99 @@
using LightlessSync.API.Dto.User;
using LightlessSync.API.Routes;
using LightlessSyncShared.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace LightlessSyncAuthService.Controllers;
[Route(LightlessAuth.User)]
[Authorize(Policy = "Internal")]
public class UserController : Controller
{
protected readonly ILogger Logger;
protected readonly IDbContextFactory<LightlessDbContext> LightlessDbContextFactory;
public UserController(ILogger<UserController> logger, IDbContextFactory<LightlessDbContext> lightlessDbContext)
{
Logger = logger;
LightlessDbContextFactory = lightlessDbContext;
}
[Route(LightlessAuth.Ban_Uid)]
[HttpPost]
public async Task MarkForBanUid([FromBody] BanRequest request)
{
using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync();
Logger.LogInformation("Banning user with UID {UID}", request.Uid);
//Mark User as banned, and not marked for ban
var auth = await dbContext.Auth.FirstOrDefaultAsync(f => f.UserUID == request.Uid);
if (auth != null)
{
auth.MarkForBan = true;
}
await dbContext.SaveChangesAsync();
}
[Route(LightlessAuth.User_Unban_Uid)]
[HttpPost]
public async Task UnBanUserByUid([FromBody] UnbanRequest request)
{
using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync();
Logger.LogInformation("Unbanning user with UID {UID}", request.Uid);
//Mark User as not banned, and not marked for ban (if marked)
var auth = await dbContext.Auth.FirstOrDefaultAsync(f => f.UserUID == request.Uid);
if (auth != null)
{
auth.IsBanned = false;
auth.MarkForBan = false;
}
// Remove all bans associated with this user
var bannedFromLightlessIds = dbContext.BannedUsers.Where(b => b.BannedUid == request.Uid);
dbContext.BannedUsers.RemoveRange(bannedFromLightlessIds);
// Remove all character/discord bans associated with this user
var lodestoneAuths = dbContext.LodeStoneAuth.Where(l => l.User != null && l.User.UID == request.Uid).ToList();
foreach (var lodestoneAuth in lodestoneAuths)
{
var bannedRegs = dbContext.BannedRegistrations.Where(b => b.DiscordIdOrLodestoneAuth == lodestoneAuth.HashedLodestoneId || b.DiscordIdOrLodestoneAuth == lodestoneAuth.DiscordId.ToString());
dbContext.BannedRegistrations.RemoveRange(bannedRegs);
}
await dbContext.SaveChangesAsync();
}
[Route(LightlessAuth.User_Unban_Discord)]
[HttpPost]
public async Task UnBanUserByDiscordId([FromBody] UnbanRequest request)
{
Logger.LogInformation("Unbanning user with discordId: {discordId}", request.DiscordId);
using var dbContext = await LightlessDbContextFactory.CreateDbContextAsync();
var userByDiscord = await dbContext.LodeStoneAuth.Include(l => l.User).FirstOrDefaultAsync(l => l.DiscordId.ToString() == request.DiscordId);
if (userByDiscord?.User == null)
{
Logger.LogInformation("Unbanning user with discordId: {discordId} but no user found", request.DiscordId);
return;
}
var bannedRegs = dbContext.BannedRegistrations.Where(b => b.DiscordIdOrLodestoneAuth == request.DiscordId || b.DiscordIdOrLodestoneAuth == userByDiscord.HashedLodestoneId);
//Mark User as not banned, and not marked for ban (if marked)
var auth = await dbContext.Auth.FirstOrDefaultAsync(f => f.UserUID == userByDiscord.User.UID);
if (auth != null)
{
auth.IsBanned = false;
auth.MarkForBan = false;
}
// Remove all bans associated with this user
var bannedFromLightlessIds = dbContext.BannedUsers.Where(b => b.BannedUid == auth.UserUID || b.BannedUid == auth.PrimaryUserUID);
dbContext.BannedUsers.RemoveRange(bannedFromLightlessIds);
await dbContext.SaveChangesAsync();
}
}

View File

@@ -1,29 +1,30 @@
using Microsoft.EntityFrameworkCore;
using LightlessSyncServer.Hubs;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Authorization;
using AspNetCoreRateLimit;
using LightlessSync.API.SignalR;
using LightlessSyncAuthService.Controllers;
using LightlessSyncServer.Controllers;
using LightlessSyncServer.Hubs;
using LightlessSyncServer.Services;
using LightlessSyncShared.Data;
using LightlessSyncShared.Metrics;
using LightlessSyncServer.Services;
using LightlessSyncShared.Utils;
using LightlessSyncShared.RequirementHandlers;
using LightlessSyncShared.Services;
using Prometheus;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using StackExchange.Redis;
using StackExchange.Redis.Extensions.Core.Configuration;
using System.Net;
using StackExchange.Redis.Extensions.System.Text.Json;
using LightlessSync.API.SignalR;
using LightlessSyncShared.Utils;
using LightlessSyncShared.Utils.Configuration;
using MessagePack;
using MessagePack.Resolvers;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Mvc.Controllers;
using LightlessSyncServer.Controllers;
using LightlessSyncShared.RequirementHandlers;
using LightlessSyncShared.Utils.Configuration;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Prometheus;
using StackExchange.Redis;
using StackExchange.Redis.Extensions.Core.Configuration;
using StackExchange.Redis.Extensions.System.Text.Json;
using System.Net;
using System.Text;
namespace LightlessSyncServer;
@@ -71,7 +72,7 @@ public class Startup
a.FeatureProviders.Remove(a.FeatureProviders.OfType<ControllerFeatureProvider>().First());
if (lightlessConfig.GetValue<Uri>(nameof(ServerConfiguration.MainServerAddress), defaultValue: null) == null)
{
a.FeatureProviders.Add(new AllowedControllersFeatureProvider(typeof(LightlessServerConfigurationController), typeof(LightlessBaseConfigurationController), typeof(ClientMessageController)));
a.FeatureProviders.Add(new AllowedControllersFeatureProvider(typeof(LightlessServerConfigurationController), typeof(LightlessBaseConfigurationController), typeof(ClientMessageController), typeof(UserController)));
}
else
{

View File

@@ -1,5 +1,5 @@
using FluentAssertions;
using LightlessSyncServer.Discord;
using LightlessSyncServices.Discord;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

View File

@@ -7,7 +7,6 @@ using LightlessSyncShared.Models;
using LightlessSyncShared.Services;
using LightlessSyncShared.Utils.Configuration;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
namespace LightlessSyncServices.Discord;

View File

@@ -9,6 +9,7 @@ using LightlessSyncShared.Services;
using StackExchange.Redis;
using LightlessSync.API.Data.Enum;
using LightlessSyncShared.Utils.Configuration;
using LightlessSync.API.Dto.User;
namespace LightlessSyncServices.Discord;
@@ -18,15 +19,16 @@ public class LightlessModule : InteractionModuleBase
private readonly IServiceProvider _services;
private readonly IConfigurationService<ServicesConfiguration> _lightlessServicesConfiguration;
private readonly IConnectionMultiplexer _connectionMultiplexer;
private readonly ServerTokenGenerator _serverTokenGenerator;
public LightlessModule(ILogger<LightlessModule> logger, IServiceProvider services,
IConfigurationService<ServicesConfiguration> lightlessServicesConfiguration,
IConnectionMultiplexer connectionMultiplexer)
IConnectionMultiplexer connectionMultiplexer, ServerTokenGenerator serverTokenGenerator)
{
_logger = logger;
_services = services;
_lightlessServicesConfiguration = lightlessServicesConfiguration;
_connectionMultiplexer = connectionMultiplexer;
_serverTokenGenerator = serverTokenGenerator;
}
[SlashCommand("userinfo", "Shows you your user information")]
@@ -103,9 +105,15 @@ public class LightlessModule : InteractionModuleBase
try
{
using HttpClient c = new HttpClient();
await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/msgc/sendMessage"), new ClientMessage(messageType, message, uid ?? string.Empty))
.ConfigureAwait(false);
c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token);
var testUri = new Uri(_lightlessServicesConfiguration.GetValue<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/msgc/sendMessage");
await c.PostAsJsonAsync(
new Uri(_lightlessServicesConfiguration.GetValue<Uri>(nameof(ServicesConfiguration.MainServerAddress)), "/msgc/sendMessage"),
new ClientMessage(messageType, message, uid ?? string.Empty)
).ConfigureAwait(false);
var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault<ulong?>(nameof(ServicesConfiguration.DiscordChannelForMessages), null);
if (uid == null && discordChannelForMessages != null)
@@ -138,6 +146,134 @@ 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)
{
_logger.LogInformation("SlashCommand:{userId}:{Method}:{params}",
Context.Interaction.User.Id, nameof(UnbanByDiscord),
string.Join(",", new[] { $"{nameof(discordId)}:{discordId}" }));
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<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanDiscord"), new UnbanRequest(string.Empty, discordId))
.ConfigureAwait(false);
var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault<ulong?>(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(discordId + " 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("unbanbyuid", "ADMIN ONLY: Unban a user by their uid")]
public async Task UnbanByUID([Summary("uid", "uid to unban")] 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<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanDiscord");
c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _serverTokenGenerator.Token);
await c.PostAsJsonAsync(new Uri(_lightlessServicesConfiguration.GetValue<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/user/unbanUID"), new UnbanRequest(uid, string.Empty))
.ConfigureAwait(false);
var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault<ulong?>(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),
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<Uri>
(nameof(ServicesConfiguration.MainServerAddress)), "/user/ban"), new BanRequest(uid))
.ConfigureAwait(false);
var discordChannelForMessages = _lightlessServicesConfiguration.GetValueOrDefault<ulong?>(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("Ban Alert!");
eb.WithColor(embedColor);
eb.WithDescription(uid + " has been marked for ban");
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<Embed> HandleUserAdd(string desiredUid, ulong discordUserId)
{
var embed = new EmbedBuilder();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LightlessSyncServer.Migrations
{
/// <inheritdoc />
public partial class AddBannedUid : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "banned_uid",
table: "banned_users",
type: "text",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "banned_uid",
table: "banned_users");
}
}
}

View File

@@ -64,6 +64,10 @@ namespace LightlessSyncServer.Migrations
.HasColumnType("character varying(100)")
.HasColumnName("character_identification");
b.Property<string>("BannedUid")
.HasColumnType("text")
.HasColumnName("banned_uid");
b.Property<string>("Reason")
.HasColumnType("text")
.HasColumnName("reason");

View File

@@ -7,6 +7,7 @@ public class Banned
[Key]
[MaxLength(100)]
public string CharacterIdentification { get; set; }
public string BannedUid { get; set; }
public string Reason { get; set; }
[Timestamp]
public byte[] Timestamp { get; set; }