mirror of
https://github.com/spacebarchat/server.git
synced 2026-08-27 22:34:11 +00:00
Publish LazyRequest typescript attempt, partial C# impl
This commit is contained in:
+5
-2
@@ -1,6 +1,7 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Cryptography;
|
||||
using ArcaneLibs.Collections;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Spacebar.Models.Db.Contexts;
|
||||
@@ -53,7 +54,7 @@ public class SpacebarAuthenticationService(ILogger<SpacebarAuthenticationService
|
||||
async () => {
|
||||
var uid = config.OverrideUid ?? res?.ClaimsIdentity.Claims.First(x => x.Type == "id").Value;
|
||||
if (string.IsNullOrWhiteSpace(uid)) throw new InvalidOperationException("No user ID specified, is the access token valid?");
|
||||
return await db.Users.FindAsync(long.Parse(uid)) ?? throw new InvalidOperationException();
|
||||
return await db.Users.FindAsync(long.Parse(uid)) ?? throw new InvalidOperationException($"Could not find user with ID {uid}?");
|
||||
},
|
||||
config.AuthCacheExpiry);
|
||||
}
|
||||
@@ -62,9 +63,11 @@ public class SpacebarAuthenticationService(ILogger<SpacebarAuthenticationService
|
||||
var res = await ValidateTokenAsync(token);
|
||||
return await SessionCache.GetOrAdd(token,
|
||||
async () => {
|
||||
var uid = config.OverrideUid ?? res?.ClaimsIdentity.Claims.First(x => x.Type == "id").Value;
|
||||
var did = config.OverrideDid ?? res?.ClaimsIdentity.Claims.First(x => x.Type == "did").Value;
|
||||
if (string.IsNullOrWhiteSpace(did)) throw new InvalidOperationException("No device ID specified, is the access token valid?");
|
||||
return await db.Sessions.FindAsync(long.Parse(did)) ?? throw new InvalidOperationException();
|
||||
return await db.Sessions.SingleAsync(s => s.SessionId == did && s.UserId == long.Parse(uid))
|
||||
?? throw new InvalidOperationException($"Could not find device with ID {did}?");
|
||||
},
|
||||
config.AuthCacheExpiry);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using ArcaneLibs.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Spacebar.DataMappings.Generic;
|
||||
using Spacebar.GatewayOffload.Extensions.Db;
|
||||
using Spacebar.Interop.Authentication.AspNetCore;
|
||||
using Spacebar.Interop.Replication.Abstractions;
|
||||
@@ -29,13 +34,87 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen
|
||||
yield break;
|
||||
}
|
||||
|
||||
var memberList = new List<IMemberListEntry>();
|
||||
|
||||
// Fetch hoisted roles for the guild to define groups
|
||||
var hoistedRoles = await db.Roles
|
||||
.AsNoTracking()
|
||||
.Where(r => r.GuildId == payload.GuildId && r.Hoist)
|
||||
.OrderByDescending(r => r.Position)
|
||||
.Select(r => new { r.Id })
|
||||
// .Select(r => r.Id)
|
||||
.ToListAsync();
|
||||
|
||||
logger.LogDebug("Got hoisted roles: {roleIds}", hoistedRoles.Select(x => x.Id).ToList());
|
||||
List<long> handledRoles = [];
|
||||
foreach (var roleObj in hoistedRoles) {
|
||||
var role = roleObj.Id;
|
||||
var members = await db.Members.AsNoTracking()
|
||||
.Include(x => x.IdNavigation)
|
||||
.Where(x =>
|
||||
x.GuildId == payload.GuildId
|
||||
&& x.Roles.Any(r => r.Id == role)
|
||||
&& !x.Roles.Any(r => handledRoles.Contains(r.Id))
|
||||
// and finally, filter by online
|
||||
&& x.IdNavigation.Sessions.Any(s => s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown")
|
||||
)
|
||||
.OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync();
|
||||
|
||||
logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}",
|
||||
members.Count, role, roleObj.Name, string.Join("\n - ", members.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}"))
|
||||
);
|
||||
|
||||
memberList.Add(new RoleEntry() { Id = role.ToString(), Count = members.Count });
|
||||
memberList.AddRange(members.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() }));
|
||||
|
||||
handledRoles.Add(role);
|
||||
}
|
||||
|
||||
// online members
|
||||
var onlineMembers = await db.Members.AsNoTracking()
|
||||
.Include(x => x.IdNavigation)
|
||||
// .ThenInclude(x=>x.Sessions)
|
||||
.Where(x =>
|
||||
x.GuildId == payload.GuildId
|
||||
&& !x.Roles.Any(r => handledRoles.Contains(r.Id))
|
||||
// and finally, filter by online
|
||||
&& x.IdNavigation.Sessions.Any(s => s.Status != "offline" && s.Status != "invisible" && s.Status != "unknown")
|
||||
)
|
||||
.OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync();
|
||||
|
||||
logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}",
|
||||
onlineMembers.Count, "online", "online", string.Join("\n - ", onlineMembers.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}"))
|
||||
);
|
||||
|
||||
if (onlineMembers.Count > 0) {
|
||||
memberList.Add(new RoleEntry() { Id = "online", Count = onlineMembers.Count });
|
||||
memberList.AddRange(onlineMembers.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() }));
|
||||
}
|
||||
|
||||
|
||||
if (memberList.Count < 2000) {
|
||||
logger.LogInformation("Less than 2000 members, including offline members...");
|
||||
var offlineMembers = await db.Members.AsNoTracking()
|
||||
.Include(x => x.IdNavigation)
|
||||
// .ThenInclude(x=>x.Sessions)
|
||||
.Where(x =>
|
||||
x.GuildId == payload.GuildId
|
||||
&& !x.Roles.Any(r => handledRoles.Contains(r.Id))
|
||||
// and finally, filter by online
|
||||
&& (x.IdNavigation.Sessions.Any(s => s.Status == "offline" || s.Status == "invisible" || s.Status == "unknown") || !x.IdNavigation.Sessions.Any())
|
||||
)
|
||||
.OrderBy(x => x.Nick ?? x.IdNavigation.Username).ToListAsync();
|
||||
|
||||
logger.LogInformation("Got {count} potential members for group {group} ({groupName}):\n - {members}",
|
||||
offlineMembers.Count, "offline", "offline", string.Join("\n - ", offlineMembers.Take(10).Select(x => $"{x.Id} {x.Nick ?? x.IdNavigation.Tag}"))
|
||||
);
|
||||
|
||||
if (offlineMembers.Count > 0) {
|
||||
memberList.Add(new RoleEntry() { Id = "offline", Count = offlineMembers.Count });
|
||||
memberList.AddRange(offlineMembers.Select(m => (IMemberListEntry)new MemberEntry() { Member = m.ToPublicMember() }));
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Got member list with {count} total nodes", memberList.Count);
|
||||
}
|
||||
|
||||
private async Task<string?> GetMemberListIdAsync(SpacebarDbContext db, long guildId, long channelId) {
|
||||
@@ -48,4 +127,19 @@ public class Op14Controller(ILogger<Op12Controller> logger, SpacebarAspNetAuthen
|
||||
|
||||
return null; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IMemberListEntry { }
|
||||
|
||||
internal struct RoleEntry : IMemberListEntry {
|
||||
[JsonPropertyName("id"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("count")]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
internal struct MemberEntry : IMemberListEntry {
|
||||
[JsonPropertyName("member")]
|
||||
public Member Member { get; set; }
|
||||
}
|
||||
@@ -32,3 +32,15 @@ Content-Type: application/json
|
||||
]
|
||||
|
||||
###
|
||||
|
||||
POST {{GatewayOffload_HostAddress}}/_spacebar/offload/gateway/LazyRequest
|
||||
Accept: application/json
|
||||
Authorization: Bearer {{AccessToken}}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"guild_id": "1006649183970562092",
|
||||
"channels": {
|
||||
"1006649184062836783": [[1,2]]
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,17 @@
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Trace",
|
||||
//Warning
|
||||
"Microsoft.AspNetCore.Server.Kestrel.Connections": "Information",
|
||||
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets": "Information",
|
||||
"Microsoft.AspNetCore.Mvc": "Warning",
|
||||
//Warning
|
||||
"Microsoft.AspNetCore.HostFiltering": "Warning",
|
||||
//Warning
|
||||
"Microsoft.AspNetCore.Cors": "Warning",
|
||||
//Warning
|
||||
// "Microsoft.EntityFrameworkCore": "Warning"
|
||||
"Microsoft.EntityFrameworkCore.Database.Command": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Spacebar": "Host=127.0.0.1; Username=postgres; Database=spacebar; Port=5433; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600;"
|
||||
"Spacebar": "Host=127.0.0.1; Username=postgres; Database=sb-testing; Port=5432; Include Error Detail=true; Maximum Pool Size=1000; Command Timeout=6000; Timeout=600;"
|
||||
},
|
||||
"Spacebar": {
|
||||
"Authentication": {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"dev": {
|
||||
"AccessToken": "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwMDY1OTgyMzAxNTYzNDEyNzYiLCJpYXQiOjE3NjU4NjYxNDcsImtpZCI6IjVkZTcwNjZlNWQ5YTkxZDc4NGQ2NTY1Njc2Zjc0ZGY4NGQyMDllNzBjY2M3ZmZmNmFhNjgxNTkwODEwMWRjMWEiLCJ2ZXIiOjMsImRpZCI6IklCWkFSR01YT0UifQ.ALoB-4LXPaHTiUWRSoO3KIIc7CX2tP2vdebxmt10h3DqqBW57Zqx9zNImGxn0tV4cqFB1nZct3cZjJ_XVchtUF61AEgGR54QpV2sHAss2NMqZA_S3WK7UigFJYDddWUt2D_GrvzUYUVJ_WB4gt-tXekKzB2K6dazTEFYPFSY6xINBWed"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user