aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BackEnd/Timeline.Tests/Helpers/TestDatabase.cs7
-rw-r--r--BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs9
-rw-r--r--BackEnd/Timeline.Tests/ServiceTests/ServiceTestBase.cs67
-rw-r--r--BackEnd/Timeline.Tests/ServiceTests/User/RegisterCode/RegisterCodeServiceTest.cs42
-rw-r--r--BackEnd/Timeline.Tests/Services/ServiceTestBase.cs10
-rw-r--r--BackEnd/Timeline.Tests/Timeline.Tests.csproj6
-rw-r--r--BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.Designer.cs747
-rw-r--r--BackEnd/Timeline/Migrations/20220417152839_AddRegisterCode.cs84
-rw-r--r--BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs88
-rw-r--r--BackEnd/Timeline/Services/User/UserService.cs15
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)