Developer 02 6338b81571 Refaktorisierung: Absicherung von DB-Operationen und Verbesserung der Geschäftslogik
- Implementierung von LINQ-Abfragen innerhalb der Core-Bibliothek zur Minderung von SQL-Injection-Anfälligkeiten für DB-Operationen von Umschlägen und Empfängern.
- Aktualisierung der Geschäftslogik in der Service-Schicht für verbessertes Transaktionshandling.
- Erweiterung der ServiceMessage um eine neue Flag-Funktion zum Verfolgen von Cybersecurity- und Datenintegritätsproblemen.
- Hinzufügen spezifischer Benutzerverhaltensflags zur besseren Erkennung und Behandlung potenzieller Datenverletzungen.
2024-04-24 13:45:03 +02:00

188 lines
8.8 KiB
C#

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.Diagnostics;
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 IConfiguration _config;
private readonly IEnvelopeReceiverService _envRcvService;
private readonly IEnvelopeService _envelopeService;
private readonly IEnvelopeHistoryService _historyService;
public HomeController(DatabaseService databaseService, EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IConfiguration configuration, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeService envelopeService, IEnvelopeHistoryService historyService) : base(databaseService, logger)
{
this.envelopeOldService = envelopeOldService;
_envRcvService = envelopeReceiverService;
_envelopeService = envelopeService;
_config = configuration;
_historyService = historyService;
}
[HttpGet("/EnvelopeKey/{envelopeReceiverId}")]
public async Task<IActionResult> 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 View("EnvelopeLocked").WithData("EnvelopeKey", envelopeReceiverId);
}
[HttpGet("EnvelopeKey/{envelopeReceiverId}/Locked")]
public IActionResult EnvelopeLocked([FromRoute] string envelopeReceiverId)
{
return View().WithData("EnvelopeKey", envelopeReceiverId);
}
[HttpPost("/EnvelopeKey/{envelopeReceiverId}/Locked")]
public async Task<IActionResult> 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<Claim>
{
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<IActionResult> 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(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}