diff options
author | crupest <crupest@outlook.com> | 2022-04-17 23:31:15 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-04-17 23:31:15 +0800 |
commit | ad2829be08116cdb596990c1152e1dfc4f0ffe47 (patch) | |
tree | e7f2f5dd2fd72889148d323492de7ab9d5cfce8d | |
parent | 84cb99d087f62dca89fa682feae6738b3350fed4 (diff) | |
download | timeline-ad2829be08116cdb596990c1152e1dfc4f0ffe47.tar.gz timeline-ad2829be08116cdb596990c1152e1dfc4f0ffe47.tar.bz2 timeline-ad2829be08116cdb596990c1152e1dfc4f0ffe47.zip |
...
10 files changed, 1038 insertions, 37 deletions
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<IUserTokenService>();
- mockUserTokenManager.SetReturnsDefault(Task.CompletedTask);
-
- var userService = new UserService(NullLogger<UserService>.Instance, context, new PasswordService(), mockUserTokenManager.Object, new Clock());
+ var userService = new UserService(NullLogger<UserService>.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;
@@ -96,12 +96,6 @@ namespace Timeline.Tests.IntegratedTests }
{
- 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<UserService>.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<IUserTokenService> 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<UserService>.Instance, Database, new PasswordService(), UserTokenService, Clock);
+ UserService = new UserService(NullLogger<UserService>.Instance, Database, new PasswordService(), Clock);
TimelineService = new TimelineService(NullLogger<TimelineService>.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 @@ </ItemGroup>
<ItemGroup>
<None Remove="V2\" />
+ <None Remove="ServiceTest\" />
+ <None Remove="ServiceTests\User\" />
+ <None Remove="ServiceTests\User\RegisterCode\" />
</ItemGroup>
<ItemGroup>
<Folder Include="IntegratedTests2\" />
+ <Folder Include="ServiceTests\" />
+ <Folder Include="ServiceTests\User\" />
+ <Folder Include="ServiceTests\User\RegisterCode\" />
</ItemGroup>
</Project>
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 @@ +// <auto-generated /> +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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<long>("Rank") + .HasColumnType("INTEGER") + .HasColumnName("rank"); + + b.Property<long>("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<byte[]>("Data") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("data"); + + b.Property<int>("Ref") + .HasColumnType("INTEGER") + .HasColumnName("ref"); + + b.Property<string>("Tag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("tag"); + + b.HasKey("Id"); + + b.HasIndex("Tag") + .IsUnique(); + + b.ToTable("data"); + }); + + modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<DateTime>("AddTime") + .HasColumnType("TEXT") + .HasColumnName("add_time"); + + b.Property<long?>("OperatorId") + .HasColumnType("INTEGER") + .HasColumnName("operator_id"); + + b.Property<long>("Order") + .HasColumnType("INTEGER") + .HasColumnName("order"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<byte[]>("Key") + .IsRequired() + .HasColumnType("BLOB") + .HasColumnName("key"); + + b.HasKey("Id"); + + b.ToTable("jwt_token"); + }); + + modelBuilder.Entity("Timeline.Entities.MigrationEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("migrations"); + }); + + modelBuilder.Entity("Timeline.Entities.RegisterCode", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("Code") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("code"); + + b.Property<bool>("Enabled") + .HasColumnType("INTEGER") + .HasColumnName("enabled"); + + b.Property<long?>("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner_id"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("register_code"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("Color") + .HasColumnType("TEXT") + .HasColumnName("color"); + + b.Property<DateTime>("CreateTime") + .HasColumnType("TEXT") + .HasColumnName("create_time"); + + b.Property<long>("CurrentPostLocalId") + .HasColumnType("INTEGER") + .HasColumnName("current_post_local_id"); + + b.Property<string>("Description") + .HasColumnType("TEXT") + .HasColumnName("description"); + + b.Property<DateTime>("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property<string>("Name") + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.Property<DateTime>("NameLastModified") + .HasColumnType("TEXT") + .HasColumnName("name_last_modified"); + + b.Property<long>("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner"); + + b.Property<string>("Title") + .HasColumnType("TEXT") + .HasColumnName("title"); + + b.Property<string>("UniqueId") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("unique_id") + .HasDefaultValueSql("lower(hex(randomblob(16)))"); + + b.Property<int>("Visibility") + .HasColumnType("INTEGER") + .HasColumnName("visibility"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<long>("TimelineId") + .HasColumnType("INTEGER") + .HasColumnName("timeline"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("DataTag") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("data_tag"); + + b.Property<long>("Index") + .HasColumnType("INTEGER") + .HasColumnName("index"); + + b.Property<string>("Kind") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("kind"); + + b.Property<DateTime>("LastUpdated") + .HasColumnType("TEXT") + .HasColumnName("last_updated"); + + b.Property<long>("PostId") + .HasColumnType("INTEGER") + .HasColumnName("post"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("timeline_post_data"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<long?>("AuthorId") + .HasColumnType("INTEGER") + .HasColumnName("author"); + + b.Property<string>("Color") + .HasColumnType("TEXT") + .HasColumnName("color"); + + b.Property<string>("Content") + .HasColumnType("TEXT") + .HasColumnName("content"); + + b.Property<string>("ContentType") + .HasColumnType("TEXT") + .HasColumnName("content_type"); + + b.Property<bool>("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property<string>("ExtraContent") + .HasColumnType("TEXT") + .HasColumnName("extra_content"); + + b.Property<DateTime>("LastUpdated") + .HasColumnType("TEXT") + .HasColumnName("last_updated"); + + b.Property<long>("LocalId") + .HasColumnType("INTEGER") + .HasColumnName("local_id"); + + b.Property<DateTime>("Time") + .HasColumnType("TEXT") + .HasColumnName("time"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("DataTag") + .HasColumnType("TEXT") + .HasColumnName("data_tag"); + + b.Property<DateTime>("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property<string>("Type") + .HasColumnType("TEXT") + .HasColumnName("type"); + + b.Property<long>("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("user_avatars"); + }); + + modelBuilder.Entity("Timeline.Entities.UserConfigurationEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<int>("BookmarkVisibility") + .HasColumnType("INTEGER") + .HasColumnName("bookmark_visibility"); + + b.Property<long>("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_config"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<DateTime>("CreateTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("create_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property<DateTime>("LastModified") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("last_modified") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property<string>("Nickname") + .HasColumnType("TEXT") + .HasColumnName("nickname"); + + b.Property<string>("Password") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("password"); + + b.Property<string>("UniqueId") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("unique_id") + .HasDefaultValueSql("lower(hex(randomblob(16)))"); + + b.Property<string>("Username") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("username"); + + b.Property<DateTime>("UsernameChangeTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("username_change_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("Permission") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("permission"); + + b.Property<long>("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_permission"); + }); + + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<long?>("IntroducerId") + .HasColumnType("INTEGER") + .HasColumnName("introducer_id"); + + b.Property<string>("RegisterCode") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("register_code"); + + b.Property<DateTime>("RegisterTime") + .HasColumnType("TEXT") + .HasColumnName("register_time"); + + b.Property<long>("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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<DateTime?>("CreateAt") + .HasColumnType("TEXT") + .HasColumnName("create_at"); + + b.Property<bool>("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property<DateTime?>("ExpireAt") + .HasColumnType("TEXT") + .HasColumnName("expire_at"); + + b.Property<string>("Token") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("token"); + + b.Property<long>("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<long>(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + owner_id = table.Column<long>(type: "INTEGER", nullable: true), + code = table.Column<string>(type: "TEXT", nullable: false), + enabled = table.Column<bool>(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<long>(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + user_id = table.Column<long>(type: "INTEGER", nullable: false), + register_code = table.Column<string>(type: "TEXT", nullable: false), + introducer_id = table.Column<long>(type: "INTEGER", nullable: true), + register_time = table.Column<DateTime>(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<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<string>("Code") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("code"); + + b.Property<bool>("Enabled") + .HasColumnType("INTEGER") + .HasColumnName("enabled"); + + b.Property<long?>("OwnerId") + .HasColumnType("INTEGER") + .HasColumnName("owner_id"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("register_code"); + }); + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => { b.Property<long>("Id") @@ -453,6 +480,39 @@ namespace Timeline.Migrations b.ToTable("user_permission"); }); + modelBuilder.Entity("Timeline.Entities.UserRegisterInfo", b => + { + b.Property<long>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property<long?>("IntroducerId") + .HasColumnType("INTEGER") + .HasColumnName("introducer_id"); + + b.Property<string>("RegisterCode") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("register_code"); + + b.Property<DateTime>("RegisterTime") + .HasColumnType("TEXT") + .HasColumnName("register_time"); + + b.Property<long>("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<long>("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<UserService> logger, DatabaseContext database, IPasswordService passwordService, IUserTokenService userTokenService, IClock clock)
+ public UserService(ILogger<UserService> 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<Page<UserEntity>> GetUsersV2Async(int page, int pageSize) |