From b4e39332efc770382d115b9621f9b895eba677a2 Mon Sep 17 00:00:00 2001 From: Yuuki Wesp Date: Thu, 28 Nov 2024 00:43:13 +0300 Subject: [PATCH 1/4] add missed sentry --- src/Argon.Entry/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Argon.Entry/Program.cs b/src/Argon.Entry/Program.cs index 4313aff..6270317 100644 --- a/src/Argon.Entry/Program.cs +++ b/src/Argon.Entry/Program.cs @@ -9,6 +9,7 @@ using Argon.Api.Features.Jwt; using Argon.Api.Features.Pex; using Argon.Api.Services; +using Argon.Api.Services.Fusion; using Argon.Contracts; using Newtonsoft.Json.Converters; using Orleans.Clustering.Kubernetes; @@ -16,7 +17,7 @@ using Orleans.Serialization; var builder = WebApplication.CreateBuilder(args); - +builder.AddSentry(builder.Configuration.GetConnectionString("Sentry")); builder.WebHost.ConfigureKestrel(options => { options.Limits.KeepAliveTimeout = TimeSpan.FromSeconds(400); From 03354f929fd6bf6788974e3d91912ced6dd0d674 Mon Sep 17 00:00:00 2001 From: Yuuki Wesp Date: Thu, 28 Nov 2024 00:43:27 +0300 Subject: [PATCH 2/4] add lockdown operatioln --- src/Argon.Contracts/AuthorizationError.cs | 15 +++++++++++++++ src/Argon.Contracts/Models/User.cs | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/Argon.Contracts/AuthorizationError.cs b/src/Argon.Contracts/AuthorizationError.cs index 47c3232..db04be9 100644 --- a/src/Argon.Contracts/AuthorizationError.cs +++ b/src/Argon.Contracts/AuthorizationError.cs @@ -20,4 +20,19 @@ public enum RegistrationError EMAIL_BANNED, SSO_EMAILS_NOT_ALLOWED, INTERNAL_ERROR +} + + +[TsEnum] +public enum LockdownReason +{ + NONE = 0, + SPAM_SCAM_ACCOUNT, + INCITING_MOMENT, + NON_BINARY_PERSON, + TOS_VIOLATION, + LGBT_AGITATION, + DRUG_VIOLATION, + TERRORISM_AGITATION, + CHILD_ABUSE } \ No newline at end of file diff --git a/src/Argon.Contracts/Models/User.cs b/src/Argon.Contracts/Models/User.cs index 7f89bd6..33da60f 100644 --- a/src/Argon.Contracts/Models/User.cs +++ b/src/Argon.Contracts/Models/User.cs @@ -26,4 +26,7 @@ public static readonly Guid SystemUser public string? OtpHash { get; set; } = null; [IgnoreMember] public ICollection ServerMembers { get; set; } = new List(); + + public LockdownReason LockdownReason { get; set; } + public DateTime? LockDownExpiration { get; set; } } \ No newline at end of file From 8fdd092c1fa9c4664444f5275a3884eee52f2c39 Mon Sep 17 00:00:00 2001 From: Yuuki Wesp Date: Thu, 28 Nov 2024 00:44:02 +0300 Subject: [PATCH 3/4] drop unused code, optimization ef, fixes --- Argon.Server.sln.DotSettings | 3 +- .../Controllers/MetadataController.cs | 27 ----- .../Orleanse/Streams/ClientArgonStream.cs | 46 ++++++++ .../Features/Orleanse/Streams/IArgonStream.cs | 12 ++ .../Orleanse/Streams/IStreamExtension.cs | 39 +++++++ .../Orleanse/Streams/ServerArgonStream.cs | 23 ++++ .../Features/Rpc/ClientArgonStream.cs | 105 ------------------ src/Argon.Api/Grains/FusionGrain.cs | 13 ++- src/Argon.Api/Grains/Interfaces/IUserGrain.cs | 16 +-- src/Argon.Api/Grains/SessionManager.cs | 2 +- src/Argon.Api/Grains/UserGrain.cs | 48 +++----- src/Argon.Api/Program.cs | 1 + src/Argon.Api/Services/EventBusService.cs | 15 --- .../Services/Fusion/EventBusService.cs | 22 ++++ .../{ => Fusion}/ServerInteraction.cs | 1 - .../Services/{ => Fusion}/UserInteraction.cs | 2 +- .../{ => Fusion}/UserStateInteraction.cs | 2 +- 17 files changed, 182 insertions(+), 195 deletions(-) delete mode 100644 src/Argon.Api/Controllers/MetadataController.cs create mode 100644 src/Argon.Api/Features/Orleanse/Streams/ClientArgonStream.cs create mode 100644 src/Argon.Api/Features/Orleanse/Streams/IArgonStream.cs create mode 100644 src/Argon.Api/Features/Orleanse/Streams/IStreamExtension.cs create mode 100644 src/Argon.Api/Features/Orleanse/Streams/ServerArgonStream.cs delete mode 100644 src/Argon.Api/Features/Rpc/ClientArgonStream.cs delete mode 100644 src/Argon.Api/Services/EventBusService.cs create mode 100644 src/Argon.Api/Services/Fusion/EventBusService.cs rename src/Argon.Api/Services/{ => Fusion}/ServerInteraction.cs (98%) rename src/Argon.Api/Services/{ => Fusion}/UserInteraction.cs (98%) rename src/Argon.Api/Services/{ => Fusion}/UserStateInteraction.cs (94%) diff --git a/Argon.Server.sln.DotSettings b/Argon.Server.sln.DotSettings index 8229e12..7623b95 100644 --- a/Argon.Server.sln.DotSettings +++ b/Argon.Server.sln.DotSettings @@ -92,4 +92,5 @@ True True True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/src/Argon.Api/Controllers/MetadataController.cs b/src/Argon.Api/Controllers/MetadataController.cs deleted file mode 100644 index c400a3d..0000000 --- a/src/Argon.Api/Controllers/MetadataController.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Argon.Api.Controllers; - -using Argon.Features; -using Extensions; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -[ApiController] -public class MetadataController : ControllerBase -{ - [HttpGet("/cfg.json"), AllowAnonymous] - public ValueTask GetHead() - => new(new HeadRoutingConfig($"{GlobalVersion.FullSemVer}.{GlobalVersion.ShortSha}", - "api.argon.gl", "argon-f14ic5ia.livekit.cloud", [ - new FeatureFlag("dev.window", true), - new FeatureFlag("user.allowServerCreation", true) - ], this.HttpContext.GetRegion())); -} - -public record HeadRoutingConfig( - string version, - string masterEndpoint, - string webRtcEndpoint, - List features, - string currentRegionCode); - -public record FeatureFlag(string code, bool enabled); \ No newline at end of file diff --git a/src/Argon.Api/Features/Orleanse/Streams/ClientArgonStream.cs b/src/Argon.Api/Features/Orleanse/Streams/ClientArgonStream.cs new file mode 100644 index 0000000..566a18d --- /dev/null +++ b/src/Argon.Api/Features/Orleanse/Streams/ClientArgonStream.cs @@ -0,0 +1,46 @@ +namespace Argon.Api.Features.Rpc; + +using Orleans.Streams; +using System.Threading.Channels; +using Contracts; + +public sealed class ClientArgonStream : IArgonStream where T : IArgonEvent +{ + private StreamSubscriptionHandle clientHandler { get; set; } + private Channel channel { get; } = Channel.CreateUnbounded(); + public async Task OnNextAsync(T item, StreamSequenceToken? token = null) + => await channel.Writer.WriteAsync(item); + + public Task OnCompletedAsync() + { + channel.Writer.Complete(); + return Task.CompletedTask; + } + public Task OnErrorAsync(Exception ex) + { + channel.Writer.Complete(ex); + return Task.CompletedTask; + } + + public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken ct = default) + { + while (await channel.Reader.WaitToReadAsync(ct)) + { + while (channel.Reader.TryRead(out var serverEvent)) + yield return serverEvent; + } + } + + public async ValueTask DisposeAsync() + => await clientHandler.UnsubscribeAsync(); + + + internal async ValueTask> BindClient(IAsyncStream stream) + { + clientHandler = await stream.SubscribeAsync(this); + return this; + } + + public ValueTask Fire(T ev) + => throw new NotImplementedException($"Client stream cannot be fire event"); +} \ No newline at end of file diff --git a/src/Argon.Api/Features/Orleanse/Streams/IArgonStream.cs b/src/Argon.Api/Features/Orleanse/Streams/IArgonStream.cs new file mode 100644 index 0000000..46bc811 --- /dev/null +++ b/src/Argon.Api/Features/Orleanse/Streams/IArgonStream.cs @@ -0,0 +1,12 @@ +namespace Argon.Api.Features.Rpc; + +using ActualLab.Rpc; +using Contracts; +using Orleans.Streams; + +public interface IArgonStream : + IAsyncObserver, IAsyncEnumerable, IAsyncDisposable where T : IArgonEvent +{ + public RpcStream AsRpcStream() => new(this); + ValueTask Fire(T ev); +} \ No newline at end of file diff --git a/src/Argon.Api/Features/Orleanse/Streams/IStreamExtension.cs b/src/Argon.Api/Features/Orleanse/Streams/IStreamExtension.cs new file mode 100644 index 0000000..8d571af --- /dev/null +++ b/src/Argon.Api/Features/Orleanse/Streams/IStreamExtension.cs @@ -0,0 +1,39 @@ +namespace Argon.Api.Features.Rpc; + +using Contracts; + +public interface IStreamExtension +{ + ValueTask> CreateClientStream(Guid primary); +} + +public interface IStreamExtension where T : Grain, IGrainWithGuidKey +{ + ValueTask> CreateServerStream(); + ValueTask> CreateServerStreamFor(Guid targetId); +} +public static class ArgonStreamExtensions +{ + public static IStreamExtension Streams(this T grain) where T : Grain, IGrainWithGuidKey + => new StreamForGrainExtension(grain); + + public static IStreamExtension Streams(this IClusterClient clusterClient) + => new StreamForClusterClientExtension(clusterClient); +} +public readonly struct StreamForGrainExtension(T grain) : IStreamExtension where T : Grain, IGrainWithGuidKey +{ + public ValueTask> CreateServerStream() + => CreateServerStreamFor(grain.GetPrimaryKey()); + + public async ValueTask> CreateServerStreamFor(Guid targetId) + => new ServerArgonStream(grain.GetStreamProvider(IArgonEvent.ProviderId) + .GetStream(StreamId.Create(IArgonEvent.Namespace, targetId))); +} + +public readonly struct StreamForClusterClientExtension(IClusterClient? client) : IStreamExtension +{ + public ValueTask> CreateClientStream(Guid primary) + => new ClientArgonStream().BindClient(client + .GetStreamProvider(IArgonEvent.ProviderId) + .GetStream(StreamId.Create(IArgonEvent.Namespace, primary))); +} \ No newline at end of file diff --git a/src/Argon.Api/Features/Orleanse/Streams/ServerArgonStream.cs b/src/Argon.Api/Features/Orleanse/Streams/ServerArgonStream.cs new file mode 100644 index 0000000..c4ca8a8 --- /dev/null +++ b/src/Argon.Api/Features/Orleanse/Streams/ServerArgonStream.cs @@ -0,0 +1,23 @@ +namespace Argon.Api.Features.Rpc; + +using Contracts; +using Orleans.Streams; + +public sealed class ServerArgonStream(IAsyncStream stream) : IArgonStream where T : IArgonEvent +{ + public Task OnNextAsync(T item, StreamSequenceToken? token = null) + => stream.OnNextAsync(item, token); + + public Task OnCompletedAsync() + => stream.OnCompletedAsync(); + public Task OnErrorAsync(Exception ex) + => stream.OnErrorAsync(ex); + + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken ct = default) + => throw new NotImplementedException($"Server stream cannot create async enumerator"); + + public async ValueTask DisposeAsync() {} // nothing any to dispose + + public async ValueTask Fire(T ev) + => await OnNextAsync(ev); +} \ No newline at end of file diff --git a/src/Argon.Api/Features/Rpc/ClientArgonStream.cs b/src/Argon.Api/Features/Rpc/ClientArgonStream.cs deleted file mode 100644 index 7abbece..0000000 --- a/src/Argon.Api/Features/Rpc/ClientArgonStream.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace Argon.Api.Features.Rpc; - -using Orleans.Streams; -using System.Threading.Channels; -using ActualLab.Rpc; -using Contracts; - -public interface IArgonStream : - IAsyncObserver, IAsyncEnumerable, IAsyncDisposable where T : IArgonEvent -{ - public RpcStream AsRpcStream() => new(this); - ValueTask Fire(T ev); -} - -public static class ArgonStreamExtensions -{ - public static IStreamExtension Streams(this T grain) where T : Grain, IGrainWithGuidKey - => new StreamForGrainExtension(grain); - - public static IStreamExtension Streams(this IClusterClient clusterClient) - => new StreamForClusterClientExtension(clusterClient); -} -public interface IStreamExtension -{ - ValueTask> CreateClientStream(Guid primary); -} -public interface IStreamExtension where T : Grain, IGrainWithGuidKey -{ - ValueTask> CreateServerStream(); -} - -public readonly struct StreamForGrainExtension(T grain) : IStreamExtension where T : Grain, IGrainWithGuidKey -{ - public async ValueTask> CreateServerStream() - => new ServerArgonStream(grain.GetStreamProvider(IArgonEvent.ProviderId) - .GetStream(StreamId.Create(IArgonEvent.Namespace, grain.GetPrimaryKey()))) ; -} - -public readonly struct StreamForClusterClientExtension(IClusterClient? client) : IStreamExtension -{ - public ValueTask> CreateClientStream(Guid primary) - => new ClientArgonStream().BindClient(client - .GetStreamProvider(IArgonEvent.ProviderId) - .GetStream(StreamId.Create(IArgonEvent.Namespace, primary))); -} - -public sealed class ClientArgonStream : IArgonStream where T : IArgonEvent -{ - private StreamSubscriptionHandle clientHandler { get; set; } - private Channel channel { get; } = Channel.CreateUnbounded(); - public async Task OnNextAsync(T item, StreamSequenceToken? token = null) - => await channel.Writer.WriteAsync(item); - - public Task OnCompletedAsync() - { - channel.Writer.Complete(); - return Task.CompletedTask; - } - public Task OnErrorAsync(Exception ex) - { - channel.Writer.Complete(ex); - return Task.CompletedTask; - } - - public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken ct = default) - { - while (await channel.Reader.WaitToReadAsync(ct)) - { - while (channel.Reader.TryRead(out var serverEvent)) - yield return serverEvent; - } - } - - public async ValueTask DisposeAsync() - => await clientHandler.UnsubscribeAsync(); - - - internal async ValueTask> BindClient(IAsyncStream stream) - { - clientHandler = await stream.SubscribeAsync(this); - return this; - } - - public ValueTask Fire(T ev) - => throw new NotImplementedException($"Client stream cannot be fire event"); -} - -public sealed class ServerArgonStream(IAsyncStream stream) : IArgonStream where T : IArgonEvent -{ - public Task OnNextAsync(T item, StreamSequenceToken? token = null) - => stream.OnNextAsync(item, token); - - public Task OnCompletedAsync() - => stream.OnCompletedAsync(); - public Task OnErrorAsync(Exception ex) - => stream.OnErrorAsync(ex); - - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken ct = default) - => throw new NotImplementedException($"Server stream cannot create async enumerator"); - - public async ValueTask DisposeAsync() {} // nothing any to dispose - - public async ValueTask Fire(T ev) - => await OnNextAsync(ev); -} \ No newline at end of file diff --git a/src/Argon.Api/Grains/FusionGrain.cs b/src/Argon.Api/Grains/FusionGrain.cs index 8afaa2d..b1014b3 100644 --- a/src/Argon.Api/Grains/FusionGrain.cs +++ b/src/Argon.Api/Grains/FusionGrain.cs @@ -3,6 +3,7 @@ namespace Argon.Api.Grains; using Contracts; using Extensions; using Features.Jwt; +using Features.Rpc; using Interfaces; using R3; using static DeactivationReasonCode; @@ -10,10 +11,13 @@ namespace Argon.Api.Grains; public class FusionGrain(IGrainFactory grainFactory) : Grain, IFusionSessionGrain { private DateTimeOffset _latestSignalTime = DateTimeOffset.UtcNow; - private DisposableBag disposableBag; + private DisposableBag disposableBag; + private Guid _userId; private Guid _machineId; + private IArgonStream userStream; + public async ValueTask SelfDestroy() { var servers = await grainFactory @@ -23,7 +27,7 @@ public async ValueTask SelfDestroy() await grainFactory .GetGrain(server) .SetUserStatus(_userId, UserStatus.Offline); - _userId = default; + _userId = default; _machineId = default; GrainContext.Deactivate(new(ApplicationRequested, "omae wa mou shindeiru")); } @@ -38,8 +42,11 @@ public async ValueTask BeginRealtimeSession(Guid userId, Guid machineKey, UserSt { this.RegisterGrainTimer(OnValidateActiveAsync, TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2)) .AddTo(ref disposableBag); - this._userId = userId; + this._userId = userId; this._machineId = machineKey; + + userStream = await this.Streams().CreateServerStreamFor(_userId); + await grainFactory .GetGrain(userId) .IndicateLastActive(machineKey); diff --git a/src/Argon.Api/Grains/Interfaces/IUserGrain.cs b/src/Argon.Api/Grains/Interfaces/IUserGrain.cs index d84d7fe..2535c1b 100644 --- a/src/Argon.Api/Grains/Interfaces/IUserGrain.cs +++ b/src/Argon.Api/Grains/Interfaces/IUserGrain.cs @@ -6,19 +6,15 @@ namespace Argon.Api.Grains.Interfaces; [Alias("Argon.Api.Grains.Interfaces.IUserGrain")] public interface IUserGrain : IGrainWithGuidKey { - [Alias("UpdateUser")] + [Alias(nameof(UpdateUser))] Task UpdateUser(UserEditInput input); - [Alias("DeleteUser")] - Task DeleteUser(); + [Alias(nameof(GetMe))] + Task GetMe(); - [Alias("GetUser")] - Task GetUser(); - - [Alias("GetMyServers")] + [Alias(nameof(GetMyServers))] Task> GetMyServers(); - [Alias("GetMyServersIds")] + [Alias(nameof(GetMyServersIds))] Task> GetMyServersIds(); -} - +} \ No newline at end of file diff --git a/src/Argon.Api/Grains/SessionManager.cs b/src/Argon.Api/Grains/SessionManager.cs index 740ce1a..57c200a 100644 --- a/src/Argon.Api/Grains/SessionManager.cs +++ b/src/Argon.Api/Grains/SessionManager.cs @@ -14,7 +14,7 @@ public class SessionManager( IPasswordHashingService passwordHashingService, ApplicationDbContext context) : Grain, ISessionManager { - public async Task GetUser() => await grainFactory.GetGrain(this.GetPrimaryKey()).GetUser(); + public async Task GetUser() => await grainFactory.GetGrain(this.GetPrimaryKey()).GetMe(); public Task Logout() => throw new NotImplementedException(); } \ No newline at end of file diff --git a/src/Argon.Api/Grains/UserGrain.cs b/src/Argon.Api/Grains/UserGrain.cs index 7e48f34..fb8bb37 100644 --- a/src/Argon.Api/Grains/UserGrain.cs +++ b/src/Argon.Api/Grains/UserGrain.cs @@ -11,7 +11,7 @@ public class UserGrain(IPasswordHashingService passwordHashingService, Applicati { public async Task UpdateUser(UserEditInput input) { - var user = await Get(); + var user = await context.Users.FirstAsync(x => x.Id == this.GetPrimaryKey()); user.Username = input.Username ?? user.Username; user.Username = input.DisplayName ?? user.DisplayName; user.AvatarFileId = input.AvatarId ?? user.AvatarFileId; @@ -20,39 +20,27 @@ public async Task UpdateUser(UserEditInput input) return user; } - public Task DeleteUser() - { - var user = context.Users.First(u => u.Id == this.GetPrimaryKey()); - user.DeletedAt = DateTime.UtcNow; - context.Users.Update(user); - return context.SaveChangesAsync(); - } - - public async Task GetUser() - { - var user = await Get(); - return user; - } + public async Task GetMe() + => await context.Users + .Include(x => x.ServerMembers) + .ThenInclude(x => x.Server) + .ThenInclude(x => x.Channels) + .FirstAsync(user => user.Id == this.GetPrimaryKey()); public async Task> GetMyServers() - { - var user = await context.Users - .Include(user => user.ServerMembers).ThenInclude(usersToServerRelation => usersToServerRelation.Server) - .FirstAsync(u => u.Id == this.GetPrimaryKey()); - var r = user.ServerMembers + => await context.Users + .Include(user => user.ServerMembers) + .ThenInclude(usersToServerRelation => usersToServerRelation.Server) + .Where(x => x.Id == this.GetPrimaryKey()) + .SelectMany(x => x.ServerMembers) .Select(x => x.Server) - .ToList(); - return r; - } + .ToListAsync(); public async Task> GetMyServersIds() - { - var user = await context.Users + => await context.Users .Include(user => user.ServerMembers) - .FirstAsync(u => u.Id == this.GetPrimaryKey()); - return user.ServerMembers.Select(x => x.ServerId).ToList(); - } - - private async Task Get() => await context.Users.Include(x => x.ServerMembers).ThenInclude(x => x.Server) - .ThenInclude(x => x.Channels).FirstAsync(user => user.Id == this.GetPrimaryKey()); + .Where(u => u.Id == this.GetPrimaryKey()) + .SelectMany(x => x.ServerMembers) + .Select(x => x.ServerId) + .ToListAsync(); } \ No newline at end of file diff --git a/src/Argon.Api/Program.cs b/src/Argon.Api/Program.cs index e4d16ed..7b664c4 100644 --- a/src/Argon.Api/Program.cs +++ b/src/Argon.Api/Program.cs @@ -18,6 +18,7 @@ using Argon.Api.Grains.Interfaces; using Argon.Api.Migrations; using Argon.Api.Services; +using Argon.Api.Services.Fusion; using Argon.Contracts; using Argon.Sfu; using Microsoft.EntityFrameworkCore; diff --git a/src/Argon.Api/Services/EventBusService.cs b/src/Argon.Api/Services/EventBusService.cs deleted file mode 100644 index 488f312..0000000 --- a/src/Argon.Api/Services/EventBusService.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Argon.Api.Services; - -using ActualLab.Rpc; -using Contracts; -using Features.Rpc; - -public class EventBusService(IClusterClient clusterClient) : IEventBus -{ - public async ValueTask> SubscribeToServerEvents(Guid ServerId) - { - var stream = await clusterClient.Streams().CreateClientStream(ServerId); - return stream.AsRpcStream(); - } -} - diff --git a/src/Argon.Api/Services/Fusion/EventBusService.cs b/src/Argon.Api/Services/Fusion/EventBusService.cs new file mode 100644 index 0000000..92fef33 --- /dev/null +++ b/src/Argon.Api/Services/Fusion/EventBusService.cs @@ -0,0 +1,22 @@ +namespace Argon.Api.Services.Fusion; + +using ActualLab.Rpc; +using Contracts; +using Features.Rpc; + +public class EventBusService(IClusterClient clusterClient, IFusionContext fusionContext) : IEventBus +{ + public async ValueTask> SubscribeToServerEvents(Guid ServerId) + { + var stream = await clusterClient.Streams().CreateClientStream(ServerId); + return stream.AsRpcStream(); + } + + public async ValueTask> SubscribeToMeEvents() + { + var user = await fusionContext.GetUserDataAsync(); + var stream = await clusterClient.Streams().CreateClientStream(user.id); + return stream.AsRpcStream(); + } +} + diff --git a/src/Argon.Api/Services/ServerInteraction.cs b/src/Argon.Api/Services/Fusion/ServerInteraction.cs similarity index 98% rename from src/Argon.Api/Services/ServerInteraction.cs rename to src/Argon.Api/Services/Fusion/ServerInteraction.cs index 1925772..b7ec51f 100644 --- a/src/Argon.Api/Services/ServerInteraction.cs +++ b/src/Argon.Api/Services/Fusion/ServerInteraction.cs @@ -3,7 +3,6 @@ namespace Argon.Api.Services; using Grains.Interfaces; using Contracts; using Contracts.Models; -using Entities; public class ServerInteraction(IGrainFactory grainFactory, IFusionContext fusionContext) : IServerInteraction { diff --git a/src/Argon.Api/Services/UserInteraction.cs b/src/Argon.Api/Services/Fusion/UserInteraction.cs similarity index 98% rename from src/Argon.Api/Services/UserInteraction.cs rename to src/Argon.Api/Services/Fusion/UserInteraction.cs index 0784d1d..dad3604 100644 --- a/src/Argon.Api/Services/UserInteraction.cs +++ b/src/Argon.Api/Services/Fusion/UserInteraction.cs @@ -11,7 +11,7 @@ public class UserInteraction(IGrainFactory grainFactory, IFusionContext fusionCo public async Task GetMe() { var userData = await fusionContext.GetUserDataAsync(); - return await grainFactory.GetGrain(userData.id).GetUser(); + return await grainFactory.GetGrain(userData.id).GetMe(); } public async Task CreateServer(CreateServerRequest request) diff --git a/src/Argon.Api/Services/UserStateInteraction.cs b/src/Argon.Api/Services/Fusion/UserStateInteraction.cs similarity index 94% rename from src/Argon.Api/Services/UserStateInteraction.cs rename to src/Argon.Api/Services/Fusion/UserStateInteraction.cs index 502ce6d..78b098e 100644 --- a/src/Argon.Api/Services/UserStateInteraction.cs +++ b/src/Argon.Api/Services/Fusion/UserStateInteraction.cs @@ -1,4 +1,4 @@ -namespace Argon.Api.Services; +namespace Argon.Api.Services.Fusion; using ActualLab.Text; using Contracts; From 0fbfb4ae9fb8bc50f5b0056049ee1940efac30e7 Mon Sep 17 00:00:00 2001 From: Yuuki Wesp Date: Thu, 28 Nov 2024 00:50:54 +0300 Subject: [PATCH 4/4] add missed migrations --- .../Entities/ApplicationDbContext.cs | 20 +- ...20241127215023_lockdownfeature.Designer.cs | 561 ++++++++++++++++++ .../20241127215023_lockdownfeature.cs | 75 +++ .../ApplicationDbContextModelSnapshot.cs | 11 +- 4 files changed, 659 insertions(+), 8 deletions(-) create mode 100644 src/Argon.Api/Migrations/20241127215023_lockdownfeature.Designer.cs create mode 100644 src/Argon.Api/Migrations/20241127215023_lockdownfeature.cs diff --git a/src/Argon.Api/Entities/ApplicationDbContext.cs b/src/Argon.Api/Entities/ApplicationDbContext.cs index b043ae4..c5217cc 100644 --- a/src/Argon.Api/Entities/ApplicationDbContext.cs +++ b/src/Argon.Api/Entities/ApplicationDbContext.cs @@ -15,15 +15,19 @@ public class ApplicationDbContext(DbContextOptions options public DbSet Channels { get; set; } public DbSet UsersToServerRelations { get; set; } - public DbSet ServerMemberArchetypes { get; set; } - public DbSet Archetypes { get; set; } + public DbSet ServerMemberArchetypes { get; set; } + public DbSet Archetypes { get; set; } public DbSet ChannelEntitlementOverwrites { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() - .HasKey(x => new { x.ServerMemberId, x.ArchetypeId }); + .HasKey(x => new + { + x.ServerMemberId, + x.ArchetypeId + }); modelBuilder.Entity() .HasOne(x => x.ServerMember) @@ -60,7 +64,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasForeignKey(c => c.ServerId); modelBuilder.Entity() - .HasIndex(x => new { x.Id, x.ServerId }); + .HasIndex(x => new + { + x.Id, + x.ServerId + }); modelBuilder.Entity() .HasOne(cpo => cpo.Channel) @@ -116,7 +124,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) IsMentionable = true, IsHidden = false, Description = "Default role for everyone in this server", - CreatedAt = DateTime.UtcNow + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411) } ]); @@ -133,7 +141,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) IsMentionable = false, IsHidden = true, Description = "Default role for owner in this server", - CreatedAt = DateTime.UtcNow + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382) } ]); } diff --git a/src/Argon.Api/Migrations/20241127215023_lockdownfeature.Designer.cs b/src/Argon.Api/Migrations/20241127215023_lockdownfeature.Designer.cs new file mode 100644 index 0000000..f34c34a --- /dev/null +++ b/src/Argon.Api/Migrations/20241127215023_lockdownfeature.Designer.cs @@ -0,0 +1,561 @@ +// +using System; +using Argon.Api.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Argon.Api.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20241127215023_lockdownfeature")] + partial class lockdownfeature + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Argon.Api.Entities.UserAgreements", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AgreeTOS") + .HasColumnType("boolean"); + + b.Property("AllowedSendOptionalEmails") + .HasColumnType("boolean"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserAgreements"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ArchetypeModel.Archetype", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Colour") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Entitlement") + .HasColumnType("numeric(20,0)"); + + b.Property("IconFileId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsHidden") + .HasColumnType("boolean"); + + b.Property("IsLocked") + .HasColumnType("boolean"); + + b.Property("IsMentionable") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ServerId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServerId"); + + b.ToTable("Archetypes"); + + b.HasData( + new + { + Id = new Guid("11111111-3333-0000-1111-111111111111"), + Colour = -8355712, + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411), + CreatorId = new Guid("11111111-2222-1111-2222-111111111111"), + Description = "Default role for everyone in this server", + Entitlement = 15760355m, + IsDeleted = false, + IsHidden = false, + IsLocked = false, + IsMentionable = true, + Name = "everyone", + ServerId = new Guid("11111111-0000-1111-1111-111111111111"), + UpdatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }, + new + { + Id = new Guid("11111111-4444-0000-1111-111111111111"), + Colour = -8355712, + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382), + CreatorId = new Guid("11111111-2222-1111-2222-111111111111"), + Description = "Default role for owner in this server", + Entitlement = -1m, + IsDeleted = false, + IsHidden = true, + IsLocked = true, + IsMentionable = false, + Name = "owner", + ServerId = new Guid("11111111-0000-1111-1111-111111111111"), + UpdatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }); + }); + + modelBuilder.Entity("Argon.Contracts.Models.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ServerId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServerId"); + + b.HasIndex("Id", "ServerId"); + + b.ToTable("Channels"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ChannelEntitlementOverwrite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Allow") + .HasColumnType("numeric(20,0)"); + + b.Property("ArchetypeId") + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Deny") + .HasColumnType("numeric(20,0)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Scope") + .HasColumnType("integer"); + + b.Property("ServerMemberId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ArchetypeId"); + + b.HasIndex("ChannelId"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServerMemberId"); + + b.ToTable("ChannelEntitlementOverwrites"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AvatarFileId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("Servers"); + + b.HasData( + new + { + Id = new Guid("11111111-0000-1111-1111-111111111111"), + AvatarFileId = "", + CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + CreatorId = new Guid("11111111-2222-1111-2222-111111111111"), + Description = "", + IsDeleted = false, + Name = "system_server", + UpdatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified) + }); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ServerMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatorId") + .HasColumnType("uuid"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("JoinedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ServerId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServerId"); + + b.HasIndex("UserId"); + + b.ToTable("UsersToServerRelations"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ServerMemberArchetype", b => + { + b.Property("ServerMemberId") + .HasColumnType("uuid"); + + b.Property("ArchetypeId") + .HasColumnType("uuid"); + + b.HasKey("ServerMemberId", "ArchetypeId"); + + b.HasIndex("ArchetypeId"); + + b.ToTable("ServerMemberArchetypes"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AvatarFileId") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LockDownExpiration") + .HasColumnType("timestamp with time zone"); + + b.Property("LockdownReason") + .HasColumnType("integer"); + + b.Property("OtpHash") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("PasswordDigest") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("PhoneNumber") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + + b.HasData( + new + { + Id = new Guid("11111111-2222-1111-2222-111111111111"), + CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + DisplayName = "System", + Email = "system@argon.gl", + IsDeleted = false, + LockdownReason = 0, + UpdatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Username = "system" + }); + }); + + modelBuilder.Entity("Argon.Api.Entities.UserAgreements", b => + { + b.HasOne("Argon.Contracts.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ArchetypeModel.Archetype", b => + { + b.HasOne("Argon.Contracts.Models.Server", "Server") + .WithMany("Archetypes") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.Channel", b => + { + b.HasOne("Argon.Contracts.Models.Server", "Server") + .WithMany("Channels") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ChannelEntitlementOverwrite", b => + { + b.HasOne("Argon.Contracts.Models.ArchetypeModel.Archetype", "Archetype") + .WithMany() + .HasForeignKey("ArchetypeId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Argon.Contracts.Models.Channel", "Channel") + .WithMany("EntitlementOverwrites") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Argon.Contracts.Models.ServerMember", "ServerMember") + .WithMany() + .HasForeignKey("ServerMemberId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("Archetype"); + + b.Navigation("Channel"); + + b.Navigation("ServerMember"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ServerMember", b => + { + b.HasOne("Argon.Contracts.Models.Server", "Server") + .WithMany("Users") + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Argon.Contracts.Models.User", "User") + .WithMany("ServerMembers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Server"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ServerMemberArchetype", b => + { + b.HasOne("Argon.Contracts.Models.ArchetypeModel.Archetype", "Archetype") + .WithMany("ServerMemberRoles") + .HasForeignKey("ArchetypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Argon.Contracts.Models.ServerMember", "ServerMember") + .WithMany("ServerMemberArchetypes") + .HasForeignKey("ServerMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Archetype"); + + b.Navigation("ServerMember"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ArchetypeModel.Archetype", b => + { + b.Navigation("ServerMemberRoles"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.Channel", b => + { + b.Navigation("EntitlementOverwrites"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.Server", b => + { + b.Navigation("Archetypes"); + + b.Navigation("Channels"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.ServerMember", b => + { + b.Navigation("ServerMemberArchetypes"); + }); + + modelBuilder.Entity("Argon.Contracts.Models.User", b => + { + b.Navigation("ServerMembers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Argon.Api/Migrations/20241127215023_lockdownfeature.cs b/src/Argon.Api/Migrations/20241127215023_lockdownfeature.cs new file mode 100644 index 0000000..44cdc35 --- /dev/null +++ b/src/Argon.Api/Migrations/20241127215023_lockdownfeature.cs @@ -0,0 +1,75 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Argon.Api.Migrations +{ + /// + public partial class lockdownfeature : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "LockDownExpiration", + table: "Users", + type: "timestamp with time zone", + nullable: true); + + migrationBuilder.AddColumn( + name: "LockdownReason", + table: "Users", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.UpdateData( + table: "Archetypes", + keyColumn: "Id", + keyValue: new Guid("11111111-3333-0000-1111-111111111111"), + column: "CreatedAt", + value: new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411)); + + migrationBuilder.UpdateData( + table: "Archetypes", + keyColumn: "Id", + keyValue: new Guid("11111111-4444-0000-1111-111111111111"), + column: "CreatedAt", + value: new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382)); + + migrationBuilder.UpdateData( + table: "Users", + keyColumn: "Id", + keyValue: new Guid("11111111-2222-1111-2222-111111111111"), + columns: new[] { "LockDownExpiration", "LockdownReason" }, + values: new object[] { null, 0 }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LockDownExpiration", + table: "Users"); + + migrationBuilder.DropColumn( + name: "LockdownReason", + table: "Users"); + + migrationBuilder.UpdateData( + table: "Archetypes", + keyColumn: "Id", + keyValue: new Guid("11111111-3333-0000-1111-111111111111"), + column: "CreatedAt", + value: new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382)); + + migrationBuilder.UpdateData( + table: "Archetypes", + keyColumn: "Id", + keyValue: new Guid("11111111-4444-0000-1111-111111111111"), + column: "CreatedAt", + value: new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411)); + } + } +} diff --git a/src/Argon.Api/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Argon.Api/Migrations/ApplicationDbContextModelSnapshot.cs index 2c448eb..ce85521 100644 --- a/src/Argon.Api/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Argon.Api/Migrations/ApplicationDbContextModelSnapshot.cs @@ -116,7 +116,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = new Guid("11111111-3333-0000-1111-111111111111"), Colour = -8355712, - CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382), + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411), CreatorId = new Guid("11111111-2222-1111-2222-111111111111"), Description = "Default role for everyone in this server", Entitlement = 15760355m, @@ -132,7 +132,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = new Guid("11111111-4444-0000-1111-111111111111"), Colour = -8355712, - CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8411), + CreatedAt = new DateTime(2024, 11, 23, 16, 1, 14, 205, DateTimeKind.Utc).AddTicks(8382), CreatorId = new Guid("11111111-2222-1111-2222-111111111111"), Description = "Default role for owner in this server", Entitlement = -1m, @@ -384,6 +384,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("IsDeleted") .HasColumnType("boolean"); + b.Property("LockDownExpiration") + .HasColumnType("timestamp with time zone"); + + b.Property("LockdownReason") + .HasColumnType("integer"); + b.Property("OtpHash") .HasMaxLength(128) .HasColumnType("character varying(128)"); @@ -416,6 +422,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) DisplayName = "System", Email = "system@argon.gl", IsDeleted = false, + LockdownReason = 0, UpdatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), Username = "system" });