From eb1b148146281449b56bd68d1f99b4e48287a0b7 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 16 Apr 2022 22:17:56 +0800 Subject: ... --- .../Controllers/V2/UserAvatarV2Controller.cs | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 BackEnd/Timeline/Controllers/V2/UserAvatarV2Controller.cs (limited to 'BackEnd') diff --git a/BackEnd/Timeline/Controllers/V2/UserAvatarV2Controller.cs b/BackEnd/Timeline/Controllers/V2/UserAvatarV2Controller.cs new file mode 100644 index 00000000..2f0256ec --- /dev/null +++ b/BackEnd/Timeline/Controllers/V2/UserAvatarV2Controller.cs @@ -0,0 +1,104 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Timeline.Filters; +using Timeline.Helpers.Cache; +using Timeline.Models; +using Timeline.Models.Validation; +using Timeline.Services.User; +using Timeline.Services.User.Avatar; + +namespace Timeline.Controllers.V2 +{ + /// + /// Operations about user avatar. + /// + [ApiController] + [Route("v2/users/{username}/avatar")] + public class UserAvatarV2Controller : V2ControllerBase + { + private readonly IUserService _userService; + private readonly IUserAvatarService _service; + + public UserAvatarV2Controller(IUserService userService, IUserAvatarService service) + { + _userService = userService; + _service = service; + } + + /// + /// Get avatar of a user. + /// + /// Username of the user to get avatar of. + /// If-None-Match header. + /// Avatar data. + [HttpGet] + [ProducesImages] + [ProducesResponseType(typeof(byte[]), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(void), StatusCodes.Status304NotModified)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Get([FromRoute][Username] string username, [FromHeader(Name = "If-None-Match")] string? ifNoneMatch) + { + _ = ifNoneMatch; + long userId = await _userService.GetUserIdByUsernameAsync(username); + return await DataCacheHelper.GenerateActionResult(this, () => _service.GetAvatarDigestAsync(userId), () => _service.GetAvatarAsync(userId)); + } + + /// + /// Set avatar of a user. You have to be administrator to change other's. + /// + /// Username of the user to set avatar of. + /// The avatar data. + [HttpPut] + [Authorize] + [ConsumesImages] + [MaxContentLength(1000 * 1000 * 10)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task Put([FromRoute][Username] string username, [FromBody] ByteData body) + { + long userId = await _userService.GetUserIdByUsernameAsync(username); + + if (!UserHasPermission(UserPermission.UserManagement) && GetAuthUserId() != userId) + { + return Forbid(); + } + + + var digest = await _service.SetAvatarAsync(userId, body); + + Response.Headers.Append("ETag", $"\"{digest.ETag}\""); + return NoContent(); + } + + /// + /// Reset the avatar to the default one. You have to be administrator to reset other's. + /// + /// Username of the user. + /// Succeeded to reset. + /// You have not logged in. + /// You are not administrator. + [HttpDelete] + [Authorize] + [NotEntityDelete] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] + public async Task Delete([FromRoute][Username] string username) + { + long userId = await _userService.GetUserIdByUsernameAsync(username); + + if (!UserHasPermission(UserPermission.UserManagement) && GetAuthUserId() != userId) + { + return Forbid(); + } + + await _service.DeleteAvatarAsync(userId); + return NoContent(); + } + } +} -- cgit v1.2.3