From ad2829be08116cdb596990c1152e1dfc4f0ffe47 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 17 Apr 2022 23:31:15 +0800 Subject: ... --- BackEnd/Timeline.Tests/Helpers/TestDatabase.cs | 7 +- BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs | 9 +- .../Timeline.Tests/ServiceTests/ServiceTestBase.cs | 67 ++ .../User/RegisterCode/RegisterCodeServiceTest.cs | 42 ++ BackEnd/Timeline.Tests/Services/ServiceTestBase.cs | 10 +- BackEnd/Timeline.Tests/Timeline.Tests.csproj | 6 + .../20220417152839_AddRegisterCode.Designer.cs | 747 +++++++++++++++++++++ .../Migrations/20220417152839_AddRegisterCode.cs | 84 +++ .../Migrations/DatabaseContextModelSnapshot.cs | 88 ++- BackEnd/Timeline/Services/User/UserService.cs | 15 +- 10 files changed, 1038 insertions(+), 37 deletions(-) create mode 100644 BackEnd/Timeline.Tests/ServiceTests/ServiceTestBase.cs create mode 100644 BackEnd/Timeline.Tests/ServiceTests/User/RegisterCode/RegisterCodeServiceTest.cs create mode 100644 BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.Designer.cs create mode 100644 BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.cs (limited to 'BackEnd') diff --git a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs index 5752b8cd..9bd690a2 100644 --- a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs +++ b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs @@ -1,11 +1,9 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging.Abstractions; -using Moq; using System.Threading.Tasks; using Timeline.Entities; using Timeline.Services; -using Timeline.Services.Token; using Timeline.Services.User; using Xunit; using Xunit.Abstractions; @@ -26,10 +24,7 @@ namespace Timeline.Tests.Helpers using var context = CreateContext(); await context.Database.MigrateAsync(); - var mockUserTokenManager = new Mock(); - mockUserTokenManager.SetReturnsDefault(Task.CompletedTask); - - var userService = new UserService(NullLogger.Instance, context, new PasswordService(), mockUserTokenManager.Object, new Clock()); + var userService = new UserService(NullLogger.Instance, context, new PasswordService(), new Clock()); await userService.ModifyUserAsync( await userService.GetUserIdByUsernameAsync("administrator"), diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs index 01390baf..62932010 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs @@ -1,4 +1,4 @@ -using FluentAssertions; +using FluentAssertions; using System.Collections.Generic; using System.Threading.Tasks; using Timeline.Models.Http; @@ -95,12 +95,6 @@ namespace Timeline.Tests.IntegratedTests body.Nickname.Should().Be("aaa"); } - { - var token = userClient.DefaultRequestHeaders.Authorization!.Parameter!; - // Token should expire. - await userClient.TestPostAssertErrorAsync("token/verify", new HttpVerifyOrRevokeTokenRequest() { Token = token }); - } - { // Check password. (await CreateClientWithCredential("newuser", "newpw")).Dispose(); @@ -294,7 +288,6 @@ namespace Timeline.Tests.IntegratedTests { using var client = await CreateClientAsUser(); await client.TestPostAsync(changePasswordUrl, new HttpChangePasswordRequest { OldPassword = "user1pw", NewPassword = "newpw" }); - await client.TestPatchAssertUnauthorizedAsync("users/user1", new HttpUserPatchRequest { }); (await CreateClientWithCredential("user1", "newpw")).Dispose(); } diff --git a/BackEnd/Timeline.Tests/ServiceTests/ServiceTestBase.cs b/BackEnd/Timeline.Tests/ServiceTests/ServiceTestBase.cs new file mode 100644 index 00000000..0019de02 --- /dev/null +++ b/BackEnd/Timeline.Tests/ServiceTests/ServiceTestBase.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.Logging.Abstractions; +using System.Threading.Tasks; +using Timeline.Entities; +using Timeline.Services.User; +using Timeline.Tests.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Timeline.Tests.ServiceTests +{ + public abstract class ServiceTestBase : IAsyncLifetime + { + private readonly ITestOutputHelper? _testOutputHelper; + + protected TestDatabase TestDatabase { get; } + protected DatabaseContext Database { get; private set; } = default!; + + protected TestClock Clock { get; } = new TestClock(); + protected UserService UserService { get; private set; } = default!; + + protected long AdminId { get; private set; } + protected long UserId { get; private set; } + + protected ServiceTestBase(ITestOutputHelper? testOutputHelper = null) + { + _testOutputHelper = testOutputHelper; + TestDatabase = new TestDatabase(); + } + + public async Task InitializeAsync() + { + await TestDatabase.InitializeAsync(); + Database = TestDatabase.CreateContext(_testOutputHelper); + + UserService = new UserService(NullLogger.Instance, Database, new PasswordService(), Clock); + + AdminId = await UserService.GetUserIdByUsernameAsync("admin"); + UserId = await UserService.GetUserIdByUsernameAsync("user"); + + await OnInitializeAsync(); + OnInitialize(); + } + + public async Task DisposeAsync() + { + OnDispose(); + await OnDisposeAsync(); + await Database.DisposeAsync(); + await TestDatabase.DisposeAsync(); + } + + + protected virtual void OnInitialize() { } + protected virtual void OnDispose() { } + + + protected virtual Task OnInitializeAsync() + { + return Task.CompletedTask; + } + + protected virtual Task OnDisposeAsync() + { + return Task.CompletedTask; + } + } +} diff --git a/BackEnd/Timeline.Tests/ServiceTests/User/RegisterCode/RegisterCodeServiceTest.cs b/BackEnd/Timeline.Tests/ServiceTests/User/RegisterCode/RegisterCodeServiceTest.cs new file mode 100644 index 00000000..6542696f --- /dev/null +++ b/BackEnd/Timeline.Tests/ServiceTests/User/RegisterCode/RegisterCodeServiceTest.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using FluentAssertions; +using Timeline.Services.User.RegisterCode; +using Xunit; + +namespace Timeline.Tests.ServiceTests.User.RegisterCode +{ + public class RegisterCodeServiceTest : ServiceTestBase + { + private RegisterCodeService _registerCodeService = default!; + + protected override void OnInitialize() + { + _registerCodeService = new RegisterCodeService(Database); + } + + protected override void OnDispose() + { + _registerCodeService.Dispose(); + } + + [Fact] + public async Task Test() + { + var a = await _registerCodeService.GetCurrentCode(AdminId); + a.Should().BeNull(); + var b = await _registerCodeService.CreateNewCode(AdminId); + b.Should().NotBeNullOrEmpty(); + var c = await _registerCodeService.GetCurrentCode(AdminId); + c.Should().Be(b); + var d = await _registerCodeService.CreateNewCode(AdminId); + d.Should().NotBe(b); + var e = await _registerCodeService.GetCodeOwner(d); + e.Should().Be(AdminId); + var f = await _registerCodeService.GetCodeOwner(b); + f.Should().BeNull(); + var g = await _registerCodeService.GetCodeOwner(b, false); + g.Should().Be(AdminId); + } + } +} + diff --git a/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs b/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs index 039d3f59..fa8269c2 100644 --- a/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs +++ b/BackEnd/Timeline.Tests/Services/ServiceTestBase.cs @@ -1,9 +1,7 @@ using Microsoft.Extensions.Logging.Abstractions; -using Moq; using System.Threading.Tasks; using Timeline.Entities; using Timeline.Services.Timeline; -using Timeline.Services.Token; using Timeline.Services.User; using Timeline.Tests.Helpers; using Xunit; @@ -21,8 +19,6 @@ namespace Timeline.Tests.Services protected TestClock Clock { get; } = new TestClock(); protected UserService UserService { get; private set; } = default!; protected TimelineService TimelineService { get; private set; } = default!; - protected Mock UserTokenServiceMock { get; private set; } = default!; - protected IUserTokenService UserTokenService { get; private set; } = default!; protected long UserId { get; private set; } protected long AdminId { get; private set; } @@ -38,11 +34,7 @@ namespace Timeline.Tests.Services await TestDatabase.InitializeAsync(); Database = TestDatabase.CreateContext(_testOutputHelper); - UserTokenServiceMock = new(); - UserTokenServiceMock.SetReturnsDefault(Task.CompletedTask); - UserTokenService = UserTokenServiceMock.Object; - - UserService = new UserService(NullLogger.Instance, Database, new PasswordService(), UserTokenService, Clock); + UserService = new UserService(NullLogger.Instance, Database, new PasswordService(), Clock); TimelineService = new TimelineService(NullLogger.Instance, Database, UserService, Clock); UserId = await UserService.GetUserIdByUsernameAsync("user"); diff --git a/BackEnd/Timeline.Tests/Timeline.Tests.csproj b/BackEnd/Timeline.Tests/Timeline.Tests.csproj index 84fc9055..9c8c64b4 100644 --- a/BackEnd/Timeline.Tests/Timeline.Tests.csproj +++ b/BackEnd/Timeline.Tests/Timeline.Tests.csproj @@ -31,8 +31,14 @@ + + + + + + diff --git a/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.Designer.cs b/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.Designer.cs new file mode 100644 index 00000000..acfbbd6c --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.Designer.cs @@ -0,0 +1,747 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Timeline.Entities; + +#nullable disable + +namespace Timeline.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20220417152839_AddRegisterCode")] + partial class AddRegisterCode + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.4"); + + modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Rank") + .HasColumnType("INTEGER") + .HasColumnName("rank"); + + b.Property("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user"); + + b.HasKey("Id"); + + b.HasIndex("TimelineId"); + + b.HasIndex("UserId"); + + b.ToTable("bookmark_timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.DataEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Data") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("data"); + + b.Property("Ref") + .HasColumnType("INTEGER") + .HasColumnName("ref"); + + b.Property("Tag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("tag"); + + b.HasKey("Id"); + + b.HasIndex("Tag") + .IsUnique(); + + b.ToTable("data"); + }); + + modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("AddTime") + .HasColumnType("TEXT") + .HasColumnName("add_time"); + + b.Property("OperatorId") + .HasColumnType("INTEGER") + .HasColumnName("operator_id"); + + b.Property("Order") + .HasColumnType("INTEGER") + .HasColumnName("order"); + + b.Property("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline_id"); + + b.HasKey("Id"); + + b.HasIndex("OperatorId"); + + b.HasIndex("TimelineId"); + + b.ToTable("highlight_timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.JwtTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Key") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("key"); + + b.HasKey("Id"); + + b.ToTable("jwt_token"); + }); + + modelBuilder.Entity("Timeline.Entities.MigrationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("migrations"); + }); + + modelBuilder.Entity("Timeline.Entities.RegisterCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("code"); + + b.Property("Enabled") + .HasColumnType("INTEGER") + .HasColumnName("enabled"); + + b.Property("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner_id"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("register_code"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Color") + .HasColumnType("TEXT") + .HasColumnName("color"); + + b.Property("CreateTime") + .HasColumnType("TEXT") + .HasColumnName("create_time"); + + b.Property("CurrentPostLocalId") + .HasColumnType("INTEGER") + .HasColumnName("current_post_local_id"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasColumnName("description"); + + b.Property("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.Property("NameLastModified") + .HasColumnType("TEXT") + .HasColumnName("name_last_modified"); + + b.Property("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner"); + + b.Property("Title") + .HasColumnType("TEXT") + .HasColumnName("title"); + + b.Property("UniqueId") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("unique_id") + .HasDefaultValueSql("lower(hex(randomblob(16)))"); + + b.Property("Visibility") + .HasColumnType("INTEGER") + .HasColumnName("visibility"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user"); + + b.HasKey("Id"); + + b.HasIndex("TimelineId"); + + b.HasIndex("UserId"); + + b.ToTable("timeline_members"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostDataEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("DataTag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("data_tag"); + + b.Property("Index") + .HasColumnType("INTEGER") + .HasColumnName("index"); + + b.Property("Kind") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("kind"); + + b.Property("LastUpdated") + .HasColumnType("TEXT") + .HasColumnName("last_updated"); + + b.Property("PostId") + .HasColumnType("INTEGER") + .HasColumnName("post"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("timeline_post_data"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("AuthorId") + .HasColumnType("INTEGER") + .HasColumnName("author"); + + b.Property("Color") + .HasColumnType("TEXT") + .HasColumnName("color"); + + b.Property("Content") + .HasColumnType("TEXT") + .HasColumnName("content"); + + b.Property("ContentType") + .HasColumnType("TEXT") + .HasColumnName("content_type"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("ExtraContent") + .HasColumnType("TEXT") + .HasColumnName("extra_content"); + + b.Property("LastUpdated") + .HasColumnType("TEXT") + .HasColumnName("last_updated"); + + b.Property("LocalId") + .HasColumnType("INTEGER") + .HasColumnName("local_id"); + + b.Property("Time") + .HasColumnType("TEXT") + .HasColumnName("time"); + + b.Property("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("TimelineId"); + + b.ToTable("timeline_posts"); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("DataTag") + .HasColumnType("TEXT") + .HasColumnName("data_tag"); + + b.Property("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property("Type") + .HasColumnType("TEXT") + .HasColumnName("type"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("user_avatars"); + }); + + modelBuilder.Entity("Timeline.Entities.UserConfigurationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("BookmarkVisibility") + .HasColumnType("INTEGER") + .HasColumnName("bookmark_visibility"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_config"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("create_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("LastModified") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("last_modified") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("Nickname") + .HasColumnType("TEXT") + .HasColumnName("nickname"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("password"); + + b.Property("UniqueId") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("unique_id") + .HasDefaultValueSql("lower(hex(randomblob(16)))"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("username"); + + b.Property("UsernameChangeTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("username_change_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(0L) + .HasColumnName("version"); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Timeline.Entities.UserPermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Permission") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("permission"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_permission"); + }); + + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("IntroducerId") + .HasColumnType("INTEGER") + .HasColumnName("introducer_id"); + + b.Property("RegisterCode") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("register_code"); + + b.Property("RegisterTime") + .HasColumnType("TEXT") + .HasColumnName("register_time"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("IntroducerId"); + + b.HasIndex("UserId"); + + b.ToTable("user_register_info"); + }); + + modelBuilder.Entity("Timeline.Entities.UserTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateAt") + .HasColumnType("TEXT") + .HasColumnName("create_at"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("ExpireAt") + .HasColumnType("TEXT") + .HasColumnName("expire_at"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("token"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("user_token"); + }); + + modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b => + { + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany() + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Timeline"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Operator") + .WithMany() + .HasForeignKey("OperatorId"); + + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany() + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Operator"); + + b.Navigation("Timeline"); + }); + + modelBuilder.Entity("Timeline.Entities.RegisterCode", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Owner") + .WithMany("Timelines") + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Members") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("TimelinesJoined") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Timeline"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostDataEntity", b => + { + b.HasOne("Timeline.Entities.TimelinePostEntity", "Post") + .WithMany("DataList") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Author") + .WithMany("TimelinePosts") + .HasForeignKey("AuthorId"); + + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Posts") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Timeline"); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithOne("Avatar") + .HasForeignKey("Timeline.Entities.UserAvatarEntity", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.UserConfigurationEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.UserPermissionEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("Permissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Introducer") + .WithMany() + .HasForeignKey("IntroducerId"); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Introducer"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.UserTokenEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.Navigation("Members"); + + b.Navigation("Posts"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.Navigation("DataList"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Navigation("Avatar"); + + b.Navigation("Permissions"); + + b.Navigation("TimelinePosts"); + + b.Navigation("Timelines"); + + b.Navigation("TimelinesJoined"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.cs b/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.cs new file mode 100644 index 00000000..c76cb4d0 --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.cs @@ -0,0 +1,84 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Timeline.Migrations +{ + public partial class AddRegisterCode : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "register_code", + columns: table => new + { + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + owner_id = table.Column(type: "INTEGER", nullable: true), + code = table.Column(type: "TEXT", nullable: false), + enabled = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_register_code", x => x.id); + table.ForeignKey( + name: "FK_register_code_users_owner_id", + column: x => x.owner_id, + principalTable: "users", + principalColumn: "id"); + }); + + migrationBuilder.CreateTable( + name: "user_register_info", + columns: table => new + { + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + user_id = table.Column(type: "INTEGER", nullable: false), + register_code = table.Column(type: "TEXT", nullable: false), + introducer_id = table.Column(type: "INTEGER", nullable: true), + register_time = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_user_register_info", x => x.id); + table.ForeignKey( + name: "FK_user_register_info_users_introducer_id", + column: x => x.introducer_id, + principalTable: "users", + principalColumn: "id"); + table.ForeignKey( + name: "FK_user_register_info_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_register_code_owner_id", + table: "register_code", + column: "owner_id"); + + migrationBuilder.CreateIndex( + name: "IX_user_register_info_introducer_id", + table: "user_register_info", + column: "introducer_id"); + + migrationBuilder.CreateIndex( + name: "IX_user_register_info_user_id", + table: "user_register_info", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "register_code"); + + migrationBuilder.DropTable( + name: "user_register_info"); + } + } +} diff --git a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs index 01a134d2..bfd9dd33 100644 --- a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs +++ b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace Timeline.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "6.0.3"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.4"); modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b => { @@ -140,6 +140,33 @@ namespace Timeline.Migrations b.ToTable("migrations"); }); + modelBuilder.Entity("Timeline.Entities.RegisterCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("code"); + + b.Property("Enabled") + .HasColumnType("INTEGER") + .HasColumnName("enabled"); + + b.Property("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner_id"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("register_code"); + }); + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => { b.Property("Id") @@ -453,6 +480,39 @@ namespace Timeline.Migrations b.ToTable("user_permission"); }); + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("IntroducerId") + .HasColumnType("INTEGER") + .HasColumnName("introducer_id"); + + b.Property("RegisterCode") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("register_code"); + + b.Property("RegisterTime") + .HasColumnType("TEXT") + .HasColumnName("register_time"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("IntroducerId"); + + b.HasIndex("UserId"); + + b.ToTable("user_register_info"); + }); + modelBuilder.Entity("Timeline.Entities.UserTokenEntity", b => { b.Property("Id") @@ -527,6 +587,15 @@ namespace Timeline.Migrations b.Navigation("Timeline"); }); + modelBuilder.Entity("Timeline.Entities.RegisterCode", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => { b.HasOne("Timeline.Entities.UserEntity", "Owner") @@ -618,6 +687,23 @@ namespace Timeline.Migrations b.Navigation("User"); }); + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Introducer") + .WithMany() + .HasForeignKey("IntroducerId"); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Introducer"); + + b.Navigation("User"); + }); + modelBuilder.Entity("Timeline.Entities.UserTokenEntity", b => { b.HasOne("Timeline.Entities.UserEntity", "User") diff --git a/BackEnd/Timeline/Services/User/UserService.cs b/BackEnd/Timeline/Services/User/UserService.cs index a20076d6..484860ac 100644 --- a/BackEnd/Timeline/Services/User/UserService.cs +++ b/BackEnd/Timeline/Services/User/UserService.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -8,7 +8,6 @@ using System.Threading.Tasks; using Timeline.Entities; using Timeline.Models; using Timeline.Models.Validation; -using Timeline.Services.Token; namespace Timeline.Services.User { @@ -21,17 +20,14 @@ namespace Timeline.Services.User private readonly IPasswordService _passwordService; - private readonly IUserTokenService _userTokenService; - private readonly UsernameValidator _usernameValidator = new UsernameValidator(); private readonly NicknameValidator _nicknameValidator = new NicknameValidator(); - public UserService(ILogger logger, DatabaseContext database, IPasswordService passwordService, IUserTokenService userTokenService, IClock clock) + public UserService(ILogger logger, DatabaseContext database, IPasswordService passwordService, IClock clock) { _logger = logger; _database = database; _passwordService = passwordService; - _userTokenService = userTokenService; _clock = clock; } @@ -208,11 +204,6 @@ namespace Timeline.Services.User await _database.SaveChangesAsync(); _logger.LogInformation(Resource.LogUserModified, entity.Username, id); - - if (password is not null) - { - await _userTokenService.RevokeAllTokenByUserIdAsync(id); - } } return entity; @@ -265,8 +256,6 @@ namespace Timeline.Services.User entity.Version += 1; await _database.SaveChangesAsync(); _logger.LogInformation(Resource.LogChangePassowrd, entity.Username, id); - - await _userTokenService.RevokeAllTokenByUserIdAsync(id); } public async Task> GetUsersV2Async(int page, int pageSize) -- cgit v1.2.3