use of io.gravitee.am.common.exception.mfa.InvalidFactorAttributeException in project gravitee-access-management by gravitee-io.
the class AccountFactorsEndpointHandler method enrollFactor.
/**
* Enroll a factor for the current user
*
* @param routingContext the routingContext holding the current user
*/
public void enrollFactor(RoutingContext routingContext) {
try {
if (routingContext.getBodyAsString() == null) {
routingContext.fail(new InvalidRequestException("Unable to parse body message"));
return;
}
final User user = routingContext.get(ConstantKeys.USER_CONTEXT_KEY);
final io.gravitee.am.gateway.handler.account.model.Enrollment enrollment = Json.decodeValue(routingContext.getBodyAsString(), io.gravitee.am.gateway.handler.account.model.Enrollment.class);
// factorId is required
if (isEmpty(enrollment.getFactorId())) {
routingContext.fail(new InvalidRequestException("Field [factorId] is required"));
return;
}
final String factorId = enrollment.getFactorId();
final EnrollmentAccount account = enrollment.getAccount();
// find factor
findFactor(factorId, h -> {
if (h.failed()) {
routingContext.fail(h.cause());
return;
}
final Factor factor = h.result();
final FactorProvider factorProvider = factorManager.get(factorId);
if (factorProvider == null) {
routingContext.fail(new FactorNotFoundException(factorId));
return;
}
if (isRecoveryCodeFactor(factor)) {
routingContext.fail(new InvalidRequestException("Recovery code does not support enrollment feature. Instead, use '/api/recovery_code' endpoint to generate recovery code."));
return;
}
// check request body parameters
switch(factor.getFactorType()) {
case CALL:
case SMS:
if (isNull(account) || isEmpty(account.getPhoneNumber())) {
routingContext.fail(new InvalidRequestException("Field [phoneNumber] is required"));
return;
}
break;
case EMAIL:
if (isNull(account) || isEmpty(account.getEmail())) {
routingContext.fail(new InvalidRequestException("Field [email] is required"));
return;
}
break;
default:
// Do nothing
break;
}
// check if the current factor is already enrolled
if (user.getFactors() != null) {
Optional<EnrolledFactor> optionalEnrolledFactor = user.getFactors().stream().filter(enrolledFactor -> factorId.equals(enrolledFactor.getFactorId())).findFirst();
if (optionalEnrolledFactor.isPresent()) {
EnrolledFactor existingEnrolledFactor = optionalEnrolledFactor.get();
if (FactorStatus.ACTIVATED.equals(existingEnrolledFactor.getStatus())) {
AccountResponseHandler.handleDefaultResponse(routingContext, existingEnrolledFactor);
return;
}
}
}
// enroll factor
enrollFactor(factor, factorProvider, account, user, eh -> {
if (eh.failed()) {
if (eh.cause() instanceof InvalidFactorAttributeException) {
routingContext.fail(400, eh.cause());
} else {
routingContext.fail(eh.cause());
}
return;
}
final EnrolledFactor enrolledFactor = eh.result();
// send challenge
sendChallenge(factorProvider, enrolledFactor, user, routingContext, sh -> {
// save enrolled factor
accountService.upsertFactor(user.getId(), enrolledFactor, new DefaultUser(user)).subscribe(__ -> AccountResponseHandler.handleDefaultResponse(routingContext, enrolledFactor), error -> routingContext.fail(error));
});
});
});
} catch (DecodeException ex) {
routingContext.fail(new InvalidRequestException("Unable to parse body message"));
}
}
Aggregations