use of org.apereo.cas.mfa.accepto.AccepttoEmailCredential in project cas by apereo.
the class AccepttoMultifactorValidateUserDeviceRegistrationActionTests method verifyOperation.
@Test
public void verifyOperation() throws Exception {
val principal = CoreAuthenticationTestUtils.getPrincipal(Map.of("email", List.of("cas@example.org"), "group", List.of("staff")));
val authentication = CoreAuthenticationTestUtils.getAuthentication(principal);
val data = MAPPER.writeValueAsString(Map.of("device_paired", "true"));
try (val webServer = new MockWebServer(5011, new ByteArrayResource(data.getBytes(StandardCharsets.UTF_8), "REST Output"), MediaType.APPLICATION_JSON_VALUE)) {
webServer.start();
val context = new MockRequestContext();
val request = new MockHttpServletRequest();
val response = new MockHttpServletResponse();
context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, response));
WebUtils.putAuthentication(authentication, context);
RequestContextHolder.setRequestContext(context);
val action = new AccepttoMultifactorValidateUserDeviceRegistrationAction(casProperties);
val result = action.doExecute(context);
assertEquals(result.getId(), CasWebflowConstants.TRANSITION_ID_FINALIZE);
assertTrue(WebUtils.getCredential(context) instanceof AccepttoEmailCredential);
}
}
use of org.apereo.cas.mfa.accepto.AccepttoEmailCredential in project cas by apereo.
the class AccepttoMultifactorValidateUserDeviceRegistrationAction method doExecute.
@Override
protected Event doExecute(final RequestContext requestContext) {
val eventAttributes = new LocalAttributeMap<>();
val acceptto = casProperties.getAuthn().getMfa().getAcceptto();
val authentication = WebUtils.getInProgressAuthentication();
val email = AccepttoApiUtils.getUserEmail(authentication, acceptto);
try {
if (verifyUserDeviceIsPaired()) {
val credential = new AccepttoEmailCredential(email);
WebUtils.putCredential(requestContext, credential);
return new EventFactorySupport().event(this, CasWebflowConstants.TRANSITION_ID_FINALIZE);
}
} catch (final Exception e) {
eventAttributes.put("error", e);
LoggingUtils.error(LOGGER, e);
}
LOGGER.warn("Device linked to [{}] is not paired; authentication cannot proceed", email);
return new EventFactorySupport().event(this, CasWebflowConstants.TRANSITION_ID_DENY, eventAttributes);
}
use of org.apereo.cas.mfa.accepto.AccepttoEmailCredential in project cas by apereo.
the class AccepttoQRCodeValidateWebSocketChannelAction method doExecute.
@Override
protected Event doExecute(final RequestContext requestContext) {
val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);
val response = WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext);
val webContext = new JEEContext(request, response);
val channel = request.getParameter("channel");
if (channel == null) {
return returnError("Unable to locate websocket channel");
}
val acceptto = casProperties.getAuthn().getMfa().getAcceptto();
val url = StringUtils.appendIfMissing(acceptto.getApiUrl(), "/") + "get_user_by_websocket_channel";
LOGGER.trace("Contacting API [{}] to fetch email address", url);
val parameters = CollectionUtils.<String, Object>wrap("uid", acceptto.getApplicationId(), "secret", acceptto.getSecret(), "websocket_channel", channel);
HttpResponse apiResponse = null;
try {
val exec = HttpUtils.HttpExecutionRequest.builder().method(HttpMethod.POST).url(url).parameters(parameters).build();
apiResponse = HttpUtils.execute(exec);
if (apiResponse != null) {
val status = apiResponse.getStatusLine().getStatusCode();
LOGGER.debug("Response API status code is [{}]", status);
if (status == HttpStatus.SC_OK) {
val result = IOUtils.toString(apiResponse.getEntity().getContent(), StandardCharsets.UTF_8);
val results = MAPPER.readValue(JsonValue.readHjson(result).toString(), Map.class);
LOGGER.debug("Received API results for channel [{}] as [{}]", channel, results);
if (results.isEmpty()) {
throw new AuthenticationException("No API results were returned for channel " + channel);
}
val success = BooleanUtils.toBoolean(results.get("success").toString());
if (success) {
val email = results.get("user_email").toString();
LOGGER.trace("Storing channel [{}] in http session", channel);
AccepttoWebflowUtils.storeChannelInSessionStore(channel, webContext, sessionStore);
WebUtils.putCredential(requestContext, new AccepttoEmailCredential(email));
return new EventFactorySupport().event(this, CasWebflowConstants.TRANSITION_ID_FINALIZE);
}
val message = results.get("message").toString();
LOGGER.error(message);
return returnError(message);
}
if (status == HttpStatus.SC_FORBIDDEN) {
return returnError("Invalid uid and secret combination; application not found");
}
if (status == HttpStatus.SC_UNAUTHORIZED) {
return returnError("Email address provided is not a valid registered account");
}
}
} catch (final Exception e) {
LoggingUtils.error(LOGGER, e);
} finally {
HttpUtils.close(apiResponse);
}
return returnError("Unable to validate websocket channel");
}
Aggregations