From 1bce70b36d4666797ae157167be4a84217a71374 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 5 May 2021 16:36:18 +0800 Subject: refactor: ... --- .../IntegratedTests/UserAvatarTest.cs | 2 +- BackEnd/Timeline/Controllers/Resource.Designer.cs | 36 ---------------------- BackEnd/Timeline/Controllers/Resource.resx | 12 -------- .../Timeline/Controllers/TimelinePostController.cs | 1 - .../Timeline/Controllers/UserAvatarController.cs | 32 ++++++------------- .../Timeline/Filters/CatchImageExceptionFilter.cs | 28 +++++++++++++++++ .../Timeline/Filters/ConsumesImagesAttribute.cs | 17 ++++++++++ .../Timeline/Filters/ProducesImagesAttribute.cs | 19 ++++++++++++ BackEnd/Timeline/Filters/Resource.Designer.cs | 36 ++++++++++++++++++++++ BackEnd/Timeline/Filters/Resource.resx | 12 ++++++++ .../Services/Timeline/ITimelinePostService.cs | 2 +- BackEnd/Timeline/Startup.cs | 1 + 12 files changed, 124 insertions(+), 74 deletions(-) create mode 100644 BackEnd/Timeline/Filters/CatchImageExceptionFilter.cs create mode 100644 BackEnd/Timeline/Filters/ConsumesImagesAttribute.cs create mode 100644 BackEnd/Timeline/Filters/ProducesImagesAttribute.cs (limited to 'BackEnd') diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs index e8c42d58..a7aa63cd 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs @@ -138,7 +138,7 @@ namespace Timeline.Tests.IntegratedTests await client.TestPutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.ContentType); await client.TestDeleteAsync("users/user1/avatar"); await client.TestPutByteArrayAssertErrorAsync("users/usernotexist/avatar", new[] { (byte)0x00 }, "image/png", errorCode: ErrorCodes.NotExist.User); - await client.TestDeleteAsync("users/usernotexist/avatar"); + await client.TestDeleteAssertErrorAsync("users/usernotexist/avatar"); } // bad username check diff --git a/BackEnd/Timeline/Controllers/Resource.Designer.cs b/BackEnd/Timeline/Controllers/Resource.Designer.cs index c062380b..a647558a 100644 --- a/BackEnd/Timeline/Controllers/Resource.Designer.cs +++ b/BackEnd/Timeline/Controllers/Resource.Designer.cs @@ -105,42 +105,6 @@ namespace Timeline.Controllers { } } - /// - /// Looks up a localized string similar to Image is not a square.. - /// - internal static string MessageImageBadSize { - get { - return ResourceManager.GetString("MessageImageBadSize", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Image decode failed.. - /// - internal static string MessageImageDecodeFailed { - get { - return ResourceManager.GetString("MessageImageDecodeFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Specified image format does not match the actual one .. - /// - internal static string MessageImageFormatUnmatch { - get { - return ResourceManager.GetString("MessageImageFormatUnmatch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown error happened to image.. - /// - internal static string MessageImageUnknownError { - get { - return ResourceManager.GetString("MessageImageUnknownError", resourceCulture); - } - } - /// /// Looks up a localized string similar to You can't do this because it is the root user.. /// diff --git a/BackEnd/Timeline/Controllers/Resource.resx b/BackEnd/Timeline/Controllers/Resource.resx index afaa1ba1..47b7a329 100644 --- a/BackEnd/Timeline/Controllers/Resource.resx +++ b/BackEnd/Timeline/Controllers/Resource.resx @@ -132,18 +132,6 @@ You can't do this unless you are administrator or resource owner. - - Image is not a square. - - - Image decode failed. - - - Specified image format does not match the actual one . - - - Unknown error happened to image. - You can't do this because it is the root user. diff --git a/BackEnd/Timeline/Controllers/TimelinePostController.cs b/BackEnd/Timeline/Controllers/TimelinePostController.cs index c33d47aa..21d3821a 100644 --- a/BackEnd/Timeline/Controllers/TimelinePostController.cs +++ b/BackEnd/Timeline/Controllers/TimelinePostController.cs @@ -202,7 +202,6 @@ namespace Timeline.Controllers } } - try { var post = await _postService.CreatePostAsync(timelineId, userId, createRequest); diff --git a/BackEnd/Timeline/Controllers/UserAvatarController.cs b/BackEnd/Timeline/Controllers/UserAvatarController.cs index 376e1f11..5b8c5cdf 100644 --- a/BackEnd/Timeline/Controllers/UserAvatarController.cs +++ b/BackEnd/Timeline/Controllers/UserAvatarController.cs @@ -7,7 +7,6 @@ using Timeline.Helpers.Cache; using Timeline.Models; using Timeline.Models.Http; using Timeline.Models.Validation; -using Timeline.Services.Imaging; using Timeline.Services.User; using Timeline.Services.User.Avatar; @@ -36,7 +35,7 @@ namespace Timeline.Controllers /// If-None-Match header. /// Avatar data. [HttpGet("users/{username}/avatar")] - [Produces("image/png", "image/jpeg", "image/gif", "image/webp", "application/json", "text/json")] + [ProducesImages] [ProducesResponseType(typeof(byte[]), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status304NotModified)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -54,7 +53,7 @@ namespace Timeline.Controllers /// The avatar data. [HttpPut("users/{username}/avatar")] [Authorize] - [Consumes("image/png", "image/jpeg", "image/gif", "image/webp")] + [ConsumesImages] [MaxContentLength(1000 * 1000 * 10)] [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -62,31 +61,17 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task Put([FromRoute][Username] string username, [FromBody] ByteData body) { - if (!UserHasPermission(UserPermission.UserManagement) && User.Identity!.Name != username) + if (!UserHasPermission(UserPermission.UserManagement) && GetUsername() != username) { return ForbidWithCommonResponse(Resource.MessageForbidNotAdministratorOrOwner); } long id = await _userService.GetUserIdByUsernameAsync(username); - try - { - var digest = await _service.SetAvatarAsync(id, body); - - Response.Headers.Append("ETag", $"\"{digest.ETag}\""); + var digest = await _service.SetAvatarAsync(id, body); - return Ok(); - } - catch (ImageException e) - { - return BadRequest(e.Error switch - { - ImageException.ErrorReason.CantDecode => new CommonResponse(ErrorCodes.Image.CantDecode, Resource.MessageImageDecodeFailed), - ImageException.ErrorReason.UnmatchedFormat => new CommonResponse(ErrorCodes.Image.UnmatchedFormat, Resource.MessageImageFormatUnmatch), - ImageException.ErrorReason.BadSize => new CommonResponse(ErrorCodes.Image.BadSize, Resource.MessageImageBadSize), - _ => new CommonResponse(ErrorCodes.Image.Unknown, Resource.MessageImageUnknownError) - }); - } + Response.Headers.Append("ETag", $"\"{digest.ETag}\""); + return Ok(); } /// @@ -98,11 +83,12 @@ namespace Timeline.Controllers /// 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)] - [Authorize] public async Task Delete([FromRoute][Username] string username) { if (!UserHasPermission(UserPermission.UserManagement) && User.Identity!.Name != username) @@ -113,7 +99,7 @@ namespace Timeline.Controllers long id = await _userService.GetUserIdByUsernameAsync(username); await _service.DeleteAvatarAsync(id); - return Ok(); + return OkWithCommonResponse(); } } } diff --git a/BackEnd/Timeline/Filters/CatchImageExceptionFilter.cs b/BackEnd/Timeline/Filters/CatchImageExceptionFilter.cs new file mode 100644 index 00000000..16278d15 --- /dev/null +++ b/BackEnd/Timeline/Filters/CatchImageExceptionFilter.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Timeline.Models.Http; +using Timeline.Services.Imaging; + +namespace Timeline.Filters +{ + public class CatchImageExceptionFilter : IExceptionFilter + { + public void OnException(ExceptionContext context) + { + if (context.Exception is ImageException e) + { + context.Result = new BadRequestObjectResult(e.Error switch + { + ImageException.ErrorReason.CantDecode => new CommonResponse(ErrorCodes.Image.CantDecode, Resource.MessageImageDecodeFailed), + ImageException.ErrorReason.UnmatchedFormat => new CommonResponse(ErrorCodes.Image.UnmatchedFormat, Resource.MessageImageFormatUnmatch), + ImageException.ErrorReason.BadSize => new CommonResponse(ErrorCodes.Image.BadSize, Resource.MessageImageBadSize), + _ => new CommonResponse(ErrorCodes.Image.Unknown, Resource.MessageImageUnknownError) + }); + } + } + } +} diff --git a/BackEnd/Timeline/Filters/ConsumesImagesAttribute.cs b/BackEnd/Timeline/Filters/ConsumesImagesAttribute.cs new file mode 100644 index 00000000..5a293dfe --- /dev/null +++ b/BackEnd/Timeline/Filters/ConsumesImagesAttribute.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Mvc; +using Timeline.Models; + +namespace Timeline.Filters +{ + public class ConsumesImagesAttribute : ConsumesAttribute + { + public ConsumesImagesAttribute() + : base(MimeTypes.ImagePng, + MimeTypes.ImageJpeg, + MimeTypes.ImageGif, + MimeTypes.ImageWebp) + { + + } + } +} diff --git a/BackEnd/Timeline/Filters/ProducesImagesAttribute.cs b/BackEnd/Timeline/Filters/ProducesImagesAttribute.cs new file mode 100644 index 00000000..b38b6543 --- /dev/null +++ b/BackEnd/Timeline/Filters/ProducesImagesAttribute.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; +using Timeline.Models; + +namespace Timeline.Filters +{ + public class ProducesImagesAttribute : ProducesAttribute + { + public ProducesImagesAttribute() + : base(MimeTypes.ImagePng, + MimeTypes.ImageJpeg, + MimeTypes.ImageGif, + MimeTypes.ImageWebp, + MimeTypes.TextJson, + MimeTypes.ApplicationJson) + { + + } + } +} diff --git a/BackEnd/Timeline/Filters/Resource.Designer.cs b/BackEnd/Timeline/Filters/Resource.Designer.cs index d5b533d4..25d0e222 100644 --- a/BackEnd/Timeline/Filters/Resource.Designer.cs +++ b/BackEnd/Timeline/Filters/Resource.Designer.cs @@ -86,5 +86,41 @@ namespace Timeline.Filters { return ResourceManager.GetString("MessageEntityNotExist", resourceCulture); } } + + /// + /// Looks up a localized string similar to Image is not a square.. + /// + internal static string MessageImageBadSize { + get { + return ResourceManager.GetString("MessageImageBadSize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Image decode failed.. + /// + internal static string MessageImageDecodeFailed { + get { + return ResourceManager.GetString("MessageImageDecodeFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specified image format does not match the actual one .. + /// + internal static string MessageImageFormatUnmatch { + get { + return ResourceManager.GetString("MessageImageFormatUnmatch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown error happened to image.. + /// + internal static string MessageImageUnknownError { + get { + return ResourceManager.GetString("MessageImageUnknownError", resourceCulture); + } + } } } diff --git a/BackEnd/Timeline/Filters/Resource.resx b/BackEnd/Timeline/Filters/Resource.resx index d55e996c..15b13f97 100644 --- a/BackEnd/Timeline/Filters/Resource.resx +++ b/BackEnd/Timeline/Filters/Resource.resx @@ -126,4 +126,16 @@ The entity you operate on does not exist. Entity type is {0}. Constraints are {1}. + + Image is not a square. + + + Image decode failed. + + + Specified image format does not match the actual one . + + + Unknown error happened to image. + \ No newline at end of file diff --git a/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs b/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs index d746cf63..92984938 100644 --- a/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs +++ b/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs @@ -66,7 +66,7 @@ namespace Timeline.Services.Timeline /// Thrown when is of invalid format. /// Thrown when timeline does not exist. /// Thrown if user of does not exist. - /// Thrown if data is not a image. Validated by . + /// Thrown if data is illegal. Task CreatePostAsync(long timelineId, long authorId, TimelinePostCreateRequest request); /// diff --git a/BackEnd/Timeline/Startup.cs b/BackEnd/Timeline/Startup.cs index 774895fe..1e0d4779 100644 --- a/BackEnd/Timeline/Startup.cs +++ b/BackEnd/Timeline/Startup.cs @@ -71,6 +71,7 @@ namespace Timeline setup.Filters.Add(new ProducesAttribute(MimeTypes.ApplicationJson, MimeTypes.TextJson)); setup.Filters.Add(); setup.Filters.Add(); + setup.Filters.Add(); setup.UseApiRoutePrefix("api"); }) .AddJsonOptions(options => -- cgit v1.2.3