From e64583304271c7c2604f41df5ce89cbed42c2cb5 Mon Sep 17 00:00:00 2001 From: "Emma [it/its]@Rory&" Date: Sun, 6 Jul 2025 16:15:15 +0200 Subject: [PATCH] More admin API fun --- extra/admin-api/.gitignore | 6 +- .../Controllers/UserController.cs | 94 ++++++++++++++++++- .../Middleware/AuthenticationMiddleware.cs | 4 +- .../Services/Configuration.cs | 2 + .../RabbitMQConfiguration.cs | 5 + 5 files changed, 105 insertions(+), 6 deletions(-) diff --git a/extra/admin-api/.gitignore b/extra/admin-api/.gitignore index 5a9afc4c..f4e4961b 100644 --- a/extra/admin-api/.gitignore +++ b/extra/admin-api/.gitignore @@ -1,9 +1,9 @@ -**/bin/ -**/obj/ +bin/ +obj/ /patches/ appsettings.Local*.json *.DotSettings.user /*.patch Spacebar.Db/**/*.orig -Spacebar.Db/**/*.rej \ No newline at end of file +Spacebar.Db/**/*.rej diff --git a/extra/admin-api/Spacebar.AdminAPI/Controllers/UserController.cs b/extra/admin-api/Spacebar.AdminAPI/Controllers/UserController.cs index 620382e1..62290991 100644 --- a/extra/admin-api/Spacebar.AdminAPI/Controllers/UserController.cs +++ b/extra/admin-api/Spacebar.AdminAPI/Controllers/UserController.cs @@ -1,9 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Text.Json.Serialization; +using System.Threading; +using System.Threading.Tasks; +using ArcaneLibs; using ArcaneLibs.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using RabbitMQ.Client; using Spacebar.AdminApi.Models; +using Spacebar.AdminAPI.Services; using Spacebar.Db.Contexts; using Spacebar.Db.Models; using Spacebar.RabbitMqUtilities; @@ -12,7 +22,7 @@ namespace Spacebar.AdminAPI.Controllers; [ApiController] [Route("/Users")] -public class UserController(ILogger logger, SpacebarDbContext db, RabbitMQService mq, IServiceProvider sp) : ControllerBase { +public class UserController(ILogger logger, Configuration config, RabbitMQConfiguration amqpConfig, SpacebarDbContext db, RabbitMQService mq, IServiceProvider sp) : ControllerBase { private readonly ILogger _logger = logger; [HttpGet] @@ -408,4 +418,86 @@ public class UserController(ILogger logger, SpacebarDbContext db } } } + + // { + // "op": 0, + // "t": "GUILD_ROLE_UPDATE", + // "d": { + // "guild_id": "1006649183970562092", + // "role": { + // "id": "1006706520514028812", + // "guild_id": "1006649183970562092", + // "color": 16711680, + // "hoist": true, + // "managed": false, + // "mentionable": true, + // "name": "Adminstrator", + // "permissions": "9", + // "position": 5, + // "unicode_emoji": "💖", + // "flags": 0 + // } + // }, + // "s": 38 + // } + + [HttpGet("test")] + public async IAsyncEnumerable Test() { + var factory = new ConnectionFactory { + Uri = new Uri(amqpConfig.ToConnectionString()) + }; + await using var mqConnection = await factory.CreateConnectionAsync(); + await using var mqChannel = await mqConnection.CreateChannelAsync(); + + var guildId = "1006649183970562092"; + // var roleId = "1006706520514028812"; //Administrator + var roleId = "1391303296148639051"; //Spacebar Maintainer + // int color = 16711680; //Administrator + int color = 99839; //Spacebar Maintainer + + await mqChannel.ExchangeDeclareAsync(exchange: guildId, type: ExchangeType.Fanout, durable: false); + + var props = new BasicProperties() { Type = "GUILD_ROLE_UPDATE" }; + int framerate = 30; + float delay = 1000f / framerate; + var secondsPerRotation = 6.243f; + // use delay, 255f = one rotation, lengthFactor = iterations to make a full rotation + var lengthFactor = (secondsPerRotation * 1000f / delay); + Console.WriteLine("Length factor: {0}, RPS: {1}", lengthFactor, 0); + var re = new RainbowEnumerator(lengthFactor: lengthFactor, offset: color, skip: 1); + var sw = Stopwatch.StartNew(); + while (true) { + var clr = re.Next(); + color = clr.r << 16 | clr.g << 8 | clr.b; + var publishSuccess = false; + do { + try { + await mqChannel.BasicPublishAsync(exchange: guildId, routingKey: "", mandatory: false, basicProperties: props, body: new { + guild_id = guildId, + role = new { + id = roleId, + guild_id = guildId, + color, + hoist = false, + managed = false, + mentionable = true, + name = "Spacebar Maintainer", + permissions = "8", + position = 5, + unicode_emoji = "", + flags = 0 + } + }.ToJson().AsBytes().ToArray()); + publishSuccess = true; + } + catch (Exception e) { + Console.WriteLine($"[RabbitMQ] Error publishing bulk delete: {e.Message}"); + await Task.Delay(10); + } + } while (!publishSuccess); + yield return $"{clr.r:X2} {clr.g:X2} {clr.b:X2} | {color:X8} | {sw.Elapsed} (waiting {Math.Max(0, (int)delay - (int)sw.ElapsedMilliseconds)} out of {delay} ms)"; + await Task.Delay(Math.Max(0, (int)delay - (int)sw.ElapsedMilliseconds)); + sw.Restart(); + } + } } \ No newline at end of file diff --git a/extra/admin-api/Spacebar.AdminAPI/Middleware/AuthenticationMiddleware.cs b/extra/admin-api/Spacebar.AdminAPI/Middleware/AuthenticationMiddleware.cs index 2dc4c977..1c8f9e93 100644 --- a/extra/admin-api/Spacebar.AdminAPI/Middleware/AuthenticationMiddleware.cs +++ b/extra/admin-api/Spacebar.AdminAPI/Middleware/AuthenticationMiddleware.cs @@ -13,7 +13,8 @@ public class AuthenticationMiddleware(RequestDelegate next) { private static Dictionary _userCacheExpiry = new(); public async Task InvokeAsync(HttpContext context, IServiceProvider sp) { - if (context.Request.Path.StartsWithSegments("/ping")) { + var config = sp.GetRequiredService(); + if (context.Request.Path.StartsWithSegments("/ping") || config.DisableAuthentication) { await next(context); return; } @@ -55,7 +56,6 @@ public class AuthenticationMiddleware(RequestDelegate next) { if (!_userCache.ContainsKey(token)) { var db = sp.GetRequiredService(); - var config = sp.GetRequiredService(); user = await db.Users.FindAsync(config.OverrideUid ?? res.ClaimsIdentity.Claims.First(x => x.Type == "id").Value) ?? throw new InvalidOperationException(); _userCache[token] = user; diff --git a/extra/admin-api/Spacebar.AdminAPI/Services/Configuration.cs b/extra/admin-api/Spacebar.AdminAPI/Services/Configuration.cs index a988a316..a58ef5c0 100644 --- a/extra/admin-api/Spacebar.AdminAPI/Services/Configuration.cs +++ b/extra/admin-api/Spacebar.AdminAPI/Services/Configuration.cs @@ -6,4 +6,6 @@ public class Configuration { } public string? OverrideUid { get; set; } + public bool DisableAuthentication { get; set; } = false; + public bool Enforce2FA { get; set; } = true; } \ No newline at end of file diff --git a/extra/admin-api/Utilities/Spacebar.RabbitMqUtilities/RabbitMQConfiguration.cs b/extra/admin-api/Utilities/Spacebar.RabbitMqUtilities/RabbitMQConfiguration.cs index e31e8c36..78a9add1 100644 --- a/extra/admin-api/Utilities/Spacebar.RabbitMqUtilities/RabbitMQConfiguration.cs +++ b/extra/admin-api/Utilities/Spacebar.RabbitMqUtilities/RabbitMQConfiguration.cs @@ -9,4 +9,9 @@ public class RabbitMQConfiguration { public required string Host { get; set; } public required string Username { get; set; } public required string Password { get; set; } + public required string Port { get; set; } + + public string ToConnectionString() { + return $"amqp://{Username}:{Password}@{Host}:{Port}"; + } } \ No newline at end of file