add document scan endpoint
This commit is contained in:
parent
b98ab42c4d
commit
b1db47726a
@ -1,11 +1,14 @@
|
|||||||
using System.Threading;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using InternshipSystem.Api.Queries;
|
using InternshipSystem.Api.Queries;
|
||||||
using InternshipSystem.Api.Security;
|
using InternshipSystem.Api.Security;
|
||||||
using InternshipSystem.Api.Services;
|
using InternshipSystem.Api.Service;
|
||||||
|
using InternshipSystem.Repository;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace InternshipSystem.Api.Controllers
|
namespace InternshipSystem.Api.Controllers
|
||||||
{
|
{
|
||||||
@ -13,11 +16,13 @@ namespace InternshipSystem.Api.Controllers
|
|||||||
[Route("document")]
|
[Route("document")]
|
||||||
public class DocumentsController : ControllerBase
|
public class DocumentsController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IInternshipService _internshipService;
|
private readonly InternshipDbContext _context;
|
||||||
|
private readonly FileValidator _fileValidator;
|
||||||
|
|
||||||
public DocumentsController(IInternshipService internshipService)
|
public DocumentsController(InternshipDbContext context, FileValidator fileValidator)
|
||||||
{
|
{
|
||||||
_internshipService = internshipService;
|
_context = context;
|
||||||
|
_fileValidator = fileValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -34,18 +39,55 @@ namespace InternshipSystem.Api.Controllers
|
|||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
[Authorize(Policy = Policies.RegisteredOnly)]
|
[Authorize(Policy = Policies.RegisteredOnly)]
|
||||||
public async Task<ActionResult> AddDocumentToInternship([FromBody] DocumentPublishRequest documentRequest,
|
public async Task<ActionResult> AddDocumentToInternship(
|
||||||
[FromServices] User user, CancellationToken cancellationToken)
|
[FromBody] DocumentPublishRequest documentRequest,
|
||||||
|
[FromServices] User user,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var validator = new DocumentPublishRequest.Validator();
|
var validator = new DocumentPublishRequest.Validator();
|
||||||
var validationResult = await validator.ValidateAsync(documentRequest, cancellationToken);
|
var result = await validator.ValidateAsync(documentRequest, cancellationToken);
|
||||||
|
|
||||||
if (!validationResult.IsValid)
|
if (!result.IsValid)
|
||||||
{
|
{
|
||||||
return BadRequest(validationResult.ToString());
|
return BadRequest(result.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _internshipService.AddDocumentToInternship(documentRequest, user, cancellationToken);
|
var edition = await _context.Editions.FirstAsync(e => e.Id == user.EditionId, cancellationToken);
|
||||||
|
|
||||||
|
var internship =
|
||||||
|
await _context.Entry(edition)
|
||||||
|
.Collection(e => e.Internships)
|
||||||
|
.Query()
|
||||||
|
.FirstAsync(i => i.Student.Id == user.PersonNumber, cancellationToken);
|
||||||
|
|
||||||
|
internship.AddNewDocument(documentRequest.Description, documentRequest.Type);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{documentId}/scan")]
|
||||||
|
public async Task<ActionResult> AddDocumentScan(long documentId, IFormFile documentScan, [FromServices] User user, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await using var memoryStream = new MemoryStream();
|
||||||
|
await documentScan.CopyToAsync(memoryStream, cancellationToken);
|
||||||
|
|
||||||
|
if (!_fileValidator.IsValidFile(memoryStream.ToArray()))
|
||||||
|
{
|
||||||
|
return BadRequest("error.document.scan");
|
||||||
|
}
|
||||||
|
|
||||||
|
var edition = await _context.Editions.FirstAsync(e => e.Id == user.EditionId, cancellationToken);
|
||||||
|
|
||||||
|
var internship =
|
||||||
|
await _context.Entry(edition)
|
||||||
|
.Collection(e => e.Internships)
|
||||||
|
.Query()
|
||||||
|
.Include(i => i.Documentation)
|
||||||
|
.FirstAsync(i => i.Student.Id == user.PersonNumber, cancellationToken);
|
||||||
|
|
||||||
|
internship.UpdateDocumentScan(documentId, memoryStream.ToArray());
|
||||||
|
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using InternshipSystem.Core.ValueObject;
|
using InternshipSystem.Core.ValueObject;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace InternshipSystem.Api.Queries
|
namespace InternshipSystem.Api.Queries
|
||||||
{
|
{
|
||||||
@ -7,14 +8,12 @@ namespace InternshipSystem.Api.Queries
|
|||||||
{
|
{
|
||||||
public long? Id { get; set; }
|
public long? Id { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public byte[] Scan { get; set; }
|
|
||||||
public DocumentType Type { get; set; }
|
public DocumentType Type { get; set; }
|
||||||
|
|
||||||
public class Validator : AbstractValidator<DocumentPublishRequest>
|
public class Validator : AbstractValidator<DocumentPublishRequest>
|
||||||
{
|
{
|
||||||
public Validator()
|
public Validator()
|
||||||
{
|
{
|
||||||
RuleFor(document => document.Scan).NotEmpty();
|
|
||||||
RuleFor(document => document.Type).NotEmpty();
|
RuleFor(document => document.Type).NotEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
src/InternshipSystem.Api/Service/FileValidator.cs
Normal file
30
src/InternshipSystem.Api/Service/FileValidator.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace InternshipSystem.Api.Service
|
||||||
|
{
|
||||||
|
public class FileValidator
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, byte[]> validFileTypes;
|
||||||
|
|
||||||
|
public FileValidator()
|
||||||
|
{
|
||||||
|
validFileTypes = new Dictionary<string, byte[]> {
|
||||||
|
{ "pdf", new byte[] { 0x25, 0x50, 0x44, 0x46 } }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValidFile(byte[] scan)
|
||||||
|
{
|
||||||
|
return IsFileValidType(scan);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsFileValidType(byte[] scan)
|
||||||
|
{
|
||||||
|
var validSignatures = validFileTypes.Values;
|
||||||
|
var header = scan[..4];
|
||||||
|
|
||||||
|
return validSignatures.Any(sig => header.SequenceEqual(header));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using InternshipSystem.Api.Queries;
|
|
||||||
using InternshipSystem.Api.Security;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace InternshipSystem.Api.Services
|
|
||||||
{
|
|
||||||
public interface IInternshipService
|
|
||||||
{
|
|
||||||
Task<ActionResult> AddDocumentToInternship(DocumentPublishRequest documentRequest, User user, CancellationToken cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AutoMapper;
|
|
||||||
using InternshipSystem.Api.Queries;
|
|
||||||
using InternshipSystem.Api.Security;
|
|
||||||
using InternshipSystem.Core;
|
|
||||||
using InternshipSystem.Repository;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace InternshipSystem.Api.Services
|
|
||||||
{
|
|
||||||
public class InternshipService : IInternshipService
|
|
||||||
{
|
|
||||||
private readonly InternshipDbContext _context;
|
|
||||||
private IMapper Mapper { get; }
|
|
||||||
|
|
||||||
public InternshipService(InternshipDbContext context, IMapper mapper)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
Mapper = mapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ActionResult> AddDocumentToInternship(DocumentPublishRequest documentRequest, User user,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var edition = await _context.Editions.FindAsync(user.EditionId);
|
|
||||||
|
|
||||||
var internship = await _context.Entry(edition)
|
|
||||||
.Collection(e => e.Internships)
|
|
||||||
.Query()
|
|
||||||
.Include(i => i.Documentation)
|
|
||||||
.SingleAsync(i => i.Student.Id == user.PersonNumber, cancellationToken);
|
|
||||||
|
|
||||||
var document = Mapper.Map<Document>(documentRequest);
|
|
||||||
|
|
||||||
if (documentRequest.Id.HasValue)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
internship.UpdateDocument(document);
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException)
|
|
||||||
{
|
|
||||||
return new NotFoundResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
internship.AddNewDocument(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
|
||||||
return new OkResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ using InternshipSystem.Api.Extensions;
|
|||||||
using InternshipSystem.Api.ModelBinders;
|
using InternshipSystem.Api.ModelBinders;
|
||||||
using InternshipSystem.Api.Options;
|
using InternshipSystem.Api.Options;
|
||||||
using InternshipSystem.Api.Security;
|
using InternshipSystem.Api.Security;
|
||||||
using InternshipSystem.Api.Services;
|
using InternshipSystem.Api.Service;
|
||||||
using InternshipSystem.Repository;
|
using InternshipSystem.Repository;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -44,7 +44,7 @@ namespace InternshipSystem.Api
|
|||||||
.AddDbContext<InternshipDbContext>(o =>
|
.AddDbContext<InternshipDbContext>(o =>
|
||||||
o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase")))
|
o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase")))
|
||||||
.AddScoped<DatabaseFiller>()
|
.AddScoped<DatabaseFiller>()
|
||||||
.AddScoped<IInternshipService, InternshipService>()
|
.AddScoped<FileValidator>()
|
||||||
.AddScoped<JwtTokenService>()
|
.AddScoped<JwtTokenService>()
|
||||||
.AddAutoMapper(cfg => cfg.AddProfile<ApiProfile>());
|
.AddAutoMapper(cfg => cfg.AddProfile<ApiProfile>());
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using InternshipSystem.Core.ValueObject;
|
||||||
|
|
||||||
namespace InternshipSystem.Core.Entity.Internship
|
namespace InternshipSystem.Core.Entity.Internship
|
||||||
{
|
{
|
||||||
@ -16,23 +17,6 @@ namespace InternshipSystem.Core.Entity.Internship
|
|||||||
|
|
||||||
public float? Grade { get; set; }
|
public float? Grade { get; set; }
|
||||||
|
|
||||||
public void UpdateDocument(Document document)
|
|
||||||
{
|
|
||||||
var oldDocument = Documentation.First(d => d.Id == document.Id);
|
|
||||||
|
|
||||||
oldDocument.Description = document.Description ?? oldDocument.Description;
|
|
||||||
oldDocument.Scan = document.Scan ?? oldDocument.Scan;
|
|
||||||
oldDocument.Type = document.Type;
|
|
||||||
oldDocument.State = DocumentState.Submitted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddNewDocument(Document document)
|
|
||||||
{
|
|
||||||
document.State = DocumentState.Submitted;
|
|
||||||
|
|
||||||
Documentation.Add(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Internship CreateStudentsInternship(Student student)
|
public static Internship CreateStudentsInternship(Student student)
|
||||||
{
|
{
|
||||||
var internship = new Internship();
|
var internship = new Internship();
|
||||||
@ -46,5 +30,25 @@ namespace InternshipSystem.Core.Entity.Internship
|
|||||||
|
|
||||||
return internship;
|
return internship;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddNewDocument(string description, DocumentType type)
|
||||||
|
{
|
||||||
|
var document = new Document
|
||||||
|
{
|
||||||
|
Description = description,
|
||||||
|
Type = type,
|
||||||
|
State = DocumentState.Draft
|
||||||
|
};
|
||||||
|
|
||||||
|
Documentation.Add(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDocumentScan(long documentId, byte[] documentScan)
|
||||||
|
{
|
||||||
|
var document = Documentation.First(d => d.Id == documentId);
|
||||||
|
|
||||||
|
document.Scan = documentScan;
|
||||||
|
document.State = DocumentState.Submitted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user