using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace OnlineSalesAutoCrop.CoreAPI.Configurations { /// /// /// /// /// /// public record Result(bool Acceptable, Status Status, string Message); /// /// /// public enum Status { /// /// /// GENUINE, /// /// /// FAKE, /// /// /// NOTSUPPORTED } /// /// /// public abstract class FileFormatDescriptor { /// /// /// protected FileFormatDescriptor() { Initialize(); MaxMagicNumberLength = MagicNumbers.Max(m => m.Length); } /// /// /// protected abstract void Initialize(); /// /// /// protected HashSet Extensions { get; } = new HashSet(StringComparer.OrdinalIgnoreCase); /// /// /// protected List MagicNumbers { get; } = []; /// /// /// protected int MaxMagicNumberLength { get; } /// /// /// protected string TypeName { get; set; } /// /// /// /// /// public bool IsIncludedExtension(string extension) => Extensions.Contains(extension); /// /// /// /// /// public Result Validate(IFormFile file) { using var stream = file.OpenReadStream(); Span 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}!"); } } /// /// /// public class ImageFile : FileFormatDescriptor { /// /// /// 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] ]); } } /// /// /// public class PdfFile : FileFormatDescriptor { /// /// /// protected override void Initialize() { TypeName = "PDF FILE"; Extensions.Add(".pdf"); MagicNumbers.Add([0x25, 0x50, 0x44, 0x46]); } } /// /// /// public class ExcelFile : FileFormatDescriptor { /// /// /// protected override void Initialize() { TypeName = "EXCEL FILE"; Extensions.UnionWith([".xls", ".doc", ".ppt"]); MagicNumbers.Add([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]); } } /// /// /// public class ExcelxFile : FileFormatDescriptor { /// /// /// protected override void Initialize() { TypeName = "EXCEL FILE"; Extensions.UnionWith([".xlsx"]); MagicNumbers.Add([0x50, 0x4B, 0x03, 0x04]); } } /// /// /// public static class ImageFileValidator { private static readonly List AllowedFormats = [new ImageFile()]; /// /// /// /// /// 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); } } /// /// /// public static class PdfFileValidator { private static readonly List AllowedFormats = [new PdfFile()]; /// /// /// /// /// 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); } } /// /// /// public static class ExcelFileValidator { private static readonly List AllowedFormats = [new ExcelFile()]; /// /// /// /// /// 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); } } /// /// /// public static class ExcelxFileValidator { private static readonly List AllowedFormats = [new ExcelxFile()]; /// /// /// /// /// 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); } } }