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.Http; using Timeline.Models.Validation; using Timeline.Services.User; using Timeline.Services.User.Avatar; namespace Timeline.Controllers { /// /// Operations about user avatar. /// [ApiController] [ProducesErrorResponseType(typeof(CommonResponse))] public class UserAvatarController : MyControllerBase { private readonly IUserService _userService; private readonly IUserAvatarService _service; public UserAvatarController(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("users/{username}/avatar")] [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("users/{username}/avatar")] [Authorize] [ConsumesImages] [MaxContentLength(1000 * 1000 * 10)] [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task Put([FromRoute][Username] string username, [FromBody] ByteData body) { if (!UserHasPermission(UserPermission.UserManagement) && !await CheckIsSelf(username)) { return ForbidWithCommonResponse(Resource.MessageForbidNotAdministratorOrOwner); } long id = await _userService.GetUserIdByUsernameAsync(username); var digest = await _service.SetAvatarAsync(id, body); Response.Headers.Append("ETag", $"\"{digest.ETag}\""); return Ok(); } /// /// Reset the avatar to the default one. You have to be administrator to reset other's. /// /// Username of the user. /// Succeeded to reset. /// Error code is 10010001 if user does not exist. /// You have not logged in. /// You are not administrator. [HttpDelete("users/{username}/avatar")] [Authorize] [NotEntityDelete] [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task Delete([FromRoute][Username] string username) { if (!UserHasPermission(UserPermission.UserManagement) && !await CheckIsSelf(username)) { return ForbidWithCommonResponse(Resource.MessageForbidNotAdministratorOrOwner); } long id = await _userService.GetUserIdByUsernameAsync(username); await _service.DeleteAvatarAsync(id); return OkWithCommonResponse(); } } }