using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Services; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using DigitalData.Core.API; using DigitalData.Core.Application; using EnvelopeGenerator.Application; using DigitalData.Core.Contracts.CultureServices; using DigitalData.Core.CultureServices; using Azure; namespace EnvelopeGenerator.Web.Controllers { public class HomeController : BaseController { private readonly EnvelopeOldService envelopeOldService; private readonly IEnvelopeReceiverService _envRcvService; private readonly IEnvelopeService _envelopeService; private readonly IEnvelopeHistoryService _historyService; private readonly IKeyTranslationService _translator; public HomeController(DatabaseService databaseService, EnvelopeOldService envelopeOldService, ILogger logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeService envelopeService, IEnvelopeHistoryService historyService, IKeyTranslationService keyTranslationService) : base(databaseService, logger) { this.envelopeOldService = envelopeOldService; _envRcvService = envelopeReceiverService; _envelopeService = envelopeService; _historyService = historyService; _translator = keyTranslationService; } [HttpGet("/EnvelopeKey/{envelopeReceiverId}")] public async Task SendAccessCode([FromRoute] string envelopeReceiverId) { ViewData["EnvelopeKey"] = envelopeReceiverId; try { var erResult = await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId); var er = erResult.Data; var receiver = er?.Receiver; var envelope = er?.Envelope; var mailAddress = receiver?.EmailAddress; if (erResult is null) { _logger.LogError(MessageKey.ServiceOutputNullError.TranslateWith(_translator)); return this.ViewEnvelopeNotFound(); } else if (erResult.IsSuccess && mailAddress is not null && (envelope?.UseAccessCode ?? false)) { EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); bool accessCodeAlreadyRequested = database.Models.receiverModel.AccessCodeAlreadyRequested(response.Receiver.Email, response.Envelope.Id); accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: envelope.Id, userReference: mailAddress); if (!accessCodeAlreadyRequested) { // Send email with password bool actionResult = database.Services.actionService.RequestAccessCode(response.Envelope, response.Receiver); bool result = database.Services.emailService.SendDocumentAccessCodeReceivedEmail(response.Envelope, response.Receiver); } } else { _logger.LogServiceMessage(erResult); return this.ViewEnvelopeNotFound(); } } catch(Exception ex) { _logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception:ex, message: MessageKey.UnexpectedError.TranslateWith(_translator)); return this.ViewInnerServiceError(); } return Redirect($"{envelopeReceiverId}/Locked"); } [HttpGet("EnvelopeKey/{envelopeReceiverId}/Locked")] public async Task EnvelopeLocked([FromRoute] string envelopeReceiverId) { try { var result = await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId); bool isExisting = result.Data; if (result.HasFlag(EnvelopeFlag.NonDecodableEnvelopeReceiverId) || !isExisting) return this.ViewEnvelopeNotFound(); return View().WithData("EnvelopeKey", envelopeReceiverId); } catch(Exception ex) { _logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex); return this.ViewInnerServiceError(); } } [HttpPost("/EnvelopeKey/{envelopeReceiverId}/Locked")] public async Task LogInEnvelope([FromRoute] string envelopeReceiverId, [FromForm] string access_code) { try { (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); if(uuid is null || signature is null) { _logger.LogEnvelopeError(uuid: uuid, signature: signature, message: MessageKey.WrongEnvelopeReceiverId.TranslateWith(_translator)); return BadRequest(_envelopeService.CreateMessage(false, MessageKey.WrongEnvelopeReceiverId.ToString())); } _logger.LogInformation($"Envelope UUID: [{uuid}]\nReceiver Signature: [{signature}]"); var verification = await _envRcvService.VerifyAccessCodeAsync(uuid: uuid, signature: signature, accessCode: access_code); var isVerified = verification.Data; EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); if (!verification.IsSuccess) { _logger.LogServiceMessage(verification); if (verification.HasFlag(Flag.SecurityBreach)) return Forbid(); return StatusCode(StatusCodes.Status500InternalServerError, verification.ClientMessages.Join()); } else if (isVerified) { if (envelopeOldService.ReceiverAlreadySigned(response.Envelope, response.Receiver.Id)) { return View("EnvelopeSigned"); } var envelope = await _envelopeService.ReadByUuidAsync(uuid: uuid, signature: signature, withAll: true); database.Services.actionService.EnterCorrectAccessCode(response.Envelope, response.Receiver); //for history ViewData["EnvelopeKey"] = envelopeReceiverId; ViewData["EnvelopeResponse"] = response; if (response.Envelope.Documents.Count() > 0) { var document = await envelopeOldService.GetDocument(response.Envelope.Documents[0].Id, envelopeReceiverId); byte[] bytes = await envelopeOldService.GetDocumentContents(document); ViewData["DocumentBytes"] = bytes; } else ViewData["DocumentBytes"] = null; var claims = new List { new Claim(ClaimTypes.NameIdentifier, uuid), new Claim(ClaimTypes.Hash, signature), }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var authProperties = new AuthenticationProperties { }; await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties); return View("ShowEnvelope", envelope); } else { database.Services.actionService.EnterIncorrectAccessCode(response.Envelope, response.Receiver); //for history _logger.LogWarning(string.Join("\n", verification.Messages)); return Unauthorized(); } } catch(Exception ex) { _logger.LogError(ex, MessageKey.UnexpectedError.ToString()); return this.InnerServiceError(messageKey: MessageKey.UnexpectedError); } } [HttpGet("/EnvelopeKey/{envelopeReceiverId}/Success")] public async Task EnvelopeSigned(string envelopeReceiverId) { try { var result = await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId); bool isExisting = result.Data; if (result.HasFlag(EnvelopeFlag.NonDecodableEnvelopeReceiverId) || !isExisting) return this.ViewEnvelopeNotFound(); EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId); if (!envelopeOldService.ReceiverAlreadySigned(response.Envelope, response.Receiver.Id)) { return Redirect($"/EnvelopeKey/{envelopeReceiverId}/Locked"); } await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); ViewData["EnvelopeKey"] = envelopeReceiverId; return View(); } catch (Exception ex) { _logger.LogEnvelopeError(envelopeEeceiverId: envelopeReceiverId, exception: ex); return this.ViewInnerServiceError(); } } [Authorize] [HttpGet("IsAuthenticated")] public IActionResult IsAuthenticated() { var envelopeUuid = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; var receiverSignature = User.FindFirst(ClaimTypes.Hash)?.Value; return Ok(new { EnvelopeUuid = envelopeUuid, ReceiverSignature = receiverSignature }); } public IActionResult Error404() => this.ViewError404(); } }