diff options
Diffstat (limited to 'Timeline/Models')
-rw-r--r-- | Timeline/Models/Converters/JsonDateTimeConverter.cs | 1 | ||||
-rw-r--r-- | Timeline/Models/Http/Common.cs | 33 | ||||
-rw-r--r-- | Timeline/Models/Http/ErrorResponse.cs | 261 | ||||
-rw-r--r-- | Timeline/Models/Http/Timeline.cs | 45 | ||||
-rw-r--r-- | Timeline/Models/Http/TimelineCommon.cs (renamed from Timeline/Models/Timeline.cs) | 25 | ||||
-rw-r--r-- | Timeline/Models/Http/TimelineController.cs | 20 | ||||
-rw-r--r-- | Timeline/Models/Http/TokenController.cs (renamed from Timeline/Models/Http/Token.cs) | 0 | ||||
-rw-r--r-- | Timeline/Models/Http/User.cs | 38 | ||||
-rw-r--r-- | Timeline/Models/Http/UserController.cs | 53 | ||||
-rw-r--r-- | Timeline/Models/Http/UserInfo.cs | 59 | ||||
-rw-r--r-- | Timeline/Models/PutResult.cs | 17 | ||||
-rw-r--r-- | Timeline/Models/UserConvert.cs | 67 | ||||
-rw-r--r-- | Timeline/Models/UserInfo.cs | 23 | ||||
-rw-r--r-- | Timeline/Models/Validation/NicknameValidator.cs | 25 | ||||
-rw-r--r-- | Timeline/Models/Validation/UsernameValidator.cs | 1 | ||||
-rw-r--r-- | Timeline/Models/Validation/Validator.cs | 28 |
16 files changed, 450 insertions, 246 deletions
diff --git a/Timeline/Models/Converters/JsonDateTimeConverter.cs b/Timeline/Models/Converters/JsonDateTimeConverter.cs index 69af53c1..ef129a01 100644 --- a/Timeline/Models/Converters/JsonDateTimeConverter.cs +++ b/Timeline/Models/Converters/JsonDateTimeConverter.cs @@ -6,7 +6,6 @@ using System.Text.Json.Serialization; namespace Timeline.Models.Converters { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods")] public class JsonDateTimeConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/Timeline/Models/Http/Common.cs b/Timeline/Models/Http/Common.cs index d1e95397..a9fc8a79 100644 --- a/Timeline/Models/Http/Common.cs +++ b/Timeline/Models/Http/Common.cs @@ -1,15 +1,9 @@ -using System.Globalization;
using static Timeline.Resources.Models.Http.Common;
namespace Timeline.Models.Http
{
public class CommonResponse
{
- internal static CommonResponse InvalidModel(string message)
- {
- return new CommonResponse(ErrorCodes.Http.Common.InvalidModel, message);
- }
-
public CommonResponse()
{
@@ -25,33 +19,6 @@ namespace Timeline.Models.Http public string? Message { get; set; }
}
- internal static class HeaderErrorResponse
- {
- internal static CommonResponse BadIfNonMatch()
- {
- return new CommonResponse(ErrorCodes.Http.Common.Header.IfNonMatch.BadFormat, MessageHeaderIfNonMatchBad);
- }
- }
-
- internal static class ContentErrorResponse
- {
- internal static CommonResponse TooBig(string maxLength)
- {
- return new CommonResponse(ErrorCodes.Http.Common.Content.TooBig,
- string.Format(CultureInfo.CurrentCulture, MessageContentTooBig, maxLength));
- }
-
- internal static CommonResponse UnmatchedLength_Smaller()
- {
- return new CommonResponse(ErrorCodes.Http.Common.Content.UnmatchedLength_Smaller, MessageContentUnmatchedLengthSmaller);
- }
- internal static CommonResponse UnmatchedLength_Bigger()
- {
- return new CommonResponse(ErrorCodes.Http.Common.Content.UnmatchedLength_Bigger, MessageContentUnmatchedLengthBigger);
- }
- }
-
-
public class CommonDataResponse<T> : CommonResponse
{
public CommonDataResponse()
diff --git a/Timeline/Models/Http/ErrorResponse.cs b/Timeline/Models/Http/ErrorResponse.cs new file mode 100644 index 00000000..87516638 --- /dev/null +++ b/Timeline/Models/Http/ErrorResponse.cs @@ -0,0 +1,261 @@ +using static Timeline.Resources.Messages;
+
+namespace Timeline.Models.Http
+{
+
+ public static class ErrorResponse
+ {
+
+ public static class Common
+ {
+
+ public static CommonResponse InvalidModel(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.InvalidModel, string.Format(Common_InvalidModel, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_InvalidModel(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.InvalidModel, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse Forbid(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Forbid, string.Format(Common_Forbid, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Forbid(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Forbid, string.Format(message, formatArgs));
+ }
+
+ public static class Header
+ {
+
+ public static CommonResponse IfNonMatch_BadFormat(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.IfNonMatch_BadFormat, string.Format(Common_Header_IfNonMatch_BadFormat, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_IfNonMatch_BadFormat(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.IfNonMatch_BadFormat, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse ContentType_Missing(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentType_Missing, string.Format(Common_Header_ContentType_Missing, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_ContentType_Missing(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentType_Missing, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse ContentLength_Missing(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentLength_Missing, string.Format(Common_Header_ContentLength_Missing, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_ContentLength_Missing(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentLength_Missing, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse ContentLength_Zero(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentLength_Zero, string.Format(Common_Header_ContentLength_Zero, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_ContentLength_Zero(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Header.ContentLength_Zero, string.Format(message, formatArgs));
+ }
+
+ }
+
+ public static class Content
+ {
+
+ public static CommonResponse TooBig(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.TooBig, string.Format(Common_Content_TooBig, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_TooBig(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.TooBig, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse UnmatchedLength_Smaller(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.UnmatchedLength_Smaller, string.Format(Common_Content_UnmatchedLength_Smaller, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_UnmatchedLength_Smaller(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.UnmatchedLength_Smaller, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse UnmatchedLength_Bigger(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.UnmatchedLength_Bigger, string.Format(Common_Content_UnmatchedLength_Bigger, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_UnmatchedLength_Bigger(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.Common.Content.UnmatchedLength_Bigger, string.Format(message, formatArgs));
+ }
+
+ }
+
+ }
+
+ public static class UserCommon
+ {
+
+ public static CommonResponse NotExist(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserCommon.NotExist, string.Format(UserCommon_NotExist, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_NotExist(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserCommon.NotExist, string.Format(message, formatArgs));
+ }
+
+ }
+
+ public static class TokenController
+ {
+
+ public static CommonResponse Create_BadCredential(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Create_BadCredential, string.Format(TokenController_Create_BadCredential, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Create_BadCredential(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Create_BadCredential, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse Verify_BadFormat(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_BadFormat, string.Format(TokenController_Verify_BadFormat, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Verify_BadFormat(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_BadFormat, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse Verify_UserNotExist(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_UserNotExist, string.Format(TokenController_Verify_UserNotExist, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Verify_UserNotExist(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_UserNotExist, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse Verify_OldVersion(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_OldVersion, string.Format(TokenController_Verify_OldVersion, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Verify_OldVersion(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_OldVersion, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse Verify_TimeExpired(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_TimeExpired, string.Format(TokenController_Verify_TimeExpired, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_Verify_TimeExpired(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TokenController.Verify_TimeExpired, string.Format(message, formatArgs));
+ }
+
+ }
+
+ public static class UserController
+ {
+
+ public static CommonResponse UsernameConflict(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserController.UsernameConflict, string.Format(UserController_UsernameConflict, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_UsernameConflict(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserController.UsernameConflict, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse ChangePassword_BadOldPassword(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserController.ChangePassword_BadOldPassword, string.Format(UserController_ChangePassword_BadOldPassword, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_ChangePassword_BadOldPassword(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserController.ChangePassword_BadOldPassword, string.Format(message, formatArgs));
+ }
+
+ }
+
+ public static class UserAvatar
+ {
+
+ public static CommonResponse BadFormat_CantDecode(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_CantDecode, string.Format(UserAvatar_BadFormat_CantDecode, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_BadFormat_CantDecode(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_CantDecode, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse BadFormat_UnmatchedFormat(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_UnmatchedFormat, string.Format(UserAvatar_BadFormat_UnmatchedFormat, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_BadFormat_UnmatchedFormat(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_UnmatchedFormat, string.Format(message, formatArgs));
+ }
+
+ public static CommonResponse BadFormat_BadSize(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_BadSize, string.Format(UserAvatar_BadFormat_BadSize, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_BadFormat_BadSize(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.UserAvatar.BadFormat_BadSize, string.Format(message, formatArgs));
+ }
+
+ }
+
+ public static class TimelineController
+ {
+
+ public static CommonResponse MemberPut_NotExist(params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TimelineController.MemberPut_NotExist, string.Format(TimelineController_MemberPut_NotExist, formatArgs));
+ }
+
+ public static CommonResponse CustomMessage_MemberPut_NotExist(string message, params object?[] formatArgs)
+ {
+ return new CommonResponse(ErrorCodes.TimelineController.MemberPut_NotExist, string.Format(message, formatArgs));
+ }
+
+ }
+
+ }
+
+}
\ No newline at end of file diff --git a/Timeline/Models/Http/Timeline.cs b/Timeline/Models/Http/Timeline.cs deleted file mode 100644 index 06b88ad1..00000000 --- a/Timeline/Models/Http/Timeline.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
-using Timeline.Entities;
-
-namespace Timeline.Models.Http
-{
- public class TimelinePostCreateRequest
- {
- [Required(AllowEmptyStrings = true)]
- public string Content { get; set; } = default!;
-
- public DateTime? Time { get; set; }
- }
-
- public class TimelinePostCreateResponse
- {
- public long Id { get; set; }
-
- public DateTime Time { get; set; }
- }
-
- public class TimelinePostDeleteRequest
- {
- [Required]
- public long? Id { get; set; }
- }
-
- public class TimelinePropertyChangeRequest
- {
- public string? Description { get; set; }
-
- public TimelineVisibility? Visibility { get; set; }
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "This is a DTO class.")]
- public class TimelineMemberChangeRequest
- {
- public List<string>? Add { get; set; }
-
- public List<string>? Remove { get; set; }
- }
-}
diff --git a/Timeline/Models/Timeline.cs b/Timeline/Models/Http/TimelineCommon.cs index 752c698d..febb8186 100644 --- a/Timeline/Models/Timeline.cs +++ b/Timeline/Models/Http/TimelineCommon.cs @@ -1,7 +1,7 @@ using System;
using System.Collections.Generic;
-namespace Timeline.Models
+namespace Timeline.Models.Http
{
public enum TimelineVisibility
{
@@ -22,30 +22,19 @@ namespace Timeline.Models public class TimelinePostInfo
{
public long Id { get; set; }
-
- public string? Content { get; set; }
-
+ public string Content { get; set; } = default!;
public DateTime Time { get; set; }
-
- /// <summary>
- /// The username of the author.
- /// </summary>
- public string Author { get; set; } = default!;
+ public UserInfo Author { get; set; } = default!;
+ public DateTime LastUpdated { get; set; } = default!;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "This is a DTO class.")]
public class BaseTimelineInfo
{
- public string? Description { get; set; }
-
- /// <summary>
- /// The username of the owner.
- /// </summary>
- public string Owner { get; set; } = default!;
-
+ public string Description { get; set; } = default!;
+ public UserInfo Owner { get; set; } = default!;
public TimelineVisibility Visibility { get; set; }
-
- public List<string> Members { get; set; } = default!;
+ public List<UserInfo> Members { get; set; } = default!;
}
public class TimelineInfo : BaseTimelineInfo
diff --git a/Timeline/Models/Http/TimelineController.cs b/Timeline/Models/Http/TimelineController.cs new file mode 100644 index 00000000..f9a4d3e5 --- /dev/null +++ b/Timeline/Models/Http/TimelineController.cs @@ -0,0 +1,20 @@ +using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Timeline.Models.Http
+{
+ public class TimelinePostCreateRequest
+ {
+ [Required(AllowEmptyStrings = true)]
+ public string Content { get; set; } = default!;
+
+ public DateTime? Time { get; set; }
+ }
+
+ public class TimelinePatchRequest
+ {
+ public string? Description { get; set; }
+
+ public TimelineVisibility? Visibility { get; set; }
+ }
+}
diff --git a/Timeline/Models/Http/Token.cs b/Timeline/Models/Http/TokenController.cs index ea8b59ed..ea8b59ed 100644 --- a/Timeline/Models/Http/Token.cs +++ b/Timeline/Models/Http/TokenController.cs diff --git a/Timeline/Models/Http/User.cs b/Timeline/Models/Http/User.cs deleted file mode 100644 index 516c1329..00000000 --- a/Timeline/Models/Http/User.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.ComponentModel.DataAnnotations;
-using Timeline.Models.Validation;
-
-namespace Timeline.Models.Http
-{
- public class UserPutRequest
- {
- [Required]
- public string Password { get; set; } = default!;
- [Required]
- public bool? Administrator { get; set; }
- }
-
- public class UserPatchRequest
- {
- public string? Password { get; set; }
- public bool? Administrator { get; set; }
- }
-
- public class ChangeUsernameRequest
- {
- [Required]
- [Username]
- public string OldUsername { get; set; } = default!;
-
- [Required]
- [Username]
- public string NewUsername { get; set; } = default!;
- }
-
- public class ChangePasswordRequest
- {
- [Required]
- public string OldPassword { get; set; } = default!;
- [Required]
- public string NewPassword { get; set; } = default!;
- }
-}
diff --git a/Timeline/Models/Http/UserController.cs b/Timeline/Models/Http/UserController.cs new file mode 100644 index 00000000..e4c95cbd --- /dev/null +++ b/Timeline/Models/Http/UserController.cs @@ -0,0 +1,53 @@ +using AutoMapper;
+using System.ComponentModel.DataAnnotations;
+using Timeline.Models.Validation;
+using Timeline.Services;
+
+namespace Timeline.Models.Http
+{
+ public class UserPatchRequest
+ {
+ [Username]
+ public string? Username { get; set; }
+
+ [MinLength(1)]
+ public string? Password { get; set; }
+
+ [Nickname]
+ public string? Nickname { get; set; }
+
+ public bool? Administrator { get; set; }
+ }
+
+ public class CreateUserRequest
+ {
+ [Required, Username]
+ public string Username { get; set; } = default!;
+
+ [Required, MinLength(1)]
+ public string Password { get; set; } = default!;
+
+ [Required]
+ public bool? Administrator { get; set; }
+
+ [Nickname]
+ public string? Nickname { get; set; }
+ }
+
+ public class ChangePasswordRequest
+ {
+ [Required(AllowEmptyStrings = false)]
+ public string OldPassword { get; set; } = default!;
+ [Required(AllowEmptyStrings = false)]
+ public string NewPassword { get; set; } = default!;
+ }
+
+ public class UserControllerAutoMapperProfile : Profile
+ {
+ public UserControllerAutoMapperProfile()
+ {
+ CreateMap<UserPatchRequest, User>(MemberList.Source);
+ CreateMap<CreateUserRequest, User>(MemberList.Source);
+ }
+ }
+}
diff --git a/Timeline/Models/Http/UserInfo.cs b/Timeline/Models/Http/UserInfo.cs new file mode 100644 index 00000000..0d1d702b --- /dev/null +++ b/Timeline/Models/Http/UserInfo.cs @@ -0,0 +1,59 @@ +using AutoMapper;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Infrastructure;
+using Microsoft.AspNetCore.Mvc.Routing;
+using Timeline.Controllers;
+using Timeline.Services;
+
+namespace Timeline.Models.Http
+{
+ public class UserInfo
+ {
+ public string Username { get; set; } = default!;
+ public string Nickname { get; set; } = default!;
+ public bool? Administrator { get; set; } = default!;
+#pragma warning disable CA1707
+ public UserInfoLinks? _links { get; set; }
+#pragma warning restore CA1707
+ }
+
+ public class UserInfoLinks
+ {
+ public string Avatar { get; set; } = default!;
+ public string Timeline { get; set; } = default!;
+ }
+
+ public class UserInfoLinksValueResolver : IValueResolver<User, UserInfo, UserInfoLinks?>
+ {
+ 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)
+ {
+ if (_actionContextAccessor.ActionContext == null)
+ return null;
+
+ var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
+ var result = new UserInfoLinks
+ {
+ Avatar = urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController)[0..^nameof(Controller).Length], new { destination.Username }),
+ Timeline = urlHelper.ActionLink(nameof(PersonalTimelineController.TimelineGet), nameof(PersonalTimelineController)[0..^nameof(Controller).Length], new { destination.Username })
+ };
+ return result;
+ }
+ }
+
+ public class UserInfoAutoMapperProfile : Profile
+ {
+ public UserInfoAutoMapperProfile()
+ {
+ CreateMap<User, UserInfo>().ForMember(u => u._links, opt => opt.MapFrom<UserInfoLinksValueResolver>());
+ }
+ }
+}
diff --git a/Timeline/Models/PutResult.cs b/Timeline/Models/PutResult.cs deleted file mode 100644 index cecf86e6..00000000 --- a/Timeline/Models/PutResult.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Timeline.Models
-{
- /// <summary>
- /// Represents the result of a "put" operation.
- /// </summary>
- public enum PutResult
- {
- /// <summary>
- /// Indicates the item did not exist and now is created.
- /// </summary>
- Create,
- /// <summary>
- /// Indicates the item exists already and is modified.
- /// </summary>
- Modify
- }
-}
diff --git a/Timeline/Models/UserConvert.cs b/Timeline/Models/UserConvert.cs deleted file mode 100644 index 5b132421..00000000 --- a/Timeline/Models/UserConvert.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System;
-using System.Collections.Generic;
-using System.Linq;
-using Timeline.Entities;
-using Timeline.Services;
-
-namespace Timeline.Models
-{
- public static class UserConvert
- {
- public static UserInfo CreateUserInfo(User user)
- {
- if (user == null)
- throw new ArgumentNullException(nameof(user));
- return new UserInfo(user.Name, UserRoleConvert.ToBool(user.RoleString));
- }
-
- internal static UserCache CreateUserCache(User user)
- {
- if (user == null)
- throw new ArgumentNullException(nameof(user));
- return new UserCache
- {
- Username = user.Name,
- Administrator = UserRoleConvert.ToBool(user.RoleString),
- Version = user.Version
- };
- }
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "No need.")]
- public static class UserRoleConvert
- {
- public const string UserRole = UserRoles.User;
- public const string AdminRole = UserRoles.Admin;
-
- public static string[] ToArray(bool administrator)
- {
- return administrator ? new string[] { UserRole, AdminRole } : new string[] { UserRole };
- }
-
- public static string[] ToArray(string s)
- {
- return s.Split(',').ToArray();
- }
-
- public static bool ToBool(IReadOnlyCollection<string> roles)
- {
- return roles.Contains(AdminRole);
- }
-
- public static string ToString(IReadOnlyCollection<string> roles)
- {
- return string.Join(',', roles);
- }
-
- public static string ToString(bool administrator)
- {
- return administrator ? UserRole + "," + AdminRole : UserRole;
- }
-
- public static bool ToBool(string s)
- {
- return s.Contains("admin", StringComparison.InvariantCulture);
- }
- }
-}
diff --git a/Timeline/Models/UserInfo.cs b/Timeline/Models/UserInfo.cs deleted file mode 100644 index b60bdfa2..00000000 --- a/Timeline/Models/UserInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Timeline.Models
-{
- public sealed class UserInfo
- {
- public UserInfo()
- {
- }
-
- public UserInfo(string username, bool administrator)
- {
- Username = username;
- Administrator = administrator;
- }
-
- public string Username { get; set; } = default!;
- public bool Administrator { get; set; } = default!;
-
- public override string ToString()
- {
- return $"Username: {Username} ; Administrator: {Administrator}";
- }
- }
-}
diff --git a/Timeline/Models/Validation/NicknameValidator.cs b/Timeline/Models/Validation/NicknameValidator.cs new file mode 100644 index 00000000..1d6ab163 --- /dev/null +++ b/Timeline/Models/Validation/NicknameValidator.cs @@ -0,0 +1,25 @@ +using System;
+using static Timeline.Resources.Models.Validation.NicknameValidator;
+
+namespace Timeline.Models.Validation
+{
+ public class NicknameValidator : Validator<string>
+ {
+ protected override (bool, string) DoValidate(string value)
+ {
+ if (value.Length > 25)
+ return (false, MessageTooLong);
+
+ return (true, GetSuccessMessage());
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
+ public class NicknameAttribute : ValidateWithAttribute
+ {
+ public NicknameAttribute() : base(typeof(NicknameValidator))
+ {
+
+ }
+ }
+}
diff --git a/Timeline/Models/Validation/UsernameValidator.cs b/Timeline/Models/Validation/UsernameValidator.cs index fc6cdf37..d8f3bdc0 100644 --- a/Timeline/Models/Validation/UsernameValidator.cs +++ b/Timeline/Models/Validation/UsernameValidator.cs @@ -8,7 +8,6 @@ namespace Timeline.Models.Validation {
public const int MaxLength = 26;
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Already checked in base class.")]
protected override (bool, string) DoValidate(string value)
{
if (value.Length == 0)
diff --git a/Timeline/Models/Validation/Validator.cs b/Timeline/Models/Validation/Validator.cs index a16f6f81..ead7dbef 100644 --- a/Timeline/Models/Validation/Validator.cs +++ b/Timeline/Models/Validation/Validator.cs @@ -20,24 +20,46 @@ namespace Timeline.Models.Validation (bool, string) Validate(object? value);
}
+ public static class ValidatorExtensions
+ {
+ public static bool Validate(this IValidator validator, object? value, out string message)
+ {
+ if (validator == null)
+ throw new ArgumentNullException(nameof(validator));
+
+ var (r, m) = validator.Validate(value);
+ message = m;
+ return r;
+ }
+ }
+
/// <summary>
/// Convenient base class for validator.
/// </summary>
/// <typeparam name="T">The type of accepted value.</typeparam>
/// <remarks>
/// Subclass should override <see cref="DoValidate(T, out string)"/> to do the real validation.
- /// This class will check the nullity and type of value. If value is null or not of type <typeparamref name="T"/>
- /// it will return false and not call <see cref="DoValidate(T, out string)"/>.
+ /// This class will check the nullity and type of value.
+ /// If value is null, it will pass or fail depending on <see cref="PermitNull"/>.
+ /// If value is not null and not of type <typeparamref name="T"/>
+ /// it will fail and not call <see cref="DoValidate(T, out string)"/>.
+ ///
+ /// <see cref="PermitNull"/> is true by default.
///
/// If you want some other behaviours, write the validator from scratch.
/// </remarks>
public abstract class Validator<T> : IValidator
{
+ protected bool PermitNull { get; set; } = true;
+
public (bool, string) Validate(object? value)
{
if (value == null)
{
- return (false, ValidatorMessageNull);
+ if (PermitNull)
+ return (true, GetSuccessMessage());
+ else
+ return (false, ValidatorMessageNull);
}
if (value is T v)
|