From 88cec262cd49b977234ea6c944c1807fa1cf6b6d Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Thu, 25 Aug 2022 00:34:21 +0200 Subject: [PATCH] add alias handling to server and database --- MareAPI | 2 +- .../MareSynchronosServer/Hubs/MareHub.User.cs | 30 +- .../MareSynchronosServer/Hubs/MareHub.cs | 4 +- .../Discord/DiscordBot.cs | 3 +- .../Data/MareDbContext.cs | 24 ++ .../20220824222011_AddAlias.Designer.cs | 335 ++++++++++++++++++ .../Migrations/20220824222011_AddAlias.cs | 115 ++++++ .../Migrations/MareDbContextModelSnapshot.cs | 39 +- .../MareSynchronosShared/Models/Alias.cs | 13 + 9 files changed, 553 insertions(+), 12 deletions(-) create mode 100644 MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.Designer.cs create mode 100644 MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.cs create mode 100644 MareSynchronosServer/MareSynchronosShared/Models/Alias.cs diff --git a/MareAPI b/MareAPI index 37d4eb5..645dd0b 160000 --- a/MareAPI +++ b/MareAPI @@ -1 +1 @@ -Subproject commit 37d4eb5b1d8fc7d6adba0d58fa3cfdf79542700f +Subproject commit 645dd0b18f815cb7ccd81f37e84ded9cf650c3f3 diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs index 8ad64de..cf89d14 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs @@ -109,10 +109,20 @@ namespace MareSynchronosServer.Hubs other = otherToUser.UserUID } into leftJoin from otherEntry in leftJoin.DefaultIfEmpty() + join alias in _dbContext.Aliases + on new + { + uid = userToOther.UserUID + } equals new + { + uid = alias.UserUID + } into aliasLeftJoin + from aliasEntry in aliasLeftJoin.DefaultIfEmpty() where userToOther.UserUID == userid select new { + Alias = aliasEntry == null ? string.Empty : aliasEntry.AliasUID, userToOther.IsPaused, OtherIsPaused = otherEntry != null && otherEntry.IsPaused, userToOther.OtherUserUID, @@ -121,6 +131,7 @@ namespace MareSynchronosServer.Hubs return (await query.ToListAsync().ConfigureAwait(false)).Select(f => new ClientPairDto() { + VanityUID = f.Alias, IsPaused = f.IsPaused, OtherUID = f.OtherUserUID, IsSynced = f.IsSynced, @@ -170,18 +181,25 @@ namespace MareSynchronosServer.Hubs [HubMethodName(Api.SendUserPairedClientAddition)] public async Task SendPairedClientAddition(string uid) { + string otherUserUid = uid; if (uid == AuthenticatedUserId) return; uid = uid.Trim(); var user = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); + var potentialAlias = _dbContext.Aliases.SingleOrDefault(u => u.AliasUID == uid); + if (potentialAlias != null) + { + otherUserUid = potentialAlias.UserUID; + } + var otherUser = await _dbContext.Users - .SingleOrDefaultAsync(u => u.UID == uid).ConfigureAwait(false); + .SingleOrDefaultAsync(u => u.UID == otherUserUid).ConfigureAwait(false); var existingEntry = await _dbContext.ClientPairs.AsNoTracking() .FirstOrDefaultAsync(p => - p.User.UID == AuthenticatedUserId && p.OtherUser.UID == uid).ConfigureAwait(false); + p.User.UID == AuthenticatedUserId && p.OtherUser.UID == otherUserUid).ConfigureAwait(false); if (otherUser == null || existingEntry != null) return; - _logger.LogInformation("User {AuthenticatedUserId} adding {uid} to whitelist", AuthenticatedUserId, uid); + _logger.LogInformation("User {AuthenticatedUserId} adding {uid} to whitelist", AuthenticatedUserId, otherUserUid); ClientPair wl = new ClientPair() { IsPaused = false, @@ -190,7 +208,7 @@ namespace MareSynchronosServer.Hubs }; await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false); await _dbContext.SaveChangesAsync().ConfigureAwait(false); - var otherEntry = OppositeEntry(uid); + var otherEntry = OppositeEntry(otherUserUid); await Clients.User(user.UID) .SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() { @@ -201,7 +219,7 @@ namespace MareSynchronosServer.Hubs }, string.Empty).ConfigureAwait(false); if (otherEntry != null) { - await Clients.User(uid).SendAsync(Api.OnUserUpdateClientPairs, + await Clients.User(otherUserUid).SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() { OtherUID = user.UID, @@ -219,7 +237,7 @@ namespace MareSynchronosServer.Hubs } } - await _metricsClient.IncGaugeAsync(new GaugeRequest() {GaugeName = MetricsAPI.GaugePairs, Value = 1}).ConfigureAwait(false); + await _metricsClient.IncGaugeAsync(new GaugeRequest() { GaugeName = MetricsAPI.GaugePairs, Value = 1 }).ConfigureAwait(false); } [Authorize(AuthenticationSchemes = SecretKeyGrpcAuthenticationHandler.AuthScheme)] diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs index 9c714fc..3eb8ab0 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs @@ -72,10 +72,12 @@ namespace MareSynchronosServer.Hubs user.LastLoggedIn = DateTime.UtcNow; user.CharacterIdentification = characterIdentification; await _dbContext.SaveChangesAsync().ConfigureAwait(false); + + var alias = await _dbContext.Aliases.SingleOrDefaultAsync(u => u.UserUID == userId).ConfigureAwait(false); return new ConnectionDto { ServerVersion = Api.Version, - UID = userId, + UID = alias == null ? userId : alias.AliasUID, IsModerator = user.IsModerator, IsAdmin = user.IsAdmin }; diff --git a/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs b/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs index 4de2b25..ff313a8 100644 --- a/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs +++ b/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs @@ -166,7 +166,8 @@ public class DiscordBot : IHostedService while (!hasValidUid) { var uid = GenerateRandomString(10); - if (db.Users.Any(u => u.UID == uid)) continue; + if (await db.Users.AnyAsync(u => u.UID == uid).ConfigureAwait(false)) continue; + if (await db.Aliases.AnyAsync(u => u.AliasUID == uid).ConfigureAwait(false)) continue; user.UID = uid; hasValidUid = true; } diff --git a/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs b/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs index b20ca3b..0858390 100644 --- a/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs +++ b/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs @@ -1,14 +1,35 @@ using MareSynchronosShared.Models; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; namespace MareSynchronosShared.Data; public class MareDbContext : DbContext { + public MareDbContext() { } public MareDbContext(DbContextOptions options) : base(options) { } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured) + { + base.OnConfiguring(optionsBuilder); + return; + } + + optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=mare;Username=postgres", builder => + { + builder.MigrationsHistoryTable("_efmigrationshistory", "public"); + builder.MigrationsAssembly("MareSynchronosShared"); + }).UseSnakeCaseNamingConvention(); + optionsBuilder.EnableThreadSafetyChecks(false); + + base.OnConfiguring(optionsBuilder); + } + public DbSet Users { get; set; } public DbSet Files { get; set; } public DbSet ClientPairs { get; set; } @@ -17,6 +38,7 @@ public class MareDbContext : DbContext public DbSet Auth { get; set; } public DbSet LodeStoneAuth { get; set; } public DbSet BannedRegistrations { get; set; } + public DbSet Aliases { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -24,6 +46,8 @@ public class MareDbContext : DbContext modelBuilder.Entity().ToTable("auth"); modelBuilder.Entity().ToTable("users"); modelBuilder.Entity().HasIndex(c => c.CharacterIdentification); + modelBuilder.Entity().ToTable("aliases"); + modelBuilder.Entity().HasIndex(c => c.AliasUID); modelBuilder.Entity().ToTable("file_caches"); modelBuilder.Entity().HasIndex(c => c.UploaderUID); modelBuilder.Entity().ToTable("client_pairs"); diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.Designer.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.Designer.cs new file mode 100644 index 0000000..5adb749 --- /dev/null +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.Designer.cs @@ -0,0 +1,335 @@ +// +using System; +using MareSynchronosShared.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + [DbContext(typeof(MareDbContext))] + [Migration("20220824222011_AddAlias")] + partial class AddAlias + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MareSynchronosShared.Models.Alias", b => + { + b.Property("AliasUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("alias_uid"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("AliasUID") + .HasName("pk_aliases"); + + b.HasIndex("AliasUID") + .HasDatabaseName("ix_aliases_alias_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_aliases_user_uid"); + + b.ToTable("aliases", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => + { + b.Property("HashedKey") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("hashed_key"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("HashedKey") + .HasName("pk_auth"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_auth_user_uid"); + + b.ToTable("auth", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Banned", b => + { + b.Property("CharacterIdentification") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("character_identification"); + + b.Property("Reason") + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("CharacterIdentification") + .HasName("pk_banned_users"); + + b.ToTable("banned_users", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.BannedRegistrations", b => + { + b.Property("DiscordIdOrLodestoneAuth") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("discord_id_or_lodestone_auth"); + + b.HasKey("DiscordIdOrLodestoneAuth") + .HasName("pk_banned_registrations"); + + b.ToTable("banned_registrations", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b => + { + b.Property("UserUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("OtherUserUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("other_user_uid"); + + b.Property("AllowReceivingMessages") + .HasColumnType("boolean") + .HasColumnName("allow_receiving_messages"); + + b.Property("IsPaused") + .HasColumnType("boolean") + .HasColumnName("is_paused"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("UserUID", "OtherUserUID") + .HasName("pk_client_pairs"); + + b.HasIndex("OtherUserUID") + .HasDatabaseName("ix_client_pairs_other_user_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_client_pairs_user_uid"); + + b.ToTable("client_pairs", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("hash"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.Property("Uploaded") + .HasColumnType("boolean") + .HasColumnName("uploaded"); + + b.Property("UploaderUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("uploader_uid"); + + b.HasKey("Hash") + .HasName("pk_file_caches"); + + b.HasIndex("UploaderUID") + .HasDatabaseName("ix_file_caches_uploader_uid"); + + b.ToTable("file_caches", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ForbiddenUploadEntry", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("hash"); + + b.Property("ForbiddenBy") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("forbidden_by"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("Hash") + .HasName("pk_forbidden_upload_entries"); + + b.ToTable("forbidden_upload_entries", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b => + { + b.Property("DiscordId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)") + .HasColumnName("discord_id"); + + b.Property("HashedLodestoneId") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("hashed_lodestone_id"); + + b.Property("LodestoneAuthString") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("lodestone_auth_string"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_at"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("DiscordId") + .HasName("pk_lodestone_auth"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_lodestone_auth_user_uid"); + + b.ToTable("lodestone_auth", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.User", b => + { + b.Property("UID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("uid"); + + b.Property("CharacterIdentification") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("character_identification"); + + b.Property("IsAdmin") + .HasColumnType("boolean") + .HasColumnName("is_admin"); + + b.Property("IsModerator") + .HasColumnType("boolean") + .HasColumnName("is_moderator"); + + b.Property("LastLoggedIn") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_logged_in"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("UID") + .HasName("pk_users"); + + b.HasIndex("CharacterIdentification") + .HasDatabaseName("ix_users_character_identification"); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Alias", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_aliases_users_user_temp_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_auth_users_user_temp_id1"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b => + { + b.HasOne("MareSynchronosShared.Models.User", "OtherUser") + .WithMany() + .HasForeignKey("OtherUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_client_pairs_users_other_user_temp_id2"); + + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_client_pairs_users_user_temp_id3"); + + b.Navigation("OtherUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b => + { + b.HasOne("MareSynchronosShared.Models.User", "Uploader") + .WithMany() + .HasForeignKey("UploaderUID") + .HasConstraintName("fk_file_caches_users_uploader_uid"); + + b.Navigation("Uploader"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_lodestone_auth_users_user_uid"); + + b.Navigation("User"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.cs new file mode 100644 index 0000000..84ee64f --- /dev/null +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/20220824222011_AddAlias.cs @@ -0,0 +1,115 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + public partial class AddAlias : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_auth_users_user_temp_id", + table: "auth"); + + migrationBuilder.DropForeignKey( + name: "fk_client_pairs_users_other_user_temp_id1", + table: "client_pairs"); + + migrationBuilder.DropForeignKey( + name: "fk_client_pairs_users_user_temp_id2", + table: "client_pairs"); + + migrationBuilder.CreateTable( + name: "aliases", + columns: table => new + { + alias_uid = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), + user_uid = table.Column(type: "character varying(10)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_aliases", x => x.alias_uid); + table.ForeignKey( + name: "fk_aliases_users_user_temp_id", + column: x => x.user_uid, + principalTable: "users", + principalColumn: "uid"); + }); + + migrationBuilder.CreateIndex( + name: "ix_aliases_alias_uid", + table: "aliases", + column: "alias_uid"); + + migrationBuilder.CreateIndex( + name: "ix_aliases_user_uid", + table: "aliases", + column: "user_uid"); + + migrationBuilder.AddForeignKey( + name: "fk_auth_users_user_temp_id1", + table: "auth", + column: "user_uid", + principalTable: "users", + principalColumn: "uid"); + + migrationBuilder.AddForeignKey( + name: "fk_client_pairs_users_other_user_temp_id2", + table: "client_pairs", + column: "other_user_uid", + principalTable: "users", + principalColumn: "uid", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_client_pairs_users_user_temp_id3", + table: "client_pairs", + column: "user_uid", + principalTable: "users", + principalColumn: "uid", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_auth_users_user_temp_id1", + table: "auth"); + + migrationBuilder.DropForeignKey( + name: "fk_client_pairs_users_other_user_temp_id2", + table: "client_pairs"); + + migrationBuilder.DropForeignKey( + name: "fk_client_pairs_users_user_temp_id3", + table: "client_pairs"); + + migrationBuilder.DropTable( + name: "aliases"); + + migrationBuilder.AddForeignKey( + name: "fk_auth_users_user_temp_id", + table: "auth", + column: "user_uid", + principalTable: "users", + principalColumn: "uid"); + + migrationBuilder.AddForeignKey( + name: "fk_client_pairs_users_other_user_temp_id1", + table: "client_pairs", + column: "other_user_uid", + principalTable: "users", + principalColumn: "uid", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_client_pairs_users_user_temp_id2", + table: "client_pairs", + column: "user_uid", + principalTable: "users", + principalColumn: "uid", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs index 5d3bb74..b46cd5e 100644 --- a/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs @@ -22,6 +22,29 @@ namespace MareSynchronosServer.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("MareSynchronosShared.Models.Alias", b => + { + b.Property("AliasUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("alias_uid"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("AliasUID") + .HasName("pk_aliases"); + + b.HasIndex("AliasUID") + .HasDatabaseName("ix_aliases_alias_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_aliases_user_uid"); + + b.ToTable("aliases", (string)null); + }); + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => { b.Property("HashedKey") @@ -244,12 +267,22 @@ namespace MareSynchronosServer.Migrations b.ToTable("users", (string)null); }); + modelBuilder.Entity("MareSynchronosShared.Models.Alias", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_aliases_users_user_temp_id"); + + b.Navigation("User"); + }); + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => { b.HasOne("MareSynchronosShared.Models.User", "User") .WithMany() .HasForeignKey("UserUID") - .HasConstraintName("fk_auth_users_user_temp_id"); + .HasConstraintName("fk_auth_users_user_temp_id1"); b.Navigation("User"); }); @@ -261,14 +294,14 @@ namespace MareSynchronosServer.Migrations .HasForeignKey("OtherUserUID") .OnDelete(DeleteBehavior.Cascade) .IsRequired() - .HasConstraintName("fk_client_pairs_users_other_user_temp_id1"); + .HasConstraintName("fk_client_pairs_users_other_user_temp_id2"); b.HasOne("MareSynchronosShared.Models.User", "User") .WithMany() .HasForeignKey("UserUID") .OnDelete(DeleteBehavior.Cascade) .IsRequired() - .HasConstraintName("fk_client_pairs_users_user_temp_id2"); + .HasConstraintName("fk_client_pairs_users_user_temp_id3"); b.Navigation("OtherUser"); diff --git a/MareSynchronosServer/MareSynchronosShared/Models/Alias.cs b/MareSynchronosServer/MareSynchronosShared/Models/Alias.cs new file mode 100644 index 0000000..5335042 --- /dev/null +++ b/MareSynchronosServer/MareSynchronosShared/Models/Alias.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace MareSynchronosShared.Models; + +public class Alias +{ + [Key] + [MaxLength(10)] + [Required] + public string AliasUID { get; set; } + public User User { get; set; } + public string UserUID { get; set; } +}