(feat): file security service
This commit is contained in:
parent
d6fcf34bf6
commit
2c137947c6
@ -0,0 +1,10 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace FileSecurityService.Extensions
|
||||||
|
{
|
||||||
|
public static class ServiceCollectionExtensions {
|
||||||
|
public static void RegisterFileSecurityService(this IServiceCollection services) {
|
||||||
|
services.AddSingleton<IFileSecurityService, FileSecurityService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
webapi/Services/FileSecurityService/FileCategory.cs
Normal file
28
webapi/Services/FileSecurityService/FileCategory.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FileSecurityService {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public enum FileCategory {
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
Document,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
Image,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
Video
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,174 +1,138 @@
|
|||||||
using DomainResults.Common;
|
using DomainResults.Common;
|
||||||
using ExtensionMethods;
|
using ExtensionMethods;
|
||||||
|
|
||||||
namespace WeatherForecast.Services.Abstractions {
|
namespace FileSecurityService {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum FileCategory {
|
public interface IFileSecurityService {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Document,
|
/// <param name="fileName"></param>
|
||||||
|
/// <param name="bytes"></param>
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
Image,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
Video
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class FileSignature {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Signatures { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string ContentType { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public FileCategory FileCategory { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="signatures"></param>
|
|
||||||
/// <param name="contentType"></param>
|
/// <param name="contentType"></param>
|
||||||
/// <param name="fileCategory"></param>
|
/// <returns></returns>
|
||||||
public FileSignature(List<string> signatures, string contentType, FileCategory fileCategory) {
|
(FileCategory?, IDomainResult) CheckFileSignature(string fileName, byte[] bytes, string contentType);
|
||||||
Signatures = signatures;
|
|
||||||
ContentType = contentType;
|
|
||||||
FileCategory = fileCategory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public class FileSecurityService : IFileSecurityService {
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public abstract class FileServiceBase {
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://gist.github.com/qti3e/6341245314bf3513abb080677cd1c93b
|
/// https://gist.github.com/qti3e/6341245314bf3513abb080677cd1c93b
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<string, FileSignature> _data = new() {
|
private readonly Dictionary<string, FileSignature> _data;
|
||||||
#region Documents
|
|
||||||
{
|
/// <summary>
|
||||||
".pdf",
|
///
|
||||||
new FileSignature(new List<string> {
|
/// </summary>
|
||||||
|
public FileSecurityService() {
|
||||||
|
_data = new Dictionary<string, FileSignature>() {
|
||||||
|
#region Documents
|
||||||
|
{
|
||||||
|
".pdf",
|
||||||
|
new FileSignature(new List<string> {
|
||||||
"0,25504446"
|
"0,25504446"
|
||||||
}, "application/pdf", FileCategory.Document)
|
}, "application/pdf", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".rtf",
|
".rtf",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,7B5C72746631"
|
"0,7B5C72746631"
|
||||||
}, "application/rtf", FileCategory.Document)
|
}, "application/rtf", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".doc",
|
".doc",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,0D444F43",
|
"0,0D444F43",
|
||||||
"0,CF11E0A1B11AE100",
|
"0,CF11E0A1B11AE100",
|
||||||
"0,D0CF11E0A1B11AE1",
|
"0,D0CF11E0A1B11AE1",
|
||||||
"0,DBA52D00",
|
"0,DBA52D00",
|
||||||
"512,ECA5C100"
|
"512,ECA5C100"
|
||||||
}, "application/msword", FileCategory.Document)
|
}, "application/msword", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".xls",
|
".xls",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"512,0908100000060500",
|
"512,0908100000060500",
|
||||||
"0,D0CF11E0A1B11AE1",
|
"0,D0CF11E0A1B11AE1",
|
||||||
"512,FDFFFFFF04",
|
"512,FDFFFFFF04",
|
||||||
"512,FDFFFFFF20000000"
|
"512,FDFFFFFF20000000"
|
||||||
}, "application/vnd.ms-excel", FileCategory.Document)
|
}, "application/vnd.ms-excel", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".ppt",
|
".ppt",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"512,006E1EF0",
|
"512,006E1EF0",
|
||||||
"512,0F00E803",
|
"512,0F00E803",
|
||||||
"512,A0461DF0",
|
"512,A0461DF0",
|
||||||
"0,D0CF11E0A1B11AE1",
|
"0,D0CF11E0A1B11AE1",
|
||||||
"512,FDFFFFFF04"
|
"512,FDFFFFFF04"
|
||||||
}, "application/vnd.ms-powerpoint", FileCategory.Document)
|
}, "application/vnd.ms-powerpoint", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".docx",
|
".docx",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,504B030414000600"
|
"0,504B030414000600"
|
||||||
}, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", FileCategory.Document)
|
}, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".xlsx",
|
".xlsx",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,504B030414000600"
|
"0,504B030414000600"
|
||||||
}, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileCategory.Document)
|
}, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileCategory.Document)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".pptx",
|
".pptx",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,504B030414000600"
|
"0,504B030414000600"
|
||||||
}, "application/vnd.openxmlformats-officedocument.presentationml.presentation", FileCategory.Document)
|
}, "application/vnd.openxmlformats-officedocument.presentationml.presentation", FileCategory.Document)
|
||||||
},
|
},
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Images
|
#region Images
|
||||||
{
|
{
|
||||||
".jpg",
|
".jpg",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,FFD8"
|
"0,FFD8"
|
||||||
}, "image/jpeg", FileCategory.Image)
|
}, "image/jpeg", FileCategory.Image)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".jpeg",
|
".jpeg",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,FFD8"
|
"0,FFD8"
|
||||||
}, "image/jpeg", FileCategory.Image)
|
}, "image/jpeg", FileCategory.Image)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".jpe",
|
".jpe",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,FFD8"
|
"0,FFD8"
|
||||||
}, "image/jpeg", FileCategory.Image)
|
}, "image/jpeg", FileCategory.Image)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
".jfif",
|
".jfif",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,FFD8"
|
"0,FFD8"
|
||||||
}, "image/jpeg", FileCategory.Image)
|
}, "image/jpeg", FileCategory.Image)
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
".png",
|
".png",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,89504E470D0A1A0A"
|
"0,89504E470D0A1A0A"
|
||||||
}, "image/png", FileCategory.Image)
|
}, "image/png", FileCategory.Image)
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
".webp",
|
".webp",
|
||||||
new FileSignature(new List<string> {
|
new FileSignature(new List<string> {
|
||||||
"0,52494646"
|
"0,52494646"
|
||||||
}, "image/webp", FileCategory.Image)
|
}, "image/webp", FileCategory.Image)
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Don't rely on or trust the FileName property without validation.
|
/// Don't rely on or trust the FileName property without validation.
|
||||||
@ -177,7 +141,7 @@ namespace WeatherForecast.Services.Abstractions {
|
|||||||
/// <param name="bytes"></param>
|
/// <param name="bytes"></param>
|
||||||
/// <param name="contentType"></param>
|
/// <param name="contentType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private protected (FileCategory?, IDomainResult) CheckFileSignature(string fileName, byte[] bytes, string contentType) {
|
public (FileCategory?, IDomainResult) CheckFileSignature(string fileName, byte[] bytes, string contentType) {
|
||||||
|
|
||||||
var data = _data.SingleOrDefault(x => x.Key == Path.GetExtension(fileName).ToLower()).Value;
|
var data = _data.SingleOrDefault(x => x.Key == Path.GetExtension(fileName).ToLower()).Value;
|
||||||
|
|
||||||
@ -208,10 +172,10 @@ namespace WeatherForecast.Services.Abstractions {
|
|||||||
x |= sample[i] ^ signBytes[i];
|
x |= sample[i] ^ signBytes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x == 0) return IDomainResult.Success(data.FileCategory); ;
|
if (x == 0) return IDomainResult.Success(data.FileCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IDomainResult.Failed<FileCategory?>(); ;
|
return IDomainResult.Failed<FileCategory?>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DomainResult.Common" Version="3.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||||
|
<PackageReference Include="nClam" Version="7.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Extensions\Extensions.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
40
webapi/Services/FileSecurityService/FileSignature.cs
Normal file
40
webapi/Services/FileSecurityService/FileSignature.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FileSecurityService {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
internal class FileSignature {
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public List<string> Signatures { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string ContentType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public FileCategory FileCategory { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="signatures"></param>
|
||||||
|
/// <param name="contentType"></param>
|
||||||
|
/// <param name="fileCategory"></param>
|
||||||
|
public FileSignature(List<string> signatures, string contentType, FileCategory fileCategory) {
|
||||||
|
Signatures = signatures;
|
||||||
|
ContentType = contentType;
|
||||||
|
FileCategory = fileCategory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreTests", "Tests\Core\Cor
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageService", "Services\ImageService\ImageService.csproj", "{16552644-D7EE-4B4A-A725-79909A8103DE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageService", "Services\ImageService\ImageService.csproj", "{16552644-D7EE-4B4A-A725-79909A8103DE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSecurityService", "Services\FileSecurityService\FileSecurityService.csproj", "{AD515653-9145-4894-9017-0ABA5A5892F4}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -79,6 +81,10 @@ Global
|
|||||||
{16552644-D7EE-4B4A-A725-79909A8103DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{16552644-D7EE-4B4A-A725-79909A8103DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{16552644-D7EE-4B4A-A725-79909A8103DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{16552644-D7EE-4B4A-A725-79909A8103DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{16552644-D7EE-4B4A-A725-79909A8103DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{16552644-D7EE-4B4A-A725-79909A8103DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AD515653-9145-4894-9017-0ABA5A5892F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{AD515653-9145-4894-9017-0ABA5A5892F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AD515653-9145-4894-9017-0ABA5A5892F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{AD515653-9145-4894-9017-0ABA5A5892F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -89,6 +95,7 @@ Global
|
|||||||
{43315A1D-9E09-4398-84B9-A9D9D623AE5A} = {216302C2-64DE-4AE7-BC14-BDAC5B732472}
|
{43315A1D-9E09-4398-84B9-A9D9D623AE5A} = {216302C2-64DE-4AE7-BC14-BDAC5B732472}
|
||||||
{04CB9827-AA6D-4708-A26D-8420C842506D} = {216302C2-64DE-4AE7-BC14-BDAC5B732472}
|
{04CB9827-AA6D-4708-A26D-8420C842506D} = {216302C2-64DE-4AE7-BC14-BDAC5B732472}
|
||||||
{16552644-D7EE-4B4A-A725-79909A8103DE} = {113EE574-E047-4727-AA36-841F845504D5}
|
{16552644-D7EE-4B4A-A725-79909A8103DE} = {113EE574-E047-4727-AA36-841F845504D5}
|
||||||
|
{AD515653-9145-4894-9017-0ABA5A5892F4} = {113EE574-E047-4727-AA36-841F845504D5}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {E2805D02-2425-424C-921D-D97341B76F73}
|
SolutionGuid = {E2805D02-2425-424C-921D-D97341B76F73}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
using DataProviders;
|
using DataProviders;
|
||||||
using DataProviders.Buckets;
|
using DataProviders.Buckets;
|
||||||
using DomainResults.Common;
|
using DomainResults.Common;
|
||||||
using WeatherForecast.Services.Abstractions;
|
using FileSecurityService;
|
||||||
|
|
||||||
namespace WeatherForecast.Services {
|
namespace WeatherForecast.Services {
|
||||||
|
|
||||||
@ -42,21 +42,25 @@ namespace WeatherForecast.Services {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FileService : FileServiceBase, IFileService {
|
public class FileService : IFileService {
|
||||||
|
|
||||||
private readonly ILogger<FilesService> _logger;
|
private readonly ILogger<FilesService> _logger;
|
||||||
|
private readonly IFileSecurityService _fileSecurityService;
|
||||||
private readonly IImagesBucketDataProvider _imageBucketDataProvider;
|
private readonly IImagesBucketDataProvider _imageBucketDataProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
|
/// <param name="fileSecurityService"></param>
|
||||||
/// <param name="imageBucketDataProvider"></param>
|
/// <param name="imageBucketDataProvider"></param>
|
||||||
public FileService(
|
public FileService(
|
||||||
ILogger<FilesService> logger,
|
ILogger<FilesService> logger,
|
||||||
|
IFileSecurityService fileSecurityService,
|
||||||
IImagesBucketDataProvider imageBucketDataProvider
|
IImagesBucketDataProvider imageBucketDataProvider
|
||||||
) {
|
) {
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_fileSecurityService = fileSecurityService;
|
||||||
_imageBucketDataProvider = imageBucketDataProvider;
|
_imageBucketDataProvider = imageBucketDataProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +80,7 @@ namespace WeatherForecast.Services {
|
|||||||
file.CopyTo(ms);
|
file.CopyTo(ms);
|
||||||
var bytes = ms.ToArray();
|
var bytes = ms.ToArray();
|
||||||
|
|
||||||
var (fileCategory, signatureResult) = CheckFileSignature(file.FileName, bytes, file.ContentType);
|
var (fileCategory, signatureResult) = _fileSecurityService.CheckFileSignature(file.FileName, bytes, file.ContentType);
|
||||||
|
|
||||||
if(!signatureResult.IsSuccess || fileCategory == null)
|
if(!signatureResult.IsSuccess || fileCategory == null)
|
||||||
return IDomainResult.Failed<Guid?>();
|
return IDomainResult.Failed<Guid?>();
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using DataProviders;
|
using DataProviders;
|
||||||
using DataProviders.Buckets;
|
using DataProviders.Buckets;
|
||||||
using DomainResults.Common;
|
using DomainResults.Common;
|
||||||
using WeatherForecast.Services.Abstractions;
|
using FileSecurityService;
|
||||||
|
|
||||||
namespace WeatherForecast.Services {
|
namespace WeatherForecast.Services {
|
||||||
|
|
||||||
@ -31,9 +31,10 @@ namespace WeatherForecast.Services {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FilesService : FileServiceBase, IFilesService {
|
public class FilesService : IFilesService {
|
||||||
|
|
||||||
private readonly ILogger<FilesService> _logger;
|
private readonly ILogger<FilesService> _logger;
|
||||||
|
private readonly IFileSecurityService _fileSecurityService;
|
||||||
private readonly IImagesBucketDataProvider _imageBucketDataProvider;
|
private readonly IImagesBucketDataProvider _imageBucketDataProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -43,9 +44,11 @@ namespace WeatherForecast.Services {
|
|||||||
/// <param name="imageBucketDataProvider"></param>
|
/// <param name="imageBucketDataProvider"></param>
|
||||||
public FilesService(
|
public FilesService(
|
||||||
ILogger<FilesService> logger,
|
ILogger<FilesService> logger,
|
||||||
|
IFileSecurityService fileSecurityService,
|
||||||
IImagesBucketDataProvider imageBucketDataProvider
|
IImagesBucketDataProvider imageBucketDataProvider
|
||||||
) {
|
) {
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_fileSecurityService = fileSecurityService;
|
||||||
_imageBucketDataProvider = imageBucketDataProvider;
|
_imageBucketDataProvider = imageBucketDataProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,8 +70,15 @@ namespace WeatherForecast.Services {
|
|||||||
foreach (var formFile in files) {
|
foreach (var formFile in files) {
|
||||||
using var ms = new MemoryStream();
|
using var ms = new MemoryStream();
|
||||||
formFile.CopyTo(ms);
|
formFile.CopyTo(ms);
|
||||||
|
var bytes = ms.ToArray();
|
||||||
|
|
||||||
newFiles.Add(new BucketFile(formFile.FileName, ms.ToArray(), formFile.ContentType));
|
var (fileCategory, signatureResult) = _fileSecurityService.CheckFileSignature(formFile.FileName, bytes, formFile.ContentType);
|
||||||
|
if (!signatureResult.IsSuccess || fileCategory == null)
|
||||||
|
return IDomainResult.Failed<List<Guid>?>();
|
||||||
|
|
||||||
|
var bucketFile = new BucketFile(formFile.FileName, bytes, formFile.ContentType);
|
||||||
|
|
||||||
|
newFiles.Add(bucketFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (list, result) = _imageBucketDataProvider.UploadMany(siteId, userId, newFiles);
|
var (list, result) = _imageBucketDataProvider.UploadMany(siteId, userId, newFiles);
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||||||
using WeatherForecast.Services;
|
using WeatherForecast.Services;
|
||||||
using DataProviders.Extensions;
|
using DataProviders.Extensions;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using FileSecurityService.Extensions;
|
||||||
|
|
||||||
namespace WeatherForecast {
|
namespace WeatherForecast {
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ namespace WeatherForecast {
|
|||||||
services.AddScoped<IFilesService, FilesService>();
|
services.AddScoped<IFilesService, FilesService>();
|
||||||
|
|
||||||
services.RegisterDataproviders(appSettings);
|
services.RegisterDataproviders(appSettings);
|
||||||
|
services.RegisterFileSecurityService();
|
||||||
|
|
||||||
#region Swagger
|
#region Swagger
|
||||||
services.ConfigureSwaggerGen(options => {
|
services.ConfigureSwaggerGen(options => {
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
<ProjectReference Include="..\Core\Core.csproj" />
|
||||||
<ProjectReference Include="..\DataProviders\DataProviders.csproj" />
|
<ProjectReference Include="..\DataProviders\DataProviders.csproj" />
|
||||||
<ProjectReference Include="..\Extensions\Extensions.csproj" />
|
<ProjectReference Include="..\Extensions\Extensions.csproj" />
|
||||||
|
<ProjectReference Include="..\Services\FileSecurityService\FileSecurityService.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user