diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index bb124db..4487b0a 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Net.Mime; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Queries; @@ -100,7 +101,14 @@ namespace InternshipSystem.Api.Controllers var document = internship.Documentation.First(d => d.Id == documentId); - document.Scan = new DocumentScan { File = memoryStream.ToArray() }; + document.Scan = new DocumentScan + { + File = memoryStream.ToArray(), + Size = memoryStream.Length, + Filename = documentScan.FileName, + Mime = _fileValidator.GetFileMime(memoryStream.ToArray()) + }; + document.State = DocumentState.Submitted; await _context.SaveChangesAsync(cancellationToken); @@ -110,7 +118,7 @@ namespace InternshipSystem.Api.Controllers [HttpGet("{documentId}/scan")] [Authorize(Policy = Policies.RegisteredOnly)] - public async Task GetDocumentScan(long documentId, [FromServices] User user, CancellationToken cancellationToken) + public async Task GetDocumentScan(long documentId, [FromQuery] string disposition, [FromServices] User user, CancellationToken cancellationToken) { var edition = await _context.Editions.FirstAsync(e => e.Id == user.EditionId, cancellationToken); @@ -128,8 +136,15 @@ namespace InternshipSystem.Api.Controllers .FirstOrDefaultAsync(d => d.Id == documentId, cancellationToken); var stream = new MemoryStream(document.Scan.File); + + Response.Headers.Add("Content-Disposition", new ContentDisposition + { + Inline = disposition == "inline", + FileName = document.Scan.Filename, + Size = document.Scan.Size + }.ToString()); - return File(stream, "application/pdf"); + return File(stream, document.Scan.Mime); } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Service/FileValidator.cs b/src/InternshipSystem.Api/Service/FileValidator.cs index 838081f..ab1da52 100644 --- a/src/InternshipSystem.Api/Service/FileValidator.cs +++ b/src/InternshipSystem.Api/Service/FileValidator.cs @@ -5,12 +5,15 @@ namespace InternshipSystem.Api.Service { public class FileValidator { - private readonly Dictionary validFileTypes; + private readonly List<(string Mime, byte[] Signature)> validFileTypes; public FileValidator() { - validFileTypes = new Dictionary { - { "pdf", new byte[] { 0x25, 0x50, 0x44, 0x46 } } + validFileTypes = new List<(string, byte[])> { + ("application/pdf", new byte[] { 0x25, 0x50, 0x44, 0x46 }), + ("image/jpeg", new byte[] { 0xFF, 0xD8, 0xFF, 0xDB }), + ("image/jpeg", new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }), + ("image/jpeg", new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 }) }; } @@ -21,10 +24,14 @@ namespace InternshipSystem.Api.Service private bool IsFileValidType(byte[] scan) { - var validSignatures = validFileTypes.Values; + return GetFileMime(scan) != null; + } + + public string GetFileMime(byte[] scan) + { var header = scan[..4]; - return validSignatures.Any(sig => header.SequenceEqual(header)); + return validFileTypes.FirstOrDefault(sig => sig.Signature.SequenceEqual(header)).Mime; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Document.cs b/src/InternshipSystem.Core/Entity/Document.cs index d98bb74..0033487 100644 --- a/src/InternshipSystem.Core/Entity/Document.cs +++ b/src/InternshipSystem.Core/Entity/Document.cs @@ -16,6 +16,9 @@ namespace InternshipSystem.Core { public long DocumentId { get; set; } public Document Document { get; set; } + public long Size { get; set; } + public string Filename { get; set; } + public string Mime { get; set; } public byte[] File { get; set; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Repository/Migrations/20201018000658_Init.Designer.cs b/src/InternshipSystem.Repository/Migrations/20201025211622_Init.Designer.cs similarity index 98% rename from src/InternshipSystem.Repository/Migrations/20201018000658_Init.Designer.cs rename to src/InternshipSystem.Repository/Migrations/20201025211622_Init.Designer.cs index 18c89c3..eb8a31a 100644 --- a/src/InternshipSystem.Repository/Migrations/20201018000658_Init.Designer.cs +++ b/src/InternshipSystem.Repository/Migrations/20201025211622_Init.Designer.cs @@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace InternshipSystem.Repository.Migrations { [DbContext(typeof(InternshipDbContext))] - [Migration("20201018000658_Init")] + [Migration("20201025211622_Init")] partial class Init { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -137,6 +137,18 @@ namespace InternshipSystem.Repository.Migrations .HasColumnName("file") .HasColumnType("bytea"); + b.Property("Filename") + .HasColumnName("filename") + .HasColumnType("text"); + + b.Property("Mime") + .HasColumnName("mime") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnName("size") + .HasColumnType("bigint"); + b.HasKey("DocumentId") .HasName("pk_document_scan"); diff --git a/src/InternshipSystem.Repository/Migrations/20201018000658_Init.cs b/src/InternshipSystem.Repository/Migrations/20201025211622_Init.cs similarity index 99% rename from src/InternshipSystem.Repository/Migrations/20201018000658_Init.cs rename to src/InternshipSystem.Repository/Migrations/20201025211622_Init.cs index 427f37a..95ef74e 100644 --- a/src/InternshipSystem.Repository/Migrations/20201018000658_Init.cs +++ b/src/InternshipSystem.Repository/Migrations/20201025211622_Init.cs @@ -344,6 +344,9 @@ namespace InternshipSystem.Repository.Migrations columns: table => new { document_id = table.Column(nullable: false), + size = table.Column(nullable: false), + filename = table.Column(nullable: true), + mime = table.Column(nullable: true), file = table.Column(nullable: true) }, constraints: table => diff --git a/src/InternshipSystem.Repository/Migrations/InternshipDbContextModelSnapshot.cs b/src/InternshipSystem.Repository/Migrations/InternshipDbContextModelSnapshot.cs index 2451970..aff7d9a 100644 --- a/src/InternshipSystem.Repository/Migrations/InternshipDbContextModelSnapshot.cs +++ b/src/InternshipSystem.Repository/Migrations/InternshipDbContextModelSnapshot.cs @@ -135,6 +135,18 @@ namespace InternshipSystem.Repository.Migrations .HasColumnName("file") .HasColumnType("bytea"); + b.Property("Filename") + .HasColumnName("filename") + .HasColumnType("text"); + + b.Property("Mime") + .HasColumnName("mime") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnName("size") + .HasColumnType("bigint"); + b.HasKey("DocumentId") .HasName("pk_document_scan");