diff options
author | 杨宇千 <crupest@outlook.com> | 2019-08-19 00:01:09 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-08-19 00:01:09 +0800 |
commit | e5f5be69f854565d4f58d996cbf4347fa0eae0ff (patch) | |
tree | b108cae68db2040b14d576d3813ab4711777fbad /Timeline | |
parent | bc832053bdad644a0a86ded0173f3f47c0159018 (diff) | |
download | timeline-e5f5be69f854565d4f58d996cbf4347fa0eae0ff.tar.gz timeline-e5f5be69f854565d4f58d996cbf4347fa0eae0ff.tar.bz2 timeline-e5f5be69f854565d4f58d996cbf4347fa0eae0ff.zip |
Add validator.
Diffstat (limited to 'Timeline')
-rw-r--r-- | Timeline/Services/UserAvatarService.cs | 44 | ||||
-rw-r--r-- | Timeline/Timeline.csproj | 1 |
2 files changed, 43 insertions, 2 deletions
diff --git a/Timeline/Services/UserAvatarService.cs b/Timeline/Services/UserAvatarService.cs index 4f11978c..2a73cde5 100644 --- a/Timeline/Services/UserAvatarService.cs +++ b/Timeline/Services/UserAvatarService.cs @@ -2,6 +2,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Formats;
using System;
using System.IO;
using System.Linq;
@@ -45,6 +47,11 @@ namespace Timeline.Services Task<Avatar> GetDefaultAvatar();
}
+ public interface IUserAvatarValidator
+ {
+ Task<(bool valid, string message)> Validate(Avatar avatar);
+ }
+
public interface IUserAvatarService
{
/// <summary>
@@ -87,6 +94,31 @@ namespace Timeline.Services }
}
+ public class UserAvatarValidator : IUserAvatarValidator
+ {
+ public Task<(bool valid, string message)> Validate(Avatar avatar)
+ {
+ return Task.Run(() =>
+ {
+ try
+ {
+ 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.");
+ if (image.Width != image.Height)
+ return (false, "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} .");
+ }
+ });
+ }
+ }
+
public class UserAvatarService : IUserAvatarService
{
@@ -95,12 +127,14 @@ namespace Timeline.Services private readonly DatabaseContext _database;
private readonly IDefaultUserAvatarProvider _defaultUserAvatarProvider;
+ private readonly IUserAvatarValidator _avatarValidator;
- public UserAvatarService(ILogger<UserAvatarService> logger, DatabaseContext database, IDefaultUserAvatarProvider defaultUserAvatarProvider)
+ public UserAvatarService(ILogger<UserAvatarService> logger, DatabaseContext database, IDefaultUserAvatarProvider defaultUserAvatarProvider, IUserAvatarValidator avatarValidator)
{
_logger = logger;
_database = database;
_defaultUserAvatarProvider = defaultUserAvatarProvider;
+ _avatarValidator = avatarValidator;
}
public async Task<Avatar> GetAvatar(string username)
@@ -157,11 +191,15 @@ namespace Timeline.Services {
_database.UserAvatars.Remove(avatarEntity);
await _database.SaveChangesAsync();
+ _logger.LogInformation("Removed an entry in user_avatars.");
}
}
else
{
- // TODO: Use image library to check the format to prohibit bad data.
+ (bool valid, string message) = await _avatarValidator.Validate(avatar);
+ if (!valid)
+ throw new AvatarDataException(avatar, $"Failed to validate image. {message}");
+
if (avatarEntity == null)
{
user.Avatar = new UserAvatar
@@ -176,6 +214,7 @@ namespace Timeline.Services avatarEntity.Data = avatar.Data;
}
await _database.SaveChangesAsync();
+ _logger.LogInformation("Added or modified an entry in user_avatars.");
}
}
}
@@ -186,6 +225,7 @@ namespace Timeline.Services {
services.AddScoped<IUserAvatarService, UserAvatarService>();
services.AddSingleton<IDefaultUserAvatarProvider, DefaultUserAvatarProvider>();
+ services.AddSingleton<IUserAvatarValidator, UserAvatarValidator>();
}
}
}
diff --git a/Timeline/Timeline.csproj b/Timeline/Timeline.csproj index 29ff3354..3855e0d1 100644 --- a/Timeline/Timeline.csproj +++ b/Timeline/Timeline.csproj @@ -12,5 +12,6 @@ <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Design" Version="1.1.2" />
+ <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-dev002868" />
</ItemGroup>
</Project>
|