From 4bbaaf45c64da897c4832aceeeec2549cfbd901a Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Mon, 19 Aug 2019 00:21:38 +0800 Subject: Improve avatar validation. --- Timeline/Services/UserAvatarService.cs | 41 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'Timeline/Services/UserAvatarService.cs') diff --git a/Timeline/Services/UserAvatarService.cs b/Timeline/Services/UserAvatarService.cs index 2a73cde5..dd0e5e7c 100644 --- a/Timeline/Services/UserAvatarService.cs +++ b/Timeline/Services/UserAvatarService.cs @@ -24,12 +24,29 @@ namespace Timeline.Services [Serializable] public class AvatarDataException : Exception { - public AvatarDataException(Avatar avatar, string message) : base(message) { Avatar = avatar; } - public AvatarDataException(Avatar avatar, string message, Exception inner) : base(message, inner) { Avatar = avatar; } + public enum ErrorReason + { + /// + /// Decoding image failed. + /// + CantDecode, + /// + /// Decoding succeeded but the real type is not the specified type. + /// + UnmatchedFormat, + /// + /// Image is not a square. + /// + BadSize + } + + public AvatarDataException(Avatar avatar, ErrorReason error, string message) : base(message) { Avatar = avatar; Error = error; } + public AvatarDataException(Avatar avatar, ErrorReason error, string message, Exception inner) : base(message, inner) { Avatar = avatar; Error = error; } protected AvatarDataException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + public ErrorReason Error { get; set; } public Avatar Avatar { get; set; } } @@ -49,7 +66,12 @@ namespace Timeline.Services public interface IUserAvatarValidator { - Task<(bool valid, string message)> Validate(Avatar avatar); + /// + /// Validate a avatar's format and size info. + /// + /// The avatar to validate. + /// Thrown when validation failed. + Task Validate(Avatar avatar); } public interface IUserAvatarService @@ -96,7 +118,7 @@ namespace Timeline.Services public class UserAvatarValidator : IUserAvatarValidator { - public Task<(bool valid, string message)> Validate(Avatar avatar) + public Task Validate(Avatar avatar) { return Task.Run(() => { @@ -105,15 +127,14 @@ namespace Timeline.Services using (var image = Image.Load(avatar.Data, out IImageFormat format)) { if (!format.MimeTypes.Contains(avatar.Type)) - return (false, "Image's actual mime type is not the specified one."); + throw new AvatarDataException(avatar, AvatarDataException.ErrorReason.UnmatchedFormat, "Image's actual mime type is not the specified one."); if (image.Width != image.Height) - return (false, "Image is not a square, aka width is not equal to height."); + throw new AvatarDataException(avatar, AvatarDataException.ErrorReason.BadSize, "Image is not a square, aka, width is not equal to height."); } - return (true, "A good avatar."); } catch (UnknownImageFormatException e) { - return (false, $"Failed to decode image. Exception: {e} ."); + throw new AvatarDataException(avatar, AvatarDataException.ErrorReason.CantDecode, "Failed to decode image. See inner exception.", e); } }); } @@ -196,9 +217,7 @@ namespace Timeline.Services } else { - (bool valid, string message) = await _avatarValidator.Validate(avatar); - if (!valid) - throw new AvatarDataException(avatar, $"Failed to validate image. {message}"); + await _avatarValidator.Validate(avatar); if (avatarEntity == null) { -- cgit v1.2.3