feat(EnvelopeReceiverReadOnly): Created endpoint for ShowEnvelope view

This commit is contained in:
Developer 02 2024-10-04 11:28:52 +02:00
parent dc997d5ff2
commit bc6955055a
3 changed files with 38 additions and 18 deletions

View File

@ -64,34 +64,34 @@ namespace EnvelopeGenerator.Extensions
return input.IndexOf('=') == -1; // No padding allowed except at the end return input.IndexOf('=') == -1; // No padding allowed except at the end
} }
public static bool TryDecode(this string encoded, out string[] decoded) public static bool TryDecode(this string encodedKey, out string[] decodedKeys)
{ {
if (!encoded.IsBase64String()) if (!encodedKey.IsBase64String())
{ {
decoded = Array.Empty<string>(); decodedKeys = Array.Empty<string>();
return false; return false;
} }
byte[] bytes = Convert.FromBase64String(encoded); byte[] bytes = Convert.FromBase64String(encodedKey);
string decodedString = Encoding.UTF8.GetString(bytes); string decodedString = Encoding.UTF8.GetString(bytes);
decoded = decodedString.Split(new string[] { "::" }, StringSplitOptions.None); decodedKeys = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
return true; return true;
} }
public static EncodeType GetEncodeType(this string[] decoded) => decoded.Length switch public static EncodeType GetEncodeType(this string[] decodedKeys) => decoded.Length switch
{ {
2 => EncodeType.EnvelopeReceiver, 2 => EncodeType.EnvelopeReceiver,
3 => long.TryParse(decoded[1], out var _) ? EncodeType.EnvelopeReceiverReadOnly : EncodeType.Undefined, 3 => long.TryParse(decoded[1], out var _) ? EncodeType.EnvelopeReceiverReadOnly : EncodeType.Undefined,
_ => EncodeType.Undefined, _ => EncodeType.Undefined,
}; };
public static (string? EnvelopeUuid, string? ReceiverSignature) ToEnvelopeReceiverId(this string[] decoded) public static (string? EnvelopeUuid, string? ReceiverSignature) ParseEnvelopeReceiverId(this string[] decodedKeys)
=> decoded.GetEncodeType() == EncodeType.EnvelopeReceiver => decodedKeys.GetEncodeType() == EncodeType.EnvelopeReceiver
? (EnvelopeUuid: decoded[0], ReceiverSignature: decoded[1]) ? (EnvelopeUuid: decodedKeys[0], ReceiverSignature: decodedKeys[1])
: throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. "); : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver.");
public static long ToReadOnlyId(this string[] decoded) public static long ParseReadOnlyId(this string[] decodedKeys)
=> decoded.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly => decodedKeys.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly
? long.Parse(decoded[1]) ? long.Parse(decodedKeys[1])
: throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. "); : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
/// <summary> /// <summary>

View File

@ -10,6 +10,7 @@ namespace EnvelopeGenerator.Extensions
{ {
public static string EncodeEnvelopeReceiverId(this long readOnlyId) public static string EncodeEnvelopeReceiverId(this long readOnlyId)
{ {
//The random number is used as a salt to increase security but it is not saved in the database.
string combinedString = $"{Random.Shared.Next()}::{readOnlyId}::{Random.Shared.Next()}"; string combinedString = $"{Random.Shared.Next()}::{readOnlyId}::{Random.Shared.Next()}";
byte[] bytes = Encoding.UTF8.GetBytes(combinedString); byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
string base64String = Convert.ToBase64String(bytes); string base64String = Convert.ToBase64String(bytes);

View File

@ -15,8 +15,6 @@ using System.Text.Encodings.Web;
using EnvelopeGenerator.Web.Models; using EnvelopeGenerator.Web.Models;
using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Domain.Entities;
using System.Text.RegularExpressions;
using static EnvelopeGenerator.Common.Constants; using static EnvelopeGenerator.Common.Constants;
namespace EnvelopeGenerator.Web.Controllers namespace EnvelopeGenerator.Web.Controllers
@ -307,15 +305,36 @@ namespace EnvelopeGenerator.Web.Controllers
} }
[Authorize] [Authorize]
[HttpGet("EnvelopeKey/{envelopeReceiverId}/ReadOnly")] [HttpGet("EnvelopeKey/{readOnlyId}/ReadOnly")]
public async Task<IActionResult> EnvelopeReceiverReadOnly(string readOnlyId) public async Task<IActionResult> EnvelopeReceiverReadOnly(string readOnlyKey)
{ {
try try
{ {
return Ok(); readOnlyKey = _urlEncoder.Encode(readOnlyKey);
// check if the readOnlyId is valid
if (!readOnlyKey.TryDecode(out var decodedKeys) || decodedKeys.GetEncodeType() != EncodeType.EnvelopeReceiverReadOnly)
{
Response.StatusCode = StatusCodes.Status401Unauthorized;
return this.ViewDocumentNotFound();
}
var readOnlyId = decodedKeys.ParseReadOnlyId();
return await _readOnlyService.ReadByIdAsync(readOnlyId).ThenAsync(
Success: erro =>
{
ViewData["model"] = erro;
return View("ShowEnvelope");
},
Fail: IActionResult (msg, ntc) =>
{
_logger.LogNotice(ntc);
return this.ViewInnerServiceError();
});
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "An unexpected error occurred while displaying a read-only envelope. Read-only key is {readOnlyKey}. {message}", readOnlyKey, ex.Message);
return this.ViewInnerServiceError(); return this.ViewInnerServiceError();
} }
} }