From 9c874edbb35c87448ce91c142b127b450879e6b4 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 10 Apr 2022 21:51:48 +0800 Subject: ... --- BackEnd/Timeline.Tests/packages.lock.json | 26 +- .../Controllers/TimelineBookmark1Controller.cs | 23 + BackEnd/Timeline/Entities/DatabaseContext.cs | 2 + .../Timeline/Entities/UserConfigurationEntity.cs | 23 + .../20220410135026_AddUserConfig.Designer.cs | 661 +++++++++++++++++++++ .../Migrations/20220410135026_AddUserConfig.cs | 43 ++ .../Migrations/DatabaseContextModelSnapshot.cs | 33 + .../Services/Api/ITimelineBookmarkService1.cs | 6 + .../Services/Api/TimelineBookmarkService1.cs | 37 ++ BackEnd/Timeline/Timeline.csproj | 2 +- BackEnd/Timeline/packages.lock.json | 26 +- 11 files changed, 855 insertions(+), 27 deletions(-) create mode 100644 BackEnd/Timeline/Controllers/TimelineBookmark1Controller.cs create mode 100644 BackEnd/Timeline/Entities/UserConfigurationEntity.cs create mode 100644 BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.Designer.cs create mode 100644 BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.cs (limited to 'BackEnd') diff --git a/BackEnd/Timeline.Tests/packages.lock.json b/BackEnd/Timeline.Tests/packages.lock.json index 5c71f593..aef482ad 100644 --- a/BackEnd/Timeline.Tests/packages.lock.json +++ b/BackEnd/Timeline.Tests/packages.lock.json @@ -398,24 +398,24 @@ }, "Microsoft.IdentityModel.JsonWebTokens": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "FJtXVXvjoza64VPFOPBxqnhe0yyQ5B/7A09+RpTXIzowr5+A4xcX42patsLrNGmFUvXZAHhS2u/6ojTzhYatpg==", + "resolved": "6.17.0", + "contentHash": "I3cSVE185qF3a222/iQIdmBFhrhZBtz7wZ1RUUbMuHC1un79XCI7vggbWdmbqIttFcUoeziemadO6t+3FLjcSA==", "dependencies": { - "Microsoft.IdentityModel.Tokens": "6.16.0" + "Microsoft.IdentityModel.Tokens": "6.17.0" } }, "Microsoft.IdentityModel.Logging": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "Fuo5SpYUpFRw90hBM3PDA1uQsrHmbIaxvwkldJcfi0O51gz/qjSFMe8136NFRoKA3NxZZScpz/47oFkRU2WA/A==" + "resolved": "6.17.0", + "contentHash": "Ix6/CMLDoo939NDf1ARDuGK6YERY7pAX9WYbfwb4gZqx7r52unMFIykJk+zlEBX7jjtbDz/0uzikQFvheV9KsQ==" }, "Microsoft.IdentityModel.Tokens": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "dL7r4bdRbDG0RmyYGw9cpO/pA3GVaxV+lI1ConYuQuRiAxd1ONFlxHue1o8wR8+lEB972cekzfj45WSNaq3+xA==", + "resolved": "6.17.0", + "contentHash": "mhOe+d9BQg5U45TkTCyXAFOjl7RvwaFj6v9qo8b+WFolkuGsfjSFfQ+WI9D3ho9sD/fK75gvL4JptmjLzyUPkw==", "dependencies": { "Microsoft.CSharp": "4.5.0", - "Microsoft.IdentityModel.Logging": "6.16.0", + "Microsoft.IdentityModel.Logging": "6.17.0", "System.Security.Cryptography.Cng": "4.5.0" } }, @@ -1033,11 +1033,11 @@ }, "System.IdentityModel.Tokens.Jwt": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "QnZUawkmLkzEhwgvlqcm2YNAoRgz27zVY+2LzMBMWMcfFhl2Sv8aavZOeuFMofmYJsST9h7BilOn7MzFSUMihQ==", + "resolved": "6.17.0", + "contentHash": "G3rY4WLr54Mo+97+AEq0ANpiKvW7E8Qu5bKWfVMa7rkyJtvrOxUqp/OLqrGw/6JDbD5GlxnAtFKukGteUuB0rQ==", "dependencies": { - "Microsoft.IdentityModel.JsonWebTokens": "6.16.0", - "Microsoft.IdentityModel.Tokens": "6.16.0" + "Microsoft.IdentityModel.JsonWebTokens": "6.17.0", + "Microsoft.IdentityModel.Tokens": "6.17.0" } }, "System.IO": { @@ -1762,7 +1762,7 @@ "Microsoft.EntityFrameworkCore.Sqlite": "6.0.3", "NSwag.AspNetCore": "13.15.10", "SixLabors.ImageSharp": "2.1.0", - "System.IdentityModel.Tokens.Jwt": "6.16.0" + "System.IdentityModel.Tokens.Jwt": "6.17.0" } } } diff --git a/BackEnd/Timeline/Controllers/TimelineBookmark1Controller.cs b/BackEnd/Timeline/Controllers/TimelineBookmark1Controller.cs new file mode 100644 index 00000000..1dfc1715 --- /dev/null +++ b/BackEnd/Timeline/Controllers/TimelineBookmark1Controller.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Timeline.Models; + +namespace Timeline.Controllers +{ + [ApiController] + [Route("users/{username}/bookmarks")] + public class TimelineBookmark1Controller : MyControllerBase + { + public TimelineBookmark1Controller() + { + } + + [ProducesResponseType(200)] + [ProducesResponseType(403)] + public async Task> ListAsync([FromRoute] string username) + { + throw new NotImplementedException(); + } + } +} diff --git a/BackEnd/Timeline/Entities/DatabaseContext.cs b/BackEnd/Timeline/Entities/DatabaseContext.cs index bb078b77..cb776e72 100644 --- a/BackEnd/Timeline/Entities/DatabaseContext.cs +++ b/BackEnd/Timeline/Entities/DatabaseContext.cs @@ -34,6 +34,8 @@ namespace Timeline.Entities public DbSet HighlightTimelines { get; set; } = default!; public DbSet BookmarkTimelines { get; set; } = default!; + public DbSet UserConfigurations { get; set; } = default!; + public DbSet JwtToken { get; set; } = default!; public DbSet UserTokens { get; set; } = default!; public DbSet Data { get; set; } = default!; diff --git a/BackEnd/Timeline/Entities/UserConfigurationEntity.cs b/BackEnd/Timeline/Entities/UserConfigurationEntity.cs new file mode 100644 index 00000000..fb06e604 --- /dev/null +++ b/BackEnd/Timeline/Entities/UserConfigurationEntity.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Timeline.Models; + +namespace Timeline.Entities +{ + [Table("user_config")] + public class UserConfigurationEntity + { + [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("bookmark_visibility")] + public TimelineVisibility BookmarkVisibility { get; set; } + } +} diff --git a/BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.Designer.cs b/BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.Designer.cs new file mode 100644 index 00000000..536a1e9b --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.Designer.cs @@ -0,0 +1,661 @@ +// +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("20220410135026_AddUserConfig")] + partial class AddUserConfig + { + 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.UserConfigurationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("BookmarkVisibility") + .HasColumnType("INTEGER") + .HasColumnName("bookmark_visibility"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_config"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("create_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("LastModified") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("last_modified") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("Nickname") + .HasColumnType("TEXT") + .HasColumnName("nickname"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("password"); + + b.Property("UniqueId") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("unique_id") + .HasDefaultValueSql("lower(hex(randomblob(16)))"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("username"); + + b.Property("UsernameChangeTime") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnName("username_change_time") + .HasDefaultValueSql("datetime('now', 'utc')"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(0L) + .HasColumnName("version"); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Timeline.Entities.UserPermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("Permission") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("permission"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_permission"); + }); + + modelBuilder.Entity("Timeline.Entities.UserTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("CreateAt") + .HasColumnType("TEXT") + .HasColumnName("create_at"); + + b.Property("Deleted") + .HasColumnType("INTEGER") + .HasColumnName("deleted"); + + b.Property("ExpireAt") + .HasColumnType("TEXT") + .HasColumnName("expire_at"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("token"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("user_token"); + }); + + modelBuilder.Entity("Timeline.Entities.BookmarkTimelineEntity", b => + { + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany() + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Timeline"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Timeline.Entities.HighlightTimelineEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Operator") + .WithMany() + .HasForeignKey("OperatorId"); + + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany() + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Operator"); + + b.Navigation("Timeline"); + }); + + modelBuilder.Entity("Timeline.Entities.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.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/20220410135026_AddUserConfig.cs b/BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.cs new file mode 100644 index 00000000..7f977127 --- /dev/null +++ b/BackEnd/Timeline/Migrations/20220410135026_AddUserConfig.cs @@ -0,0 +1,43 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Timeline.Migrations +{ + public partial class AddUserConfig : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "user_config", + columns: table => new + { + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + user_id = table.Column(type: "INTEGER", nullable: false), + bookmark_visibility = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_user_config", x => x.id); + table.ForeignKey( + name: "FK_user_config_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_user_config_user_id", + table: "user_config", + column: "user_id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "user_config"); + } + } +} diff --git a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs index f510d983..01a134d2 100644 --- a/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs +++ b/BackEnd/Timeline/Migrations/DatabaseContextModelSnapshot.cs @@ -348,6 +348,28 @@ namespace Timeline.Migrations b.ToTable("user_avatars"); }); + modelBuilder.Entity("Timeline.Entities.UserConfigurationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasColumnName("id"); + + b.Property("BookmarkVisibility") + .HasColumnType("INTEGER") + .HasColumnName("bookmark_visibility"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("user_config"); + }); + modelBuilder.Entity("Timeline.Entities.UserEntity", b => { b.Property("Id") @@ -574,6 +596,17 @@ namespace Timeline.Migrations 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") diff --git a/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs b/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs index 82e4dc48..f9ee4c15 100644 --- a/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs +++ b/BackEnd/Timeline/Services/Api/ITimelineBookmarkService1.cs @@ -15,6 +15,12 @@ namespace Timeline.Services.Api Task DeleteBookmarkAsync(long userId, long timelineId); Task MoveBookmarkAsync(long userId, long timelineId, int position); + + Task GetBookmarkVisibilityAsync(long userId); + + Task SetBookmarkVisibilityAsync(long userId, TimelineVisibility visibility); + + Task CanReadBookmarksAsync(long userId, long? visitorId); } } diff --git a/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs b/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs index 9dd3c0d7..f047a12d 100644 --- a/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs +++ b/BackEnd/Timeline/Services/Api/TimelineBookmarkService1.cs @@ -69,6 +69,14 @@ namespace Timeline.Services.Api return new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, position.Value); } + public async Task CanReadBookmarksAsync(long userId, long? visitorId) + { + var visibility = await GetBookmarkVisibilityAsync(userId); + if (visibility == TimelineVisibility.Public) return true; + else if (visibility == TimelineVisibility.Register) return visitorId is not null; + else return userId == visitorId; + } + public async Task DeleteBookmarkAsync(long userId, long timelineId) { var entity = await _databaseContext.BookmarkTimelines.Where(b => b.UserId == userId && b.TimelineId == timelineId).SingleOrDefaultAsync(); @@ -118,6 +126,14 @@ namespace Timeline.Services.Api return new Page(page, pageSize, totalCount, items); } + public async Task GetBookmarkVisibilityAsync(long userId) + { + await _userService.CheckUserExistenceAsync(userId); + var configEntity = await _databaseContext.UserConfigurations.Where(c => c.UserId == userId).SingleOrDefaultAsync(); + if (configEntity is null) return TimelineVisibility.Private; + return configEntity.BookmarkVisibility; + } + public async Task MoveBookmarkAsync(long userId, long timelineId, int position) { var user = await _userService.GetUserAsync(userId); @@ -162,5 +178,26 @@ namespace Timeline.Services.Api return new TimelineBookmark(user.Username, timeline.Name is null ? "self" : timeline.Name, (int)entity.Rank); } + + public async Task SetBookmarkVisibilityAsync(long userId, TimelineVisibility visibility) + { + await _userService.CheckUserExistenceAsync(userId); + var configEntity = await _databaseContext.UserConfigurations.Where(c => c.UserId == userId).SingleOrDefaultAsync(); + if (configEntity is null) + { + configEntity = new UserConfigurationEntity + { + UserId = userId, + BookmarkVisibility = visibility + }; + _databaseContext.UserConfigurations.Add(configEntity); + } + else + { + configEntity.BookmarkVisibility = visibility; + } + + await _databaseContext.SaveChangesAsync(); + } } } diff --git a/BackEnd/Timeline/Timeline.csproj b/BackEnd/Timeline/Timeline.csproj index 26e562e8..ee14de25 100644 --- a/BackEnd/Timeline/Timeline.csproj +++ b/BackEnd/Timeline/Timeline.csproj @@ -47,7 +47,7 @@ - + diff --git a/BackEnd/Timeline/packages.lock.json b/BackEnd/Timeline/packages.lock.json index 258d3e8d..3212d657 100644 --- a/BackEnd/Timeline/packages.lock.json +++ b/BackEnd/Timeline/packages.lock.json @@ -103,12 +103,12 @@ }, "System.IdentityModel.Tokens.Jwt": { "type": "Direct", - "requested": "[6.16.0, )", - "resolved": "6.16.0", - "contentHash": "QnZUawkmLkzEhwgvlqcm2YNAoRgz27zVY+2LzMBMWMcfFhl2Sv8aavZOeuFMofmYJsST9h7BilOn7MzFSUMihQ==", + "requested": "[6.17.0, )", + "resolved": "6.17.0", + "contentHash": "G3rY4WLr54Mo+97+AEq0ANpiKvW7E8Qu5bKWfVMa7rkyJtvrOxUqp/OLqrGw/6JDbD5GlxnAtFKukGteUuB0rQ==", "dependencies": { - "Microsoft.IdentityModel.JsonWebTokens": "6.16.0", - "Microsoft.IdentityModel.Tokens": "6.16.0" + "Microsoft.IdentityModel.JsonWebTokens": "6.17.0", + "Microsoft.IdentityModel.Tokens": "6.17.0" } }, "Humanizer.Core": { @@ -288,24 +288,24 @@ }, "Microsoft.IdentityModel.JsonWebTokens": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "FJtXVXvjoza64VPFOPBxqnhe0yyQ5B/7A09+RpTXIzowr5+A4xcX42patsLrNGmFUvXZAHhS2u/6ojTzhYatpg==", + "resolved": "6.17.0", + "contentHash": "I3cSVE185qF3a222/iQIdmBFhrhZBtz7wZ1RUUbMuHC1un79XCI7vggbWdmbqIttFcUoeziemadO6t+3FLjcSA==", "dependencies": { - "Microsoft.IdentityModel.Tokens": "6.16.0" + "Microsoft.IdentityModel.Tokens": "6.17.0" } }, "Microsoft.IdentityModel.Logging": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "Fuo5SpYUpFRw90hBM3PDA1uQsrHmbIaxvwkldJcfi0O51gz/qjSFMe8136NFRoKA3NxZZScpz/47oFkRU2WA/A==" + "resolved": "6.17.0", + "contentHash": "Ix6/CMLDoo939NDf1ARDuGK6YERY7pAX9WYbfwb4gZqx7r52unMFIykJk+zlEBX7jjtbDz/0uzikQFvheV9KsQ==" }, "Microsoft.IdentityModel.Tokens": { "type": "Transitive", - "resolved": "6.16.0", - "contentHash": "dL7r4bdRbDG0RmyYGw9cpO/pA3GVaxV+lI1ConYuQuRiAxd1ONFlxHue1o8wR8+lEB972cekzfj45WSNaq3+xA==", + "resolved": "6.17.0", + "contentHash": "mhOe+d9BQg5U45TkTCyXAFOjl7RvwaFj6v9qo8b+WFolkuGsfjSFfQ+WI9D3ho9sD/fK75gvL4JptmjLzyUPkw==", "dependencies": { "Microsoft.CSharp": "4.5.0", - "Microsoft.IdentityModel.Logging": "6.16.0", + "Microsoft.IdentityModel.Logging": "6.17.0", "System.Security.Cryptography.Cng": "4.5.0" } }, -- cgit v1.2.3