using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Queries; using InternshipSystem.Api.Security; using InternshipSystem.Api.Service; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace InternshipSystem.Api.Controllers { [ApiController] [Route("document")] public class DocumentsController : ControllerBase { private readonly InternshipDbContext _context; private readonly FileValidator _fileValidator; public DocumentsController(InternshipDbContext context, FileValidator fileValidator) { _context = context; _fileValidator = fileValidator; } /// /// Fill out required document, /// /// Documents Scan and description, and Id of filled document /// If change was successfully registered /// If the provided query was malformed /// Id doesn't match any required document /// This action is only available for authorized student registered for current edition [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [Authorize(Policy = Policies.RegisteredOnly)] public async Task AddDocumentToInternship( [FromBody] DocumentPublishRequest documentRequest, [FromServices] User user, CancellationToken cancellationToken) { var validator = new DocumentPublishRequest.Validator(); var result = await validator.ValidateAsync(documentRequest, cancellationToken); if (!result.IsValid) { return BadRequest(result.ToString()); } 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.AddNewDocument(documentRequest.Description, documentRequest.Type); await _context.SaveChangesAsync(cancellationToken); return Ok(); } [HttpPut("{documentId}/scan")] [Authorize(Policy = Policies.RegisteredOnly)] public async Task 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); var document = internship.Documentation.First(d => d.Id == documentId); document.Scan = new DocumentScan { File = memoryStream.ToArray() }; document.State = DocumentState.Submitted; await _context.SaveChangesAsync(cancellationToken); return Ok(); } [HttpGet("{documentId}/scan")] [Authorize(Policy = Policies.RegisteredOnly)] public async Task GetDocumentScan(long documentId, [FromServices] User user, CancellationToken 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); var document = await _context.Entry(internship) .Collection(i => i.Documentation) .Query() .Include(d => d.Scan) .FirstOrDefaultAsync(d => d.Id == documentId, cancellationToken); var stream = new MemoryStream(document.Scan.File); return File(stream, "application/pdf"); } } }