using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.Services; using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Models; 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; namespace EnvelopeGenerator.Web.Controllers { public class HomeController : BaseController { private readonly EnvelopeOldService envelopeOldService; private readonly IEnvelopeReceiverService _envRcvService; private readonly IEnvelopeService _envelopeService; private readonly IEnvelopeHistoryService _historyService; public HomeController(DatabaseService databaseService, EnvelopeOldService envelopeOldService, ILogger logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeService envelopeService, IEnvelopeHistoryService historyService) : base(databaseService, logger) { this.envelopeOldService = envelopeOldService; _envRcvService = envelopeReceiverService; _envelopeService = envelopeService; _historyService = historyService; } [HttpGet("/EnvelopeKey/{envelopeReceiverId}")] public async Task SendAccessCode([FromRoute] string envelopeReceiverId) { ViewData["EnvelopeKey"] = envelopeReceiverId; try { (string envelopeUuid, string receiverSignature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); var envelopeResult = await _envelopeService.ReadByUuidAsync(envelopeUuid, signature: receiverSignature, withEnvelopeReceivers:true); var envelope = envelopeResult.Data; var envelopeReceiver = envelope?.EnvelopeReceivers?.FirstOrDefault(); var mailAddress = envelopeReceiver?.Receiver?.EmailAddress; var useAccessCode = envelope?.UseAccessCode; ViewData["EnvelopeResult"] = envelopeResult; if(envelopeResult.IsSuccess && envelope is not null && 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 { envelopeResult.WithMessageKey(MessageKey.FailedToSendAccessCode); _logger.LogError($"{MessageKey.FailedToSendAccessCode.ToString()}"); } } catch(Exception ex) { _logger.LogError(ex, MessageKey.UnexpectedError.ToString()); } return Redirect($"{envelopeReceiverId}/Locked"); } [HttpGet("EnvelopeKey/{envelopeReceiverId}/Locked")] public IActionResult EnvelopeLocked([FromRoute] string envelopeReceiverId) { (string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId(); if (uuid is null || signature is null) { return View("_Error", new ErrorViewModel() { Title = "404", Subtitle = "Anfrage fehlgeschlagen!", Body = "Das angeforderte Umschlag wurde nicht gefunden." }); } return View().WithData("EnvelopeKey", envelopeReceiverId); } [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.LogWarning($"{MessageKey.WrongEnvelopeReceiverId.ToString()}"); 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 Redirect($"/EnvelopeKey/{envelopeReceiverId}/Success"); } 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) { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); ViewData["EnvelopeKey"] = envelopeReceiverId; return View(); } [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 }); } [HttpGet("Error")] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(); } } }