diff options
Diffstat (limited to 'Timeline')
-rw-r--r-- | Timeline/Controllers/ControllerAuthExtensions.cs | 2 | ||||
-rw-r--r-- | Timeline/Controllers/UserAvatarController.cs | 2 | ||||
-rw-r--r-- | Timeline/Controllers/UserController.cs | 18 | ||||
-rw-r--r-- | Timeline/Entities/UserEntity.cs | 2 | ||||
-rw-r--r-- | Timeline/Models/Http/UserInfo.cs | 21 | ||||
-rw-r--r-- | Timeline/Models/Validation/NicknameValidator.cs | 2 | ||||
-rw-r--r-- | Timeline/Services/TimelineService.cs | 2 | ||||
-rw-r--r-- | Timeline/Services/UserService.cs | 2 |
8 files changed, 32 insertions, 19 deletions
diff --git a/Timeline/Controllers/ControllerAuthExtensions.cs b/Timeline/Controllers/ControllerAuthExtensions.cs index 90da8a93..34fd4d99 100644 --- a/Timeline/Controllers/ControllerAuthExtensions.cs +++ b/Timeline/Controllers/ControllerAuthExtensions.cs @@ -34,7 +34,7 @@ namespace Timeline.Controllers var claim = controller.User.FindFirst(ClaimTypes.NameIdentifier);
if (claim == null)
- throw new InvalidOperationException("Failed to get user id because User has no NameIdentifier claim.");
+ return null;
if (long.TryParse(claim.Value, out var value))
return value;
diff --git a/Timeline/Controllers/UserAvatarController.cs b/Timeline/Controllers/UserAvatarController.cs index ab0ad8e7..2dd279a8 100644 --- a/Timeline/Controllers/UserAvatarController.cs +++ b/Timeline/Controllers/UserAvatarController.cs @@ -78,7 +78,7 @@ namespace Timeline.Controllers [HttpPut("users/{username}/avatar")]
[Authorize]
- [RequireContentLength]
+ [RequireContentType, RequireContentLength]
[Consumes("image/png", "image/jpeg", "image/gif", "image/webp")]
public async Task<IActionResult> Put([FromRoute][Username] string username)
{
diff --git a/Timeline/Controllers/UserController.cs b/Timeline/Controllers/UserController.cs index 400a518c..fa73c6f9 100644 --- a/Timeline/Controllers/UserController.cs +++ b/Timeline/Controllers/UserController.cs @@ -42,7 +42,13 @@ namespace Timeline.Controllers {
var users = await _userService.GetUsers();
var administrator = this.IsAdministrator();
- return Ok(users.Select(u => ConvertToUserInfo(u, administrator)).ToArray());
+ // Note: the (object) explicit conversion. If not convert,
+ // then result is a IUserInfo array and JsonSerializer will
+ // treat all element as IUserInfo and deserialize only properties
+ // in IUserInfo. So we convert it to object to make an object
+ // array so that JsonSerializer use the runtime type.
+ var result = users.Select(u => (object)ConvertToUserInfo(u, administrator)).ToArray();
+ return Ok(result);
}
[HttpGet("users/{username}")]
@@ -106,15 +112,11 @@ namespace Timeline.Controllers [HttpDelete("users/{username}"), AdminAuthorize]
public async Task<ActionResult<CommonDeleteResponse>> Delete([FromRoute][Username] string username)
{
- try
- {
- await _userService.DeleteUser(username);
+ var delete = await _userService.DeleteUser(username);
+ if (delete)
return Ok(CommonDeleteResponse.Delete());
- }
- catch (UserNotExistException)
- {
+ else
return Ok(CommonDeleteResponse.NotExist());
- }
}
[HttpPost("userop/createuser"), AdminAuthorize]
diff --git a/Timeline/Entities/UserEntity.cs b/Timeline/Entities/UserEntity.cs index dae6979f..946c3fa2 100644 --- a/Timeline/Entities/UserEntity.cs +++ b/Timeline/Entities/UserEntity.cs @@ -29,7 +29,7 @@ namespace Timeline.Entities [Column("version"), Required]
public long Version { get; set; }
- [Column("nickname"), MaxLength(40)]
+ [Column("nickname"), MaxLength(100)]
public string? Nickname { get; set; }
public UserAvatarEntity? Avatar { get; set; }
diff --git a/Timeline/Models/Http/UserInfo.cs b/Timeline/Models/Http/UserInfo.cs index 6029b8aa..62d989a2 100644 --- a/Timeline/Models/Http/UserInfo.cs +++ b/Timeline/Models/Http/UserInfo.cs @@ -29,21 +29,30 @@ namespace Timeline.Models.Http public bool Administrator { get; set; }
}
- public class UserInfoSetAvatarUrlAction : IMappingAction<object, IUserInfo>
+ public class UserInfoAvatarUrlValueResolver : IValueResolver<User, IUserInfo, string>
{
private readonly IActionContextAccessor _actionContextAccessor;
private readonly IUrlHelperFactory _urlHelperFactory;
- public UserInfoSetAvatarUrlAction(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory)
+ public UserInfoAvatarUrlValueResolver()
+ {
+ }
+
+ public UserInfoAvatarUrlValueResolver(IActionContextAccessor actionContextAccessor, IUrlHelperFactory urlHelperFactory)
{
_actionContextAccessor = actionContextAccessor;
_urlHelperFactory = urlHelperFactory;
}
- public void Process(object source, IUserInfo destination, ResolutionContext context)
+ public string Resolve(User source, IUserInfo destination, string destMember, ResolutionContext context)
{
+ if (_actionContextAccessor == null)
+ {
+ return $"/users/{destination.Username}/avatar";
+ }
+
var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
- destination.AvatarUrl = urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController), new { destination.Username });
+ return urlHelper.ActionLink(nameof(UserAvatarController.Get), nameof(UserAvatarController), new { destination.Username });
}
}
@@ -51,8 +60,8 @@ namespace Timeline.Models.Http {
public UserInfoAutoMapperProfile()
{
- CreateMap<User, UserInfo>().AfterMap<UserInfoSetAvatarUrlAction>();
- CreateMap<User, UserInfoForAdmin>().AfterMap<UserInfoSetAvatarUrlAction>();
+ CreateMap<User, UserInfo>().ForMember(u => u.AvatarUrl, opt => opt.MapFrom<UserInfoAvatarUrlValueResolver>());
+ CreateMap<User, UserInfoForAdmin>().ForMember(u => u.AvatarUrl, opt => opt.MapFrom<UserInfoAvatarUrlValueResolver>());
}
}
}
diff --git a/Timeline/Models/Validation/NicknameValidator.cs b/Timeline/Models/Validation/NicknameValidator.cs index 53a2916b..1d6ab163 100644 --- a/Timeline/Models/Validation/NicknameValidator.cs +++ b/Timeline/Models/Validation/NicknameValidator.cs @@ -7,7 +7,7 @@ namespace Timeline.Models.Validation {
protected override (bool, string) DoValidate(string value)
{
- if (value.Length > 10)
+ if (value.Length > 25)
return (false, MessageTooLong);
return (true, GetSuccessMessage());
diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index 89936aa2..16402f3e 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -295,7 +295,7 @@ namespace Timeline.Services {
if (entity.Content != null) // otherwise it is deleted
{
- var author = Mapper.Map<UserInfo>(UserService.GetUserById(entity.AuthorId));
+ var author = Mapper.Map<UserInfo>(await UserService.GetUserById(entity.AuthorId));
posts.Add(new TimelinePostInfo
{
Id = entity.Id,
diff --git a/Timeline/Services/UserService.cs b/Timeline/Services/UserService.cs index 1197bb73..d2dc969e 100644 --- a/Timeline/Services/UserService.cs +++ b/Timeline/Services/UserService.cs @@ -300,12 +300,14 @@ namespace Timeline.Services var administrator = info.Administrator ?? false;
var password = info.Password;
+ var nickname = info.Nickname;
var newEntity = new UserEntity
{
Username = username,
Password = _passwordService.HashPassword(password),
Roles = UserRoleConvert.ToString(administrator),
+ Nickname = nickname,
Version = 1
};
_databaseContext.Users.Add(newEntity);
|