281 lines
5.9 KiB
C#
281 lines
5.9 KiB
C#
using Microsoft.AspNetCore.Http;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace OnlineSalesAutoCrop.CoreAPI.Configurations
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="Acceptable"></param>
|
|
/// <param name="Status"></param>
|
|
/// <param name="Message"></param>
|
|
public record Result(bool Acceptable, Status Status, string Message);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public enum Status
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
GENUINE,
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
FAKE,
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
NOTSUPPORTED
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public abstract class FileFormatDescriptor
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected FileFormatDescriptor()
|
|
{
|
|
Initialize();
|
|
MaxMagicNumberLength = MagicNumbers.Max(m => m.Length);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected abstract void Initialize();
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected HashSet<string> Extensions { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected List<byte[]> MagicNumbers { get; } = [];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected int MaxMagicNumberLength { get; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected string TypeName { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="extension"></param>
|
|
/// <returns></returns>
|
|
public bool IsIncludedExtension(string extension) => Extensions.Contains(extension);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public Result Validate(IFormFile file)
|
|
{
|
|
using var stream = file.OpenReadStream();
|
|
Span<byte> initialBytes = stackalloc byte[MaxMagicNumberLength];
|
|
_ = stream.Read(initialBytes);
|
|
foreach (var magicNumber in MagicNumbers)
|
|
{
|
|
if (initialBytes[..magicNumber.Length].SequenceCompareTo(magicNumber) == 0)
|
|
{
|
|
return new Result(true, Status.GENUINE, $"{Status.GENUINE} {TypeName}");
|
|
}
|
|
}
|
|
|
|
return new Result(false, Status.FAKE, $"{Status.FAKE} {TypeName}!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class ImageFile : FileFormatDescriptor
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected override void Initialize()
|
|
{
|
|
TypeName = "IMAGE FILE";
|
|
Extensions.UnionWith([".jpeg", ".jpg", ".png"]);
|
|
MagicNumbers.AddRange(
|
|
[
|
|
[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A],
|
|
[0xFF, 0xD8, 0xFF, 0xE0],
|
|
[0xFF, 0xD8, 0xFF, 0xE1],
|
|
[0xFF, 0xD8, 0xFF, 0xE2],
|
|
[0xFF, 0xD8, 0xFF, 0xE3]
|
|
]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class PdfFile : FileFormatDescriptor
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected override void Initialize()
|
|
{
|
|
TypeName = "PDF FILE";
|
|
Extensions.Add(".pdf");
|
|
MagicNumbers.Add([0x25, 0x50, 0x44, 0x46]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class ExcelFile : FileFormatDescriptor
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected override void Initialize()
|
|
{
|
|
TypeName = "EXCEL FILE";
|
|
Extensions.UnionWith([".xls", ".doc", ".ppt"]);
|
|
MagicNumbers.Add([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class ExcelxFile : FileFormatDescriptor
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
protected override void Initialize()
|
|
{
|
|
TypeName = "EXCEL FILE";
|
|
Extensions.UnionWith([".xlsx"]);
|
|
MagicNumbers.Add([0x50, 0x4B, 0x03, 0x04]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class ImageFileValidator
|
|
{
|
|
private static readonly List<FileFormatDescriptor> AllowedFormats = [new ImageFile()];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Result Validate(IFormFile file)
|
|
{
|
|
var fileExtension = Path.GetExtension(file.FileName);
|
|
var targetType = AllowedFormats.FirstOrDefault(x => x.IsIncludedExtension(fileExtension));
|
|
|
|
if (targetType is null)
|
|
{
|
|
return new Result(false, Status.NOTSUPPORTED, $"{Status.NOTSUPPORTED}");
|
|
}
|
|
|
|
return targetType.Validate(file);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class PdfFileValidator
|
|
{
|
|
private static readonly List<FileFormatDescriptor> AllowedFormats = [new PdfFile()];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Result Validate(IFormFile file)
|
|
{
|
|
var fileExtension = Path.GetExtension(file.FileName);
|
|
var targetType = AllowedFormats.FirstOrDefault(x => x.IsIncludedExtension(fileExtension));
|
|
|
|
if (targetType is null)
|
|
{
|
|
return new Result(false, Status.NOTSUPPORTED, $"{Status.NOTSUPPORTED}");
|
|
}
|
|
|
|
return targetType.Validate(file);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class ExcelFileValidator
|
|
{
|
|
private static readonly List<FileFormatDescriptor> AllowedFormats = [new ExcelFile()];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Result Validate(IFormFile file)
|
|
{
|
|
var fileExtension = Path.GetExtension(file.FileName);
|
|
var targetType = AllowedFormats.FirstOrDefault(x => x.IsIncludedExtension(fileExtension));
|
|
|
|
if (targetType is null)
|
|
{
|
|
return new Result(false, Status.NOTSUPPORTED, $"{Status.NOTSUPPORTED}");
|
|
}
|
|
|
|
return targetType.Validate(file);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static class ExcelxFileValidator
|
|
{
|
|
private static readonly List<FileFormatDescriptor> AllowedFormats = [new ExcelxFile()];
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Result Validate(IFormFile file)
|
|
{
|
|
var fileExtension = Path.GetExtension(file.FileName);
|
|
var targetType = AllowedFormats.FirstOrDefault(x => x.IsIncludedExtension(fileExtension));
|
|
|
|
if (targetType is null)
|
|
{
|
|
return new Result(false, Status.NOTSUPPORTED, $"{Status.NOTSUPPORTED}");
|
|
}
|
|
|
|
return targetType.Validate(file);
|
|
}
|
|
}
|
|
}
|