From 7883590a7a0c5c5c4e5cff6290e26c64e1258a25 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 27 Nov 2020 00:07:09 +0800 Subject: refactor: ... --- BackEnd/Timeline/Models/Http/Timeline.cs | 45 ++++--- BackEnd/Timeline/Models/Http/TimelineController.cs | 21 +++- BackEnd/Timeline/Models/Http/TokenController.cs | 20 ++-- BackEnd/Timeline/Models/Http/User.cs | 105 +++++++++++++++++ BackEnd/Timeline/Models/Http/UserController.cs | 18 +-- BackEnd/Timeline/Models/Http/UserInfo.cs | 105 ----------------- BackEnd/Timeline/Models/Timeline.cs | 98 ---------------- BackEnd/Timeline/Models/TimelineInfo.cs | 130 +++++++++++++++++++++ BackEnd/Timeline/Models/User.cs | 21 ---- BackEnd/Timeline/Models/UserInfo.cs | 48 ++++++++ 10 files changed, 339 insertions(+), 272 deletions(-) create mode 100644 BackEnd/Timeline/Models/Http/User.cs delete mode 100644 BackEnd/Timeline/Models/Http/UserInfo.cs delete mode 100644 BackEnd/Timeline/Models/Timeline.cs create mode 100644 BackEnd/Timeline/Models/TimelineInfo.cs delete mode 100644 BackEnd/Timeline/Models/User.cs create mode 100644 BackEnd/Timeline/Models/UserInfo.cs (limited to 'BackEnd/Timeline/Models') diff --git a/BackEnd/Timeline/Models/Http/Timeline.cs b/BackEnd/Timeline/Models/Http/Timeline.cs index a81b33f5..8e3831e1 100644 --- a/BackEnd/Timeline/Models/Http/Timeline.cs +++ b/BackEnd/Timeline/Models/Http/Timeline.cs @@ -11,7 +11,7 @@ namespace Timeline.Models.Http /// /// Info of post content. /// - public class TimelinePostContentInfo + public class HttpTimelinePostContent { /// /// Type of the post content. @@ -34,7 +34,7 @@ namespace Timeline.Models.Http /// /// Info of a post. /// - public class TimelinePostInfo + public class HttpTimelinePost { /// /// Post id. @@ -43,7 +43,7 @@ namespace Timeline.Models.Http /// /// Content of the post. May be null if post is deleted. /// - public TimelinePostContentInfo? Content { get; set; } + public HttpTimelinePostContent? Content { get; set; } /// /// True if post is deleted. /// @@ -55,7 +55,7 @@ namespace Timeline.Models.Http /// /// The author. May be null if the user has been deleted. /// - public UserInfo? Author { get; set; } = default!; + public HttpUser? Author { get; set; } = default!; /// /// Last updated time. /// @@ -65,7 +65,7 @@ namespace Timeline.Models.Http /// /// Info of a timeline. /// - public class TimelineInfo + public class HttpTimeline { /// /// Unique id. @@ -90,7 +90,7 @@ namespace Timeline.Models.Http /// /// Owner of the timeline. /// - public UserInfo Owner { get; set; } = default!; + public HttpUser Owner { get; set; } = default!; /// /// Visibility of the timeline. /// @@ -99,7 +99,7 @@ namespace Timeline.Models.Http /// /// Members of timeline. /// - public List Members { get; set; } = default!; + public List Members { get; set; } = default!; #pragma warning restore CA2227 // Collection properties should be read only /// /// Create time of timeline. @@ -114,14 +114,14 @@ namespace Timeline.Models.Http /// /// Related links. /// - public TimelineInfoLinks _links { get; set; } = default!; + public HttpTimelineLinks _links { get; set; } = default!; #pragma warning restore CA1707 // Identifiers should not contain underscores } /// /// Related links for timeline. /// - public class TimelineInfoLinks + public class HttpTimelineLinks { /// /// Self. @@ -133,23 +133,23 @@ namespace Timeline.Models.Http public string Posts { get; set; } = default!; } - public class TimelineInfoLinksValueResolver : IValueResolver + public class HttpTimelineLinksValueResolver : IValueResolver { private readonly IActionContextAccessor _actionContextAccessor; private readonly IUrlHelperFactory _urlHelperFactory; - public TimelineInfoLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) + public HttpTimelineLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) { _actionContextAccessor = actionContextAccessor; _urlHelperFactory = urlHelperFactory; } - public TimelineInfoLinks Resolve(Timeline source, TimelineInfo destination, TimelineInfoLinks destMember, ResolutionContext context) + public HttpTimelineLinks Resolve(TimelineInfo source, HttpTimeline destination, HttpTimelineLinks destMember, ResolutionContext context) { var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); - return new TimelineInfoLinks + return new HttpTimelineLinks { Self = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name }), Posts = urlHelper.ActionLink(nameof(TimelineController.PostListGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { source.Name }) @@ -157,18 +157,18 @@ namespace Timeline.Models.Http } } - public class TimelinePostContentResolver : IValueResolver + public class HttpTimelinePostContentResolver : IValueResolver { private readonly IActionContextAccessor _actionContextAccessor; private readonly IUrlHelperFactory _urlHelperFactory; - public TimelinePostContentResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) + public HttpTimelinePostContentResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) { _actionContextAccessor = actionContextAccessor; _urlHelperFactory = urlHelperFactory; } - public TimelinePostContentInfo? Resolve(TimelinePost source, TimelinePostInfo destination, TimelinePostContentInfo? destMember, ResolutionContext context) + public HttpTimelinePostContent? Resolve(TimelinePostInfo source, HttpTimelinePost destination, HttpTimelinePostContent? destMember, ResolutionContext context) { var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); @@ -182,7 +182,7 @@ namespace Timeline.Models.Http if (sourceContent is TextTimelinePostContent textContent) { - return new TimelinePostContentInfo + return new HttpTimelinePostContent { Type = TimelinePostContentTypes.Text, Text = textContent.Text @@ -190,7 +190,7 @@ namespace Timeline.Models.Http } else if (sourceContent is ImageTimelinePostContent imageContent) { - return new TimelinePostContentInfo + return new HttpTimelinePostContent { Type = TimelinePostContentTypes.Image, Url = urlHelper.ActionLink( @@ -207,13 +207,12 @@ namespace Timeline.Models.Http } } - public class TimelineInfoAutoMapperProfile : Profile + public class HttpTimelineAutoMapperProfile : Profile { - public TimelineInfoAutoMapperProfile() + public HttpTimelineAutoMapperProfile() { - CreateMap().ForMember(u => u._links, opt => opt.MapFrom()); - CreateMap().ForMember(p => p.Content, opt => opt.MapFrom()); - CreateMap(); + CreateMap().ForMember(u => u._links, opt => opt.MapFrom()); + CreateMap().ForMember(p => p.Content, opt => opt.MapFrom()); } } } diff --git a/BackEnd/Timeline/Models/Http/TimelineController.cs b/BackEnd/Timeline/Models/Http/TimelineController.cs index 7bd141ed..42a926fd 100644 --- a/BackEnd/Timeline/Models/Http/TimelineController.cs +++ b/BackEnd/Timeline/Models/Http/TimelineController.cs @@ -1,4 +1,5 @@ -using System; +using AutoMapper; +using System; using System.ComponentModel.DataAnnotations; using Timeline.Models.Validation; @@ -7,7 +8,7 @@ namespace Timeline.Models.Http /// /// Content of post create request. /// - public class TimelinePostCreateRequestContent + public class HttpTimelinePostCreateRequestContent { /// /// Type of post content. @@ -24,13 +25,13 @@ namespace Timeline.Models.Http public string? Data { get; set; } } - public class TimelinePostCreateRequest + public class HttpTimelinePostCreateRequest { /// /// Content of the new post. /// [Required] - public TimelinePostCreateRequestContent Content { get; set; } = default!; + public HttpTimelinePostCreateRequestContent Content { get; set; } = default!; /// /// Time of the post. If not set, current time will be used. @@ -54,7 +55,7 @@ namespace Timeline.Models.Http /// /// Patch timeline request model. /// - public class TimelinePatchRequest + public class HttpTimelinePatchRequest { /// /// New title. Null for not change. @@ -75,7 +76,7 @@ namespace Timeline.Models.Http /// /// Change timeline name request model. /// - public class TimelineChangeNameRequest + public class HttpTimelineChangeNameRequest { /// /// Old name of timeline. @@ -90,4 +91,12 @@ namespace Timeline.Models.Http [TimelineName] public string NewName { get; set; } = default!; } + + public class HttpTimelineControllerAutoMapperProfile : Profile + { + public HttpTimelineControllerAutoMapperProfile() + { + CreateMap(); + } + } } diff --git a/BackEnd/Timeline/Models/Http/TokenController.cs b/BackEnd/Timeline/Models/Http/TokenController.cs index a42c44e5..a5cbba14 100644 --- a/BackEnd/Timeline/Models/Http/TokenController.cs +++ b/BackEnd/Timeline/Models/Http/TokenController.cs @@ -4,9 +4,9 @@ using Timeline.Controllers; namespace Timeline.Models.Http { /// - /// Request model for . + /// Request model for . /// - public class CreateTokenRequest + public class HttpCreateTokenRequest { /// /// The username. @@ -24,9 +24,9 @@ namespace Timeline.Models.Http } /// - /// Response model for . + /// Response model for . /// - public class CreateTokenResponse + public class HttpCreateTokenResponse { /// /// The token created. @@ -35,13 +35,13 @@ namespace Timeline.Models.Http /// /// The user owning the token. /// - public UserInfo User { get; set; } = default!; + public HttpUser User { get; set; } = default!; } /// - /// Request model for . + /// Request model for . /// - public class VerifyTokenRequest + public class HttpVerifyTokenRequest { /// /// The token to verify. @@ -50,13 +50,13 @@ namespace Timeline.Models.Http } /// - /// Response model for . + /// Response model for . /// - public class VerifyTokenResponse + public class HttpVerifyTokenResponse { /// /// The user owning the token. /// - public UserInfo User { get; set; } = default!; + public HttpUser User { get; set; } = default!; } } diff --git a/BackEnd/Timeline/Models/Http/User.cs b/BackEnd/Timeline/Models/Http/User.cs new file mode 100644 index 00000000..bdb40b9f --- /dev/null +++ b/BackEnd/Timeline/Models/Http/User.cs @@ -0,0 +1,105 @@ +using AutoMapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.Routing; +using System.Collections.Generic; +using Timeline.Controllers; +using Timeline.Services; + +namespace Timeline.Models.Http +{ + /// + /// Info of a user. + /// + public class HttpUser + { + /// + /// Unique id. + /// + public string UniqueId { get; set; } = default!; + /// + /// Username. + /// + public string Username { get; set; } = default!; + /// + /// Nickname. + /// + public string Nickname { get; set; } = default!; +#pragma warning disable CA2227 // Collection properties should be read only + /// + /// The permissions of the user. + /// + public List Permissions { get; set; } = default!; +#pragma warning restore CA2227 // Collection properties should be read only +#pragma warning disable CA1707 // Identifiers should not contain underscores + /// + /// Related links. + /// + public HttpUserLinks _links { get; set; } = default!; +#pragma warning restore CA1707 // Identifiers should not contain underscores + } + + /// + /// Related links for user. + /// + public class HttpUserLinks + { + /// + /// Self. + /// + public string Self { get; set; } = default!; + /// + /// Avatar url. + /// + public string Avatar { get; set; } = default!; + /// + /// Personal timeline url. + /// + public string Timeline { get; set; } = default!; + } + + public class HttpUserPermissionsValueConverter : ITypeConverter> + { + public List Convert(UserPermissions source, List destination, ResolutionContext context) + { + return source.ToStringList(); + } + } + + public class HttpUserLinksValueResolver : IValueResolver + { + private readonly IActionContextAccessor _actionContextAccessor; + private readonly IUrlHelperFactory _urlHelperFactory; + + public HttpUserLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) + { + _actionContextAccessor = actionContextAccessor; + _urlHelperFactory = urlHelperFactory; + } + + public HttpUserLinks Resolve(UserInfo source, HttpUser destination, HttpUserLinks destMember, ResolutionContext context) + { + var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); + var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); + + var result = new HttpUserLinks + { + Self = urlHelper.ActionLink(nameof(UserController.Get), nameof(UserController)[0..^nameof(Controller).Length], new { destination.Username }), + Avatar = urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController)[0..^nameof(Controller).Length], new { destination.Username }), + Timeline = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { Name = "@" + destination.Username }) + }; + return result; + } + } + + public class HttpUserAutoMapperProfile : Profile + { + public HttpUserAutoMapperProfile() + { + CreateMap>() + .ConvertUsing(); + CreateMap() + .ForMember(u => u._links, opt => opt.MapFrom()); + } + } +} diff --git a/BackEnd/Timeline/Models/Http/UserController.cs b/BackEnd/Timeline/Models/Http/UserController.cs index 92a63874..1b4d09ec 100644 --- a/BackEnd/Timeline/Models/Http/UserController.cs +++ b/BackEnd/Timeline/Models/Http/UserController.cs @@ -7,9 +7,9 @@ using Timeline.Services; namespace Timeline.Models.Http { /// - /// Request model for . + /// Request model for . /// - public class UserPatchRequest + public class HttpUserPatchRequest { /// /// New username. Null if not change. Need to be administrator. @@ -31,9 +31,9 @@ namespace Timeline.Models.Http } /// - /// Request model for . + /// Request model for . /// - public class CreateUserRequest + public class HttpCreateUserRequest { /// /// Username of the new user. @@ -49,9 +49,9 @@ namespace Timeline.Models.Http } /// - /// Request model for . + /// Request model for . /// - public class ChangePasswordRequest + public class HttpChangePasswordRequest { /// /// Old password. @@ -66,11 +66,11 @@ namespace Timeline.Models.Http public string NewPassword { get; set; } = default!; } - public class UserControllerAutoMapperProfile : Profile + public class HttpUserControllerModelAutoMapperProfile : Profile { - public UserControllerAutoMapperProfile() + public HttpUserControllerModelAutoMapperProfile() { - CreateMap(); + CreateMap(); } } } diff --git a/BackEnd/Timeline/Models/Http/UserInfo.cs b/BackEnd/Timeline/Models/Http/UserInfo.cs deleted file mode 100644 index 0f865172..00000000 --- a/BackEnd/Timeline/Models/Http/UserInfo.cs +++ /dev/null @@ -1,105 +0,0 @@ -using AutoMapper; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Infrastructure; -using Microsoft.AspNetCore.Mvc.Routing; -using System.Collections.Generic; -using Timeline.Controllers; -using Timeline.Services; - -namespace Timeline.Models.Http -{ - /// - /// Info of a user. - /// - public class UserInfo - { - /// - /// Unique id. - /// - public string UniqueId { get; set; } = default!; - /// - /// Username. - /// - public string Username { get; set; } = default!; - /// - /// Nickname. - /// - public string Nickname { get; set; } = default!; -#pragma warning disable CA2227 // Collection properties should be read only - /// - /// The permissions of the user. - /// - public List Permissions { get; set; } = default!; -#pragma warning restore CA2227 // Collection properties should be read only -#pragma warning disable CA1707 // Identifiers should not contain underscores - /// - /// Related links. - /// - public UserInfoLinks _links { get; set; } = default!; -#pragma warning restore CA1707 // Identifiers should not contain underscores - } - - /// - /// Related links for user. - /// - public class UserInfoLinks - { - /// - /// Self. - /// - public string Self { get; set; } = default!; - /// - /// Avatar url. - /// - public string Avatar { get; set; } = default!; - /// - /// Personal timeline url. - /// - public string Timeline { get; set; } = default!; - } - - public class UserPermissionsValueConverter : ITypeConverter> - { - public List Convert(UserPermissions source, List destination, ResolutionContext context) - { - return source.ToStringList(); - } - } - - public class UserInfoLinksValueResolver : IValueResolver - { - private readonly IActionContextAccessor _actionContextAccessor; - private readonly IUrlHelperFactory _urlHelperFactory; - - public UserInfoLinksValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory) - { - _actionContextAccessor = actionContextAccessor; - _urlHelperFactory = urlHelperFactory; - } - - public UserInfoLinks Resolve(User source, UserInfo destination, UserInfoLinks destMember, ResolutionContext context) - { - var actionContext = _actionContextAccessor.AssertActionContextForUrlFill(); - var urlHelper = _urlHelperFactory.GetUrlHelper(actionContext); - - var result = new UserInfoLinks - { - Self = urlHelper.ActionLink(nameof(UserController.Get), nameof(UserController)[0..^nameof(Controller).Length], new { destination.Username }), - Avatar = urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController)[0..^nameof(Controller).Length], new { destination.Username }), - Timeline = urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { Name = "@" + destination.Username }) - }; - return result; - } - } - - public class UserInfoAutoMapperProfile : Profile - { - public UserInfoAutoMapperProfile() - { - CreateMap>() - .ConvertUsing(); - CreateMap() - .ForMember(u => u._links, opt => opt.MapFrom()); - } - } -} diff --git a/BackEnd/Timeline/Models/Timeline.cs b/BackEnd/Timeline/Models/Timeline.cs deleted file mode 100644 index a5987577..00000000 --- a/BackEnd/Timeline/Models/Timeline.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Timeline.Models -{ - public enum TimelineVisibility - { - /// - /// All people including those without accounts. - /// - Public, - /// - /// Only people signed in. - /// - Register, - /// - /// Only member. - /// - Private - } - - public static class TimelinePostContentTypes - { - public const string Text = "text"; - public const string Image = "image"; - } - - public interface ITimelinePostContent - { - public string Type { get; } - } - - public class TextTimelinePostContent : ITimelinePostContent - { - public TextTimelinePostContent(string text) { Text = text; } - - public string Type { get; } = TimelinePostContentTypes.Text; - public string Text { get; set; } - } - - public class ImageTimelinePostContent : ITimelinePostContent - { - public ImageTimelinePostContent(string dataTag) { DataTag = dataTag; } - - public string Type { get; } = TimelinePostContentTypes.Image; - - /// - /// The tag of the data. The tag of the entry in DataManager. Also the etag (not quoted). - /// - public string DataTag { get; set; } - } - - public class TimelinePost - { - public TimelinePost(long id, ITimelinePostContent? content, DateTime time, User? author, DateTime lastUpdated, string timelineName) - { - Id = id; - Content = content; - Time = time; - Author = author; - LastUpdated = lastUpdated; - TimelineName = timelineName; - } - - public long Id { get; set; } - public ITimelinePostContent? Content { get; set; } - public bool Deleted => Content == null; - public DateTime Time { get; set; } - public User? Author { get; set; } - public DateTime LastUpdated { get; set; } - public string TimelineName { get; set; } - } - -#pragma warning disable CA1724 // Type names should not match namespaces - public class Timeline -#pragma warning restore CA1724 // Type names should not match namespaces - { - public string UniqueID { get; set; } = default!; - public string Name { get; set; } = default!; - public DateTime NameLastModified { get; set; } = default!; - public string Title { get; set; } = default!; - public string Description { get; set; } = default!; - public User Owner { get; set; } = default!; - public TimelineVisibility Visibility { get; set; } -#pragma warning disable CA2227 // Collection properties should be read only - public List Members { get; set; } = default!; -#pragma warning restore CA2227 // Collection properties should be read only - public DateTime CreateTime { get; set; } = default!; - public DateTime LastModified { get; set; } = default!; - } - - public class TimelineChangePropertyRequest - { - public string? Title { get; set; } - public string? Description { get; set; } - public TimelineVisibility? Visibility { get; set; } - } -} diff --git a/BackEnd/Timeline/Models/TimelineInfo.cs b/BackEnd/Timeline/Models/TimelineInfo.cs new file mode 100644 index 00000000..440f6b81 --- /dev/null +++ b/BackEnd/Timeline/Models/TimelineInfo.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; + +namespace Timeline.Models +{ + public enum TimelineVisibility + { + /// + /// All people including those without accounts. + /// + Public, + /// + /// Only people signed in. + /// + Register, + /// + /// Only member. + /// + Private + } + + public static class TimelinePostContentTypes + { + public const string Text = "text"; + public const string Image = "image"; + } + + public interface ITimelinePostContent + { + public string Type { get; } + } + + public class TextTimelinePostContent : ITimelinePostContent + { + public TextTimelinePostContent(string text) { Text = text; } + + public string Type { get; } = TimelinePostContentTypes.Text; + public string Text { get; set; } + } + + public class ImageTimelinePostContent : ITimelinePostContent + { + public ImageTimelinePostContent(string dataTag) { DataTag = dataTag; } + + public string Type { get; } = TimelinePostContentTypes.Image; + + /// + /// The tag of the data. The tag of the entry in DataManager. Also the etag (not quoted). + /// + public string DataTag { get; set; } + } + + public record TimelinePostInfo + { + public TimelinePostInfo() + { + + } + + public TimelinePostInfo(long id, ITimelinePostContent? content, DateTime time, UserInfo? author, DateTime lastUpdated, string timelineName) + { + Id = id; + Content = content; + Time = time; + Author = author; + LastUpdated = lastUpdated; + TimelineName = timelineName; + } + + public long Id { get; set; } + public ITimelinePostContent? Content { get; set; } + public bool Deleted => Content == null; + public DateTime Time { get; set; } + public UserInfo? Author { get; set; } + public DateTime LastUpdated { get; set; } + public string TimelineName { get; set; } = default!; + } + + public record TimelineInfo + { + public TimelineInfo() + { + + } + + public TimelineInfo( + string uniqueId, + string name, + DateTime nameLastModified, + string title, + string description, + UserInfo owner, + TimelineVisibility visibility, + List members, + DateTime createTime, + DateTime lastModified) + { + UniqueId = uniqueId; + Name = name; + NameLastModified = nameLastModified; + Title = title; + Description = description; + Owner = owner; + Visibility = visibility; + Members = members; + CreateTime = createTime; + LastModified = lastModified; + } + + public string UniqueId { get; set; } = default!; + public string Name { get; set; } = default!; + public DateTime NameLastModified { get; set; } = default!; + public string Title { get; set; } = default!; + public string Description { get; set; } = default!; + public UserInfo Owner { get; set; } = default!; + public TimelineVisibility Visibility { get; set; } +#pragma warning disable CA2227 // Collection properties should be read only + public List Members { get; set; } = default!; +#pragma warning restore CA2227 // Collection properties should be read only + public DateTime CreateTime { get; set; } = default!; + public DateTime LastModified { get; set; } = default!; + } + + public class TimelineChangePropertyRequest + { + public string? Title { get; set; } + public string? Description { get; set; } + public TimelineVisibility? Visibility { get; set; } + } +} diff --git a/BackEnd/Timeline/Models/User.cs b/BackEnd/Timeline/Models/User.cs deleted file mode 100644 index ae2afe85..00000000 --- a/BackEnd/Timeline/Models/User.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Timeline.Services; - -namespace Timeline.Models -{ - public record User - { - public long Id { get; set; } - public string UniqueId { get; set; } = default!; - - public string Username { get; set; } = default!; - public string Nickname { get; set; } = default!; - - public UserPermissions Permissions { get; set; } = default!; - - public DateTime UsernameChangeTime { get; set; } - public DateTime CreateTime { get; set; } - public DateTime LastModified { get; set; } - public long Version { get; set; } - } -} diff --git a/BackEnd/Timeline/Models/UserInfo.cs b/BackEnd/Timeline/Models/UserInfo.cs new file mode 100644 index 00000000..058cc590 --- /dev/null +++ b/BackEnd/Timeline/Models/UserInfo.cs @@ -0,0 +1,48 @@ +using System; +using Timeline.Services; + +namespace Timeline.Models +{ + public record UserInfo + { + public UserInfo() + { + + } + + public UserInfo( + long id, + string uniqueId, + string username, + string nickname, + UserPermissions permissions, + DateTime usernameChangeTime, + DateTime createTime, + DateTime lastModified, + long version) + { + Id = id; + UniqueId = uniqueId; + Username = username; + Nickname = nickname; + Permissions = permissions; + UsernameChangeTime = usernameChangeTime; + CreateTime = createTime; + LastModified = lastModified; + Version = version; + } + + public long Id { get; set; } + public string UniqueId { get; set; } = default!; + + public string Username { get; set; } = default!; + public string Nickname { get; set; } = default!; + + public UserPermissions Permissions { get; set; } = default!; + + public DateTime UsernameChangeTime { get; set; } + public DateTime CreateTime { get; set; } + public DateTime LastModified { get; set; } + public long Version { get; set; } + } +} -- cgit v1.2.3 From 5e4cdbbfa75ce021dfbfd8e1f2d38370a702285e Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 27 Nov 2020 01:26:23 +0800 Subject: ... --- BackEnd/Timeline.Tests/Helpers/TestDatabase.cs | 2 +- .../Services/HighlightTimelineServiceTest.cs | 35 ++++++++++++++++++---- .../Services/TimelinePostServiceTest.cs | 2 +- .../Timeline.Tests/Services/TimelineServiceTest.cs | 2 +- .../Timeline/Entities/HighlightTimelineEntity.cs | 8 +++-- BackEnd/Timeline/Models/TimelineInfo.cs | 4 +-- BackEnd/Timeline/Models/UserInfo.cs | 2 +- .../Timeline/Services/HighlightTimelineService.cs | 6 ++-- BackEnd/Timeline/Services/UserPermissionService.cs | 33 ++++++++++++++++++-- BackEnd/Timeline/Services/UserService.cs | 6 ++-- 10 files changed, 79 insertions(+), 21 deletions(-) (limited to 'BackEnd/Timeline/Models') diff --git a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs index 74db74aa..a71c2208 100644 --- a/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs +++ b/BackEnd/Timeline.Tests/Helpers/TestDatabase.cs @@ -35,7 +35,7 @@ namespace Timeline.Tests.Helpers if (_createUser) { var passwordService = new PasswordService(); - var userService = new UserService(NullLogger.Instance, context, passwordService, new Clock(), new UserPermissionService(context)); + var userService = new UserService(NullLogger.Instance, context, passwordService, new UserPermissionService(context), new Clock()); var admin = await userService.CreateUser("admin", "adminpw"); await userService.ModifyUser(admin.Id, new ModifyUserParams() { Nickname = "administrator" }); diff --git a/BackEnd/Timeline.Tests/Services/HighlightTimelineServiceTest.cs b/BackEnd/Timeline.Tests/Services/HighlightTimelineServiceTest.cs index a4cd983d..8ba26613 100644 --- a/BackEnd/Timeline.Tests/Services/HighlightTimelineServiceTest.cs +++ b/BackEnd/Timeline.Tests/Services/HighlightTimelineServiceTest.cs @@ -1,18 +1,43 @@ -using Timeline.Services; +using FluentAssertions; +using Microsoft.Extensions.Logging.Abstractions; +using System.Threading.Tasks; +using Timeline.Services; +using Timeline.Tests.Helpers; +using Xunit; namespace Timeline.Tests.Services { public class HighlightTimelineServiceTest : DatabaseBasedTest { - private UserService _userService; - private TimelineService _timelineService; + private readonly TestClock _clock = new TestClock(); + private UserService _userService = default!; + private TimelineService _timelineService = default!; - private HighlightTimelineService _service; + private HighlightTimelineService _service = default!; protected override void OnDatabaseCreated() { - + _userService = new UserService(NullLogger.Instance, Database, new PasswordService(), new UserPermissionService(Database), _clock); + _timelineService = new TimelineService(Database, _userService, _clock); + _service = new HighlightTimelineService(Database, _userService, _timelineService, _clock); } + [Fact] + public async Task Should_Work() + { + { + var ht = await _service.GetHighlightTimelines(); + ht.Should().BeEmpty(); + } + + var userId = await _userService.GetUserIdByUsername("user"); + await _timelineService.CreateTimeline("tl", userId); + await _service.AddHighlightTimeline("tl", userId); + + { + var ht = await _service.GetHighlightTimelines(); + ht.Should().HaveCount(1).And.BeEquivalentTo(await _timelineService.GetTimeline("tl")); + } + } } } diff --git a/BackEnd/Timeline.Tests/Services/TimelinePostServiceTest.cs b/BackEnd/Timeline.Tests/Services/TimelinePostServiceTest.cs index 97512be5..7771ae0b 100644 --- a/BackEnd/Timeline.Tests/Services/TimelinePostServiceTest.cs +++ b/BackEnd/Timeline.Tests/Services/TimelinePostServiceTest.cs @@ -36,7 +36,7 @@ namespace Timeline.Tests.Services { _dataManager = new DataManager(Database, _eTagGenerator); _userPermissionService = new UserPermissionService(Database); - _userService = new UserService(NullLogger.Instance, Database, _passwordService, _clock, _userPermissionService); + _userService = new UserService(NullLogger.Instance, Database, _passwordService, _userPermissionService, _clock); _timelineService = new TimelineService(Database, _userService, _clock); _timelinePostService = new TimelinePostService(NullLogger.Instance, Database, _timelineService, _userService, _dataManager, _imageValidator, _clock); _userDeleteService = new UserDeleteService(NullLogger.Instance, Database, _timelinePostService); diff --git a/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs b/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs index 98f03066..70f54ede 100644 --- a/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs +++ b/BackEnd/Timeline.Tests/Services/TimelineServiceTest.cs @@ -26,7 +26,7 @@ namespace Timeline.Tests.Services protected override void OnDatabaseCreated() { _userPermissionService = new UserPermissionService(Database); - _userService = new UserService(NullLogger.Instance, Database, _passwordService, _clock, _userPermissionService); + _userService = new UserService(NullLogger.Instance, Database, _passwordService, _userPermissionService, _clock); _timelineService = new TimelineService(Database, _userService, _clock); } diff --git a/BackEnd/Timeline/Entities/HighlightTimelineEntity.cs b/BackEnd/Timeline/Entities/HighlightTimelineEntity.cs index 0a38c8a6..3378a175 100644 --- a/BackEnd/Timeline/Entities/HighlightTimelineEntity.cs +++ b/BackEnd/Timeline/Entities/HighlightTimelineEntity.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Timeline.Entities { [Table("highlight_timelines")] - public record HighlightTimelineEntity + public class HighlightTimelineEntity { [Key, Column("id"), DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } @@ -20,5 +21,8 @@ namespace Timeline.Entities [ForeignKey(nameof(OperatorId))] public UserEntity? Operator { get; set; } + + [Column("add_time")] + public DateTime AddTime { get; set; } } } diff --git a/BackEnd/Timeline/Models/TimelineInfo.cs b/BackEnd/Timeline/Models/TimelineInfo.cs index 440f6b81..649af274 100644 --- a/BackEnd/Timeline/Models/TimelineInfo.cs +++ b/BackEnd/Timeline/Models/TimelineInfo.cs @@ -50,7 +50,7 @@ namespace Timeline.Models public string DataTag { get; set; } } - public record TimelinePostInfo + public class TimelinePostInfo { public TimelinePostInfo() { @@ -76,7 +76,7 @@ namespace Timeline.Models public string TimelineName { get; set; } = default!; } - public record TimelineInfo + public class TimelineInfo { public TimelineInfo() { diff --git a/BackEnd/Timeline/Models/UserInfo.cs b/BackEnd/Timeline/Models/UserInfo.cs index 058cc590..e8d57def 100644 --- a/BackEnd/Timeline/Models/UserInfo.cs +++ b/BackEnd/Timeline/Models/UserInfo.cs @@ -3,7 +3,7 @@ using Timeline.Services; namespace Timeline.Models { - public record UserInfo + public class UserInfo { public UserInfo() { diff --git a/BackEnd/Timeline/Services/HighlightTimelineService.cs b/BackEnd/Timeline/Services/HighlightTimelineService.cs index 619bc33e..0f4e5488 100644 --- a/BackEnd/Timeline/Services/HighlightTimelineService.cs +++ b/BackEnd/Timeline/Services/HighlightTimelineService.cs @@ -46,12 +46,14 @@ namespace Timeline.Services private readonly DatabaseContext _database; private readonly IBasicUserService _userService; private readonly ITimelineService _timelineService; + private readonly IClock _clock; - public HighlightTimelineService(DatabaseContext database, IBasicUserService userService, ITimelineService timelineService) + public HighlightTimelineService(DatabaseContext database, IBasicUserService userService, ITimelineService timelineService, IClock clock) { _database = database; _userService = userService; _timelineService = timelineService; + _clock = clock; } public async Task AddHighlightTimeline(string timelineName, long? operatorId) @@ -70,7 +72,7 @@ namespace Timeline.Services if (alreadyIs) return; - _database.HighlightTimelines.Add(new HighlightTimelineEntity { TimelineId = timelineId, OperatorId = operatorId }); + _database.HighlightTimelines.Add(new HighlightTimelineEntity { TimelineId = timelineId, OperatorId = operatorId, AddTime = _clock.GetCurrentTime() }); await _database.SaveChangesAsync(); } diff --git a/BackEnd/Timeline/Services/UserPermissionService.cs b/BackEnd/Timeline/Services/UserPermissionService.cs index 9683000a..bd7cd6aa 100644 --- a/BackEnd/Timeline/Services/UserPermissionService.cs +++ b/BackEnd/Timeline/Services/UserPermissionService.cs @@ -28,7 +28,7 @@ namespace Timeline.Services /// /// Represents a user's permissions. /// - public class UserPermissions : IEnumerable + public class UserPermissions : IEnumerable, IEquatable { public static UserPermissions AllPermissions { get; } = new UserPermissions(Enum.GetValues()); @@ -49,10 +49,10 @@ namespace Timeline.Services public UserPermissions(IEnumerable permissions) { if (permissions == null) throw new ArgumentNullException(nameof(permissions)); - _permissions = new HashSet(permissions); + _permissions = new SortedSet(permissions); } - private readonly HashSet _permissions = new(); + private readonly SortedSet _permissions = new(); /// /// Check if a permission is contained in the list. @@ -108,6 +108,33 @@ namespace Timeline.Services { return ((IEnumerable)_permissions).GetEnumerator(); } + + public bool Equals(UserPermissions? other) + { + if (other == null) + return false; + + return _permissions.SequenceEqual(other._permissions); + } + + public override bool Equals(object? obj) + { + return Equals(obj as UserPermissions); + } + + public override int GetHashCode() + { + int result = 0; + foreach (var permission in Enum.GetValues()) + { + if (_permissions.Contains(permission)) + { + result += 1; + } + result <<= 1; + } + return result; + } } public interface IUserPermissionService diff --git a/BackEnd/Timeline/Services/UserService.cs b/BackEnd/Timeline/Services/UserService.cs index 96068e44..c99e86b0 100644 --- a/BackEnd/Timeline/Services/UserService.cs +++ b/BackEnd/Timeline/Services/UserService.cs @@ -17,7 +17,7 @@ namespace Timeline.Services /// /// Null means not change. /// - public record ModifyUserParams + public class ModifyUserParams { public string? Username { get; set; } public string? Password { get; set; } @@ -78,13 +78,13 @@ namespace Timeline.Services private readonly UsernameValidator _usernameValidator = new UsernameValidator(); private readonly NicknameValidator _nicknameValidator = new NicknameValidator(); - public UserService(ILogger logger, DatabaseContext databaseContext, IPasswordService passwordService, IClock clock, IUserPermissionService userPermissionService) : base(databaseContext) + public UserService(ILogger logger, DatabaseContext databaseContext, IPasswordService passwordService, IUserPermissionService userPermissionService, IClock clock) : base(databaseContext) { _logger = logger; - _clock = clock; _databaseContext = databaseContext; _passwordService = passwordService; _userPermissionService = userPermissionService; + _clock = clock; } private void CheckUsernameFormat(string username, string? paramName) -- cgit v1.2.3 From a0f8b2ba0d41678b09bff2adaac94e5bac717b9b Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 17 Dec 2020 23:09:24 +0800 Subject: ... --- BackEnd/Timeline.ErrorCodes/ErrorCodes.cs | 5 +++ .../Controllers/HighlightTimelineController.cs | 52 ++++++++++++++++++++-- BackEnd/Timeline/Models/Http/HighlightTimeline.cs | 17 +++++++ 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 BackEnd/Timeline/Models/Http/HighlightTimeline.cs (limited to 'BackEnd/Timeline/Models') diff --git a/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs b/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs index 90c4ed99..a8519216 100644 --- a/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs +++ b/BackEnd/Timeline.ErrorCodes/ErrorCodes.cs @@ -63,6 +63,11 @@ public const int PostNotExist = 1_104_05_01; public const int PostNoData = 1_104_05_02; } + + public static class HighlightTimelineController + { + public const int NonHighlight = 1_105_01_01; + } } } diff --git a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs index 3819bfc4..0b6e1665 100644 --- a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs +++ b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs @@ -15,7 +15,6 @@ namespace Timeline.Controllers /// [ApiController] [ProducesErrorResponseType(typeof(CommonResponse))] - [Route("highlights")] public class HighlightTimelineController : Controller { private readonly IHighlightTimelineService _service; @@ -31,7 +30,7 @@ namespace Timeline.Controllers /// Get all highlight timelines. /// /// Highlight timeline list. - [HttpGet] + [HttpGet("highlights")] [ProducesResponseType(200)] public async Task>> List() { @@ -42,8 +41,8 @@ namespace Timeline.Controllers /// /// Add a timeline to highlight list. /// - /// - [HttpPut("{timeline}")] + /// The timeline name. + [HttpPut("highlights/{timeline}")] [PermissionAuthorize(UserPermission.HighlightTimelineManagement)] [ProducesResponseType(200)] [ProducesResponseType(400)] @@ -59,5 +58,50 @@ namespace Timeline.Controllers return BadRequest(ErrorResponse.TimelineController.NotExist()); } } + + /// + /// Remove a timeline from highlight list. + /// + /// Timeline name. + [HttpDelete("highlights/{timeline}")] + [PermissionAuthorize(UserPermission.HighlightTimelineManagement)] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task Delete([GeneralTimelineName] string timeline) + { + try + { + await _service.RemoveHighlightTimeline(timeline, this.GetUserId()); + return Ok(); + } + catch (TimelineNotExistException) + { + return BadRequest(ErrorResponse.TimelineController.NotExist()); + } + } + + /// + /// Move a highlight position. + /// + [HttpPost("highlightop/move")] + [PermissionAuthorize(UserPermission.HighlightTimelineManagement)] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task Move([FromBody] HttpHighlightTimelineMoveRequest body) + { + try + { + await _service.MoveHighlightTimeline(body.Timeline, body.NewPosition!.Value); + return Ok(); + } + catch (TimelineNotExistException) + { + return BadRequest(ErrorResponse.TimelineController.NotExist()); + } + catch (InvalidHighlightTimelineException) + { + return BadRequest(new CommonResponse(ErrorCodes.HighlightTimelineController.NonHighlight, "Can't move a non-highlight timeline.")); + } + } } } diff --git a/BackEnd/Timeline/Models/Http/HighlightTimeline.cs b/BackEnd/Timeline/Models/Http/HighlightTimeline.cs new file mode 100644 index 00000000..e5aed068 --- /dev/null +++ b/BackEnd/Timeline/Models/Http/HighlightTimeline.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; +using Timeline.Models.Validation; + +namespace Timeline.Models.Http +{ + /// + /// Move highlight timeline request body model. + /// + public class HttpHighlightTimelineMoveRequest + { + [GeneralTimelineName] + public string Timeline { get; set; } = default!; + + [Required] + public long? NewPosition { get; set; } + } +} -- cgit v1.2.3