From f8ecd3965d0bcec0b81e65c0b220cee8a307d858 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Mon, 18 Jul 2022 10:34:11 +0200 Subject: [PATCH] add LastLoggedIn migration, disallow secondary connections --- .../MareSynchronosServer/Hubs/MareHub.cs | 11 +- .../MareSynchronosServer.csproj | 1 - ...220718071653_UserLoginDateTime.Designer.cs | 203 ++++++++++++++++++ .../20220718071653_UserLoginDateTime.cs | 27 +++ .../Migrations/MareDbContextModelSnapshot.cs | 3 + .../MareSynchronosServer/Models/User.cs | 5 +- .../MareSynchronosServer/Startup.cs | 2 +- .../MareSynchronosServer/SystemInfoService.cs | 11 +- 8 files changed, 249 insertions(+), 14 deletions(-) create mode 100644 MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.Designer.cs create mode 100644 MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.cs diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs index 3f241e8..b75267e 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs @@ -43,9 +43,18 @@ namespace MareSynchronosServer.Hubs if (userId != null && !isBanned && !string.IsNullOrEmpty(characterIdentification)) { - MareMetrics.AuthorizedConnections.Inc(); _logger.LogInformation("Connection from " + userId); var user = (await _dbContext.Users.SingleAsync(u => u.UID == userId)); + if (!string.IsNullOrEmpty(user.CharacterIdentification)) + { + return new ConnectionDto() + { + ServerVersion = Api.Version + }; + } + + MareMetrics.AuthorizedConnections.Inc(); + user.LastLoggedIn = DateTime.UtcNow; user.CharacterIdentification = characterIdentification; await _dbContext.SaveChangesAsync(); return new ConnectionDto diff --git a/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj b/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj index 24ab12e..cb7a413 100644 --- a/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj +++ b/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj @@ -26,7 +26,6 @@ - diff --git a/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.Designer.cs b/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.Designer.cs new file mode 100644 index 0000000..d711e60 --- /dev/null +++ b/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.Designer.cs @@ -0,0 +1,203 @@ +// +using System; +using MareSynchronosServer.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + [DbContext(typeof(MareDbContext))] + [Migration("20220718071653_UserLoginDateTime")] + partial class UserLoginDateTime + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("MareSynchronosServer.Models.Auth", b => + { + b.Property("HashedKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserUID") + .HasColumnType("nvarchar(10)"); + + b.HasKey("HashedKey"); + + b.HasIndex("UserUID"); + + b.ToTable("Auth", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.Banned", b => + { + b.Property("CharacterIdentification") + .HasColumnType("nvarchar(450)"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.HasKey("CharacterIdentification"); + + b.ToTable("BannedUsers", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.ClientPair", b => + { + b.Property("UserUID") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("OtherUserUID") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("AllowReceivingMessages") + .HasColumnType("bit"); + + b.Property("IsPaused") + .HasColumnType("bit"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.HasKey("UserUID", "OtherUserUID"); + + b.HasIndex("OtherUserUID"); + + b.HasIndex("UserUID"); + + b.ToTable("ClientPairs", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.FileCache", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("nvarchar(40)"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("Uploaded") + .HasColumnType("bit"); + + b.Property("UploaderUID") + .HasColumnType("nvarchar(10)"); + + b.HasKey("Hash"); + + b.HasIndex("UploaderUID"); + + b.ToTable("FileCaches", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.ForbiddenUploadEntry", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("nvarchar(40)"); + + b.Property("ForbiddenBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.HasKey("Hash"); + + b.ToTable("ForbiddenUploadEntries", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.User", b => + { + b.Property("UID") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("CharacterIdentification") + .HasColumnType("nvarchar(450)"); + + b.Property("IsAdmin") + .HasColumnType("bit"); + + b.Property("IsModerator") + .HasColumnType("bit"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime2"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.HasKey("UID"); + + b.HasIndex("CharacterIdentification"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.Auth", b => + { + b.HasOne("MareSynchronosServer.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.ClientPair", b => + { + b.HasOne("MareSynchronosServer.Models.User", "OtherUser") + .WithMany() + .HasForeignKey("OtherUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MareSynchronosServer.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OtherUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosServer.Models.FileCache", b => + { + b.HasOne("MareSynchronosServer.Models.User", "Uploader") + .WithMany() + .HasForeignKey("UploaderUID"); + + b.Navigation("Uploader"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.cs b/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.cs new file mode 100644 index 0000000..558ee61 --- /dev/null +++ b/MareSynchronosServer/MareSynchronosServer/Migrations/20220718071653_UserLoginDateTime.cs @@ -0,0 +1,27 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + public partial class UserLoginDateTime : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "LastLoggedIn", + table: "Users", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LastLoggedIn", + table: "Users"); + } + } +} diff --git a/MareSynchronosServer/MareSynchronosServer/Migrations/MareDbContextModelSnapshot.cs b/MareSynchronosServer/MareSynchronosServer/Migrations/MareDbContextModelSnapshot.cs index ae54ded..2a56c4c 100644 --- a/MareSynchronosServer/MareSynchronosServer/Migrations/MareDbContextModelSnapshot.cs +++ b/MareSynchronosServer/MareSynchronosServer/Migrations/MareDbContextModelSnapshot.cs @@ -144,6 +144,9 @@ namespace MareSynchronosServer.Migrations b.Property("IsModerator") .HasColumnType("bit"); + b.Property("LastLoggedIn") + .HasColumnType("datetime2"); + b.Property("Timestamp") .IsConcurrencyToken() .ValueGeneratedOnAddOrUpdate() diff --git a/MareSynchronosServer/MareSynchronosServer/Models/User.cs b/MareSynchronosServer/MareSynchronosServer/Models/User.cs index 74308f7..38b1a24 100644 --- a/MareSynchronosServer/MareSynchronosServer/Models/User.cs +++ b/MareSynchronosServer/MareSynchronosServer/Models/User.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; namespace MareSynchronosServer.Models { @@ -14,5 +15,7 @@ namespace MareSynchronosServer.Models public bool IsModerator { get; set; } = false; public bool IsAdmin { get; set; } = false; + + public DateTime LastLoggedIn { get; set; } } } diff --git a/MareSynchronosServer/MareSynchronosServer/Startup.cs b/MareSynchronosServer/MareSynchronosServer/Startup.cs index f5bcf59..5d56c27 100644 --- a/MareSynchronosServer/MareSynchronosServer/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServer/Startup.cs @@ -41,7 +41,7 @@ namespace MareSynchronosServer services.AddSingleton(); services.AddSingleton(); - services.AddScoped(_ => Configuration); + services.AddTransient(_ => Configuration); services.AddDbContextPool(options => { diff --git a/MareSynchronosServer/MareSynchronosServer/SystemInfoService.cs b/MareSynchronosServer/MareSynchronosServer/SystemInfoService.cs index a6a1bc9..1ab1b88 100644 --- a/MareSynchronosServer/MareSynchronosServer/SystemInfoService.cs +++ b/MareSynchronosServer/MareSynchronosServer/SystemInfoService.cs @@ -1,17 +1,13 @@ using System; using System.Diagnostics; -using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Threading; using System.Threading.Tasks; using MareSynchronos.API; -using MareSynchronosServer.Data; using MareSynchronosServer.Hubs; using MareSynchronosServer.Metrics; using Microsoft.AspNetCore.SignalR; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -20,18 +16,13 @@ namespace MareSynchronosServer; public class SystemInfoService : IHostedService, IDisposable { private readonly ILogger _logger; - private readonly IServiceProvider _services; - private readonly IConfiguration _configuration; private readonly IHubContext _hubContext; private Timer _timer; public SystemInfoDto SystemInfoDto { get; private set; } = new(); - public SystemInfoService(ILogger logger, IServiceProvider services, - IConfiguration configuration, IHubContext hubContext) + public SystemInfoService(ILogger logger, IHubContext hubContext) { _logger = logger; - _services = services; - _configuration = configuration; _hubContext = hubContext; }