Files

55 lines
2.0 KiB
C#

public class AttestationService : IAttestationService
{
private readonly AppDbContext _db;
private readonly ILogger<AttestationService> _logger;
public AttestationService(AppDbContext db, ILogger<AttestationService> logger)
{
_db = db;
_logger = logger;
}
public async Task<User> ValidateAttestationAsync(
Guid userId, bool clinicianAttestation, string passwordConfirm)
{
// 1. Attestation flag must be explicitly true
if (!clinicianAttestation)
throw new ValidationException(
"Clinician attestation is required for live capture.",
"ATTESTATION_REQUIRED");
// 2. Load user
var user = await _db.Users.FindAsync(userId);
if (user is null)
throw new NotFoundException("User not found.", "USER_NOT_FOUND");
// 3. Role check — only Clinician role can use live capture
if (user.Role != UserRole.Clinician)
throw new ValidationException(
"Only users with the Clinician role can perform live capture.",
"CLINICIAN_ROLE_REQUIRED");
// 4. Account must be active
if (!user.IsActive)
throw new ConflictException(
"Account is disabled.", "ACCOUNT_DISABLED");
// 5. Password re-confirmation — prevents unattended sessions from
// submitting clinical data without the clinician present
if (string.IsNullOrWhiteSpace(passwordConfirm))
throw new ValidationException(
"Password re-confirmation is required.",
"PASSWORD_CONFIRM_REQUIRED");
if (!BCrypt.Net.BCrypt.Verify(passwordConfirm, user.PasswordHash))
throw new ValidationException(
"Password re-confirmation failed.",
"PASSWORD_CONFIRM_INVALID");
_logger.LogInformation(
"Clinician attestation validated for user {UserId} ({FullName})",
user.Id, user.FullName);
return user;
}
}