From 3d6c9fd916e18c99b3a5497b8313672680571b5e Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 9 Mar 2022 21:21:15 +0800 Subject: Add user token entity in preparation for refactor of tokens. --- BackEnd/Timeline/Entities/DatabaseContext.cs | 2 + BackEnd/Timeline/Entities/UserTokenEntity.cs | 28 + .../20220309132001_AddUserTokenTable.Designer.cs | 624 ++++++++++ .../Migrations/20220309132001_AddUserTokenTable.cs | 52 + .../Migrations/DatabaseContextModelSnapshot.cs | 1198 ++++++++++---------- .../Services/Token/DatabaseUserTokenHandler.cs | 0 .../Timeline/Services/Token/IUserTokenHandler.cs | 5 +- .../Timeline/Services/Token/UserTokenHandler.cs | 11 +- .../Timeline/Services/Token/UserTokenManager.cs | 4 +- BackEnd/Timeline/appsettings.json | 4 +- 10 files changed, 1341 insertions(+), 587 deletions(-) create mode 100644 BackEnd/Timeline/Entities/UserTokenEntity.cs create mode 100644 BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.Designer.cs create mode 100644 BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.cs create mode 100644 BackEnd/Timeline/Services/Token/DatabaseUserTokenHandler.cs diff --git a/BackEnd/Timeline/Entities/DatabaseContext.cs b/BackEnd/Timeline/Entities/DatabaseContext.cs index 8ccdabb5..bb078b77 100644 --- a/BackEnd/Timeline/Entities/DatabaseContext.cs +++ b/BackEnd/Timeline/Entities/DatabaseContext.cs @@ -19,6 +19,7 @@ namespace Timeline.Entities modelBuilder.Entity().Property(e => e.LastModified).HasDefaultValueSql("datetime('now', 'utc')"); modelBuilder.Entity().HasIndex(e => e.Tag).IsUnique(); modelBuilder.Entity().Property(e => e.UniqueId).HasDefaultValueSql("lower(hex(randomblob(16)))"); + modelBuilder.Entity().HasIndex(e => e.Token).IsUnique(); modelBuilder.ApplyUtcDateTimeConverter(); } @@ -34,6 +35,7 @@ namespace Timeline.Entities public DbSet BookmarkTimelines { get; set; } = default!; public DbSet JwtToken { get; set; } = default!; + public DbSet UserTokens { get; set; } = default!; public DbSet Data { get; set; } = default!; public DbSet Migrations { get; set; } = default!; diff --git a/BackEnd/Timeline/Entities/UserTokenEntity.cs b/BackEnd/Timeline/Entities/UserTokenEntity.cs new file mode 100644 index 00000000..0d8bce7d --- /dev/null +++ b/BackEnd/Timeline/Entities/UserTokenEntity.cs @@ -0,0 +1,28 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Timeline.Entities +{ + [Table("user_token")] + public class UserTokenEntity + { + [Column("id"), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + [Column("user_id")] + public long UserId { get; set; } + + [ForeignKey(nameof(UserId))] + public UserEntity User { get; set; } = default!; + + [Column("token")] + public string Token { get; set; } = default!; + + [Column("expire_at")] + public DateTime? ExpireAt { get; set; } + + [Column("create_at")] + public DateTime? CreateAt { get; set; } + } +} diff --git a/BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.Designer.cs b/BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.Designer.cs new file mode 100644 index 00000000..f31eda83 --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.Designer.cs @@ -0,0 +1,624 @@ +// +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("20220309132001_AddUserTokenTable")] + partial class AddUserTokenTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.3"); + + 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.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.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.UserTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateAt") + .HasColumnType("TEXT") + .HasColumnName("create_at"); + + 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.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.UserPermissionEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("Permissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + 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/20220309132001_AddUserTokenTable.cs b/BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.cs new file mode 100644 index 00000000..02cb5a14 --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220309132001_AddUserTokenTable.cs @@ -0,0 +1,52 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Timeline.Migrations +{ + public partial class AddUserTokenTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "user_token", + columns: table => new + { + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + user_id = table.Column(type: "INTEGER", nullable: false), + token = table.Column(type: "TEXT", nullable: false), + expire_at = table.Column(type: "TEXT", nullable: true), + create_at = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_user_token", x => x.id); + table.ForeignKey( + name: "FK_user_token_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_user_token_token", + table: "user_token", + column: "token", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_user_token_user_id", + table: "user_token", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "user_token"); + } + } +} diff --git a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs index 26a77e8a..f1e9b6ab 100644 --- a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs +++ b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs @@ -1,576 +1,622 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Timeline.Entities; - -namespace Timeline.Migrations -{ - [DbContext(typeof(DatabaseContext))] - partial class DatabaseContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.0"); - - 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.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.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.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.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.UserPermissionEntity", b => - { - b.HasOne("Timeline.Entities.UserEntity", "User") - .WithMany("Permissions") - .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 - } - } -} +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Timeline.Entities; + +#nullable disable + +namespace Timeline.Migrations +{ + [DbContext(typeof(DatabaseContext))] + partial class DatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.3"); + + 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.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.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.UserTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateAt") + .HasColumnType("TEXT") + .HasColumnName("create_at"); + + 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.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.UserPermissionEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("Permissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + 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/Services/Token/DatabaseUserTokenHandler.cs b/BackEnd/Timeline/Services/Token/DatabaseUserTokenHandler.cs new file mode 100644 index 00000000..e69de29b diff --git a/BackEnd/Timeline/Services/Token/IUserTokenHandler.cs b/BackEnd/Timeline/Services/Token/IUserTokenHandler.cs index d9788909..62e01de5 100644 --- a/BackEnd/Timeline/Services/Token/IUserTokenHandler.cs +++ b/BackEnd/Timeline/Services/Token/IUserTokenHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; namespace Timeline.Services.Token { @@ -10,7 +11,7 @@ namespace Timeline.Services.Token /// The info to generate token. /// Return the generated token. /// Thrown when is null. - string GenerateToken(UserTokenInfo tokenInfo); + Task GenerateTokenAsync(UserTokenInfo tokenInfo); /// /// Verify a token and get the saved info. Do not validate lifetime!!! @@ -23,6 +24,6 @@ namespace Timeline.Services.Token /// If this method throw , it usually means the token is not created by this service. /// Do not check expire time in this method, only check whether it is present. /// - UserTokenInfo VerifyToken(string token); + Task ValidateTokenAsync(string token); } } diff --git a/BackEnd/Timeline/Services/Token/UserTokenHandler.cs b/BackEnd/Timeline/Services/Token/UserTokenHandler.cs index c1633f4a..03b07b53 100644 --- a/BackEnd/Timeline/Services/Token/UserTokenHandler.cs +++ b/BackEnd/Timeline/Services/Token/UserTokenHandler.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; +using System.Threading.Tasks; using Timeline.Configs; using Timeline.Entities; @@ -35,7 +36,7 @@ namespace Timeline.Services.Token _tokenSecurityKey = new SymmetricSecurityKey(key); } - public string GenerateToken(UserTokenInfo tokenInfo) + public Task GenerateTokenAsync(UserTokenInfo tokenInfo) { if (tokenInfo == null) throw new ArgumentNullException(nameof(tokenInfo)); @@ -60,11 +61,11 @@ namespace Timeline.Services.Token var token = _tokenHandler.CreateToken(tokenDescriptor); var tokenString = _tokenHandler.WriteToken(token); - return tokenString; + return Task.FromResult(tokenString); } - public UserTokenInfo VerifyToken(string token) + public Task ValidateTokenAsync(string token) { if (token == null) throw new ArgumentNullException(nameof(token)); @@ -100,12 +101,12 @@ namespace Timeline.Services.Token if (exp is null) throw new JwtUserTokenBadFormatException(token, JwtUserTokenBadFormatException.ErrorKind.NoExp); - return new UserTokenInfo + return Task.FromResult(new UserTokenInfo { Id = id, Version = version, ExpireAt = EpochTime.DateTime(exp.Value) - }; + }); } catch (Exception e) when (e is SecurityTokenException || e is ArgumentException) { diff --git a/BackEnd/Timeline/Services/Token/UserTokenManager.cs b/BackEnd/Timeline/Services/Token/UserTokenManager.cs index 7ccdfe0a..bdb229f0 100644 --- a/BackEnd/Timeline/Services/Token/UserTokenManager.cs +++ b/BackEnd/Timeline/Services/Token/UserTokenManager.cs @@ -38,7 +38,7 @@ namespace Timeline.Services.Token var userId = await _userService.VerifyCredential(username, password); var user = await _userService.GetUserAsync(userId); - var token = _userTokenService.GenerateToken(new UserTokenInfo + var token = await _userTokenService.GenerateTokenAsync(new UserTokenInfo { Id = user.Id, Version = user.Version, @@ -60,7 +60,7 @@ namespace Timeline.Services.Token try { - tokenInfo = _userTokenService.VerifyToken(token); + tokenInfo = await _userTokenService.ValidateTokenAsync(token); } catch (UserTokenBadFormatException e) { diff --git a/BackEnd/Timeline/appsettings.json b/BackEnd/Timeline/appsettings.json index 5098b4ae..81c01bf6 100644 --- a/BackEnd/Timeline/appsettings.json +++ b/BackEnd/Timeline/appsettings.json @@ -5,7 +5,7 @@ } }, "Jwt": { - "Issuer": "timeline.crupest.life", - "Audience": "timeline.crupest.life" + "Issuer": "crupest.space", + "Audience": "crupest.space" } } -- cgit v1.2.3