enotaryo-landing/EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs

145 lines
6.2 KiB
C#

using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;
using Exadel.Compreface.Clients.CompreFaceClient;
using Exadel.Compreface.DTOs.FaceVerificationDTOs.FaceVerification;
using Exadel.Compreface.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace EnotaryoPH.Web.Pages
{
public class BaseTakeSelfiePageModel : PageModel
{
protected readonly NotaryoDBContext _notaryoDBContext;
private readonly ICompreFaceClient _compreFaceClient;
private readonly IConfiguration _configuration;
private readonly ICurrentUserService _currentUserService;
private Transaction _transactionEntity;
private User _user;
public BaseTakeSelfiePageModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration)
{
_notaryoDBContext = notaryoDBContext;
_currentUserService = currentUserService;
_compreFaceClient = compreFaceClient;
_configuration = configuration;
}
protected async Task<bool> PostAsync()
{
var selfieImage = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]) ?? [];
var identificationDocument = _notaryoDBContext.IdentificationDocuments.First(e => e.UserID == CurrentUser.UserID);
var faceMatches = await VerifySelfieAsync(selfieImage, identificationDocument);
var isMatchSuccess = faceMatches.Any();
if (isMatchSuccess)
{
var signatory = _notaryoDBContext.TransactionSignatories.FirstOrDefault(x => x.UserID == CurrentUser.UserID);
if (signatory != null)
{
signatory.Status = nameof(SignatoryStatus.FaceMatch);
_notaryoDBContext.Update(signatory);
}
else if (!CurrentUser.Role.IsInList(nameof(UserType.Principal), nameof(UserType.SuperUser), nameof(UserType.Administrator)))
{
return false;
}
if (CurrentTransaction.TransactionID == 0)
{
var newTransaction = new Transaction
{
Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow),
CreatedOn = DateTime.UtcNow,
TransactionDate = DateTime.UtcNow,
Status = nameof(TransactionState.New),
PrincipalID = CurrentUser.UserID
};
_notaryoDBContext.Add(CurrentTransaction);
}
var selfieEntity = CreateOrUpdateSelfie(selfieImage);
selfieEntity.Transaction = CurrentTransaction;
if (_notaryoDBContext.Entry(selfieEntity).State == EntityState.Detached)
{
_notaryoDBContext.Add(selfieEntity);
}
else
{
_notaryoDBContext.Update(selfieEntity);
}
_notaryoDBContext.SaveChanges();
}
return isMatchSuccess;
}
private TransactionSelfie CreateOrUpdateSelfie(byte[] selfieImage)
{
TransactionSelfie selfieEntity;
if (TransactionSelfie_UID == Guid.Empty)
{
selfieEntity = new TransactionSelfie
{
CreatedOn = DateTime.UtcNow,
TransactionSelfie_UID = Guid.CreateVersion7(DateTime.UtcNow),
UserID = CurrentUser.UserID,
TransactionID = CurrentTransaction.TransactionID,
};
TransactionSelfie_UID = selfieEntity.TransactionSelfie_UID.Value;
}
else
{
selfieEntity = _notaryoDBContext.TransactionSelfies.FirstOrDefault(e => e.TransactionSelfie_UID == TransactionSelfie_UID);
}
selfieEntity.File = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]);
return selfieEntity;
}
private async Task<IEnumerable<FaceMatches>> VerifySelfieAsync(byte[] selfieImage, IdentificationDocument identificationDocument)
{
var selfiePath = Path.Combine(Path.GetTempPath(), "Selfies");
if (!Directory.Exists(selfiePath))
{
Directory.CreateDirectory(selfiePath);
}
var identificationDocumentPath = Path.Combine(selfiePath, $"{identificationDocument.IdentificationDocument_UID}.jpg");
var apiKey = _configuration.GetValue<string>("CompreFaceConfig:APIKey");
var client = _compreFaceClient.GetCompreFaceService<VerificationService>(apiKey);
var faceVerificationRequest = new FaceVerificationRequestByBytes()
{
SourceImageInBytes = selfieImage,
TargetImageInBytes = identificationDocument.File,
DetProbThreshold = 0.81m,
Limit = 1,
Status = false,
FacePlugins = []
};
var result = await client.VerifyAsync(faceVerificationRequest);
var faceMatches = result.Result.SelectMany(x => x.FaceMatches);
return faceMatches;
}
[BindProperty]
public string SelfieBase64Image { get; set; }
[BindProperty(SupportsGet = true)]
public Guid Transaction_UID { get; set; }
[BindProperty(SupportsGet = true)]
public Guid TransactionSelfie_UID { get; set; }
protected User CurrentUser => _user ??= _notaryoDBContext.Users.AsNoTracking().First(x => x.User_UID == _currentUserService.GetUser_UID());
protected Transaction CurrentTransaction => _transactionEntity
??= _notaryoDBContext.Transactions.AsNoTracking().FirstOrDefault(x => x.Transaction_UID == Transaction_UID)
?? new Transaction
{
Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow),
CreatedOn = DateTime.UtcNow,
TransactionDate = DateTime.UtcNow,
Status = nameof(TransactionState.New),
PrincipalID = CurrentUser.UserID
};
}
}