OnlineSalesAutoCrop/Api/OnlineSalesAutoCrop.CoreAPI/Configurations/FileValidator.cs

281 lines
5.9 KiB
C#
Raw Normal View History

2026-06-14 12:46:29 +06:00
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);
}
}
}