EmailChangeEmailService implements ChangeEmailService { @Override public Map<String, String> completeVerification(String code) { ExpiringCode expiringCode = codeStore.retrieveCode(code, identityZoneManager.getCurrentIdentityZoneId()); if ((null == expiringCode) || ((null != expiringCode.getIntent()) && !EMAIL.name().equals(expiringCode.getIntent()))) { throw new UaaException("Error", 400); } Map<String, String> codeData = JsonUtils.readValue(expiringCode.getData(), new TypeReference<Map<String, String>>() { }); String userId = codeData.get("user_id"); String email = codeData.get("email"); ScimUser user = scimUserProvisioning.retrieve(userId, identityZoneManager.getCurrentIdentityZoneId()); if (user.getUserName().equals(user.getPrimaryEmail())) { user.setUserName(email); } user.getEmails().clear(); user.setPrimaryEmail(email); scimUserProvisioning.update(userId, user, identityZoneManager.getCurrentIdentityZoneId()); String clientId = codeData.get("client_id"); String redirectLocation = null; if (clientId != null) { String redirectUri = codeData.get("redirect_uri") == null ? "" : codeData.get("redirect_uri"); try { ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId, identityZoneManager.getCurrentIdentityZoneId()); Set<String> redirectUris = clientDetails.getRegisteredRedirectUri() == null ? Collections.emptySet() : clientDetails.getRegisteredRedirectUri(); String changeEmailRedirectUrl = (String) clientDetails.getAdditionalInformation().get(CHANGE_EMAIL_REDIRECT_URL); redirectLocation = findMatchingRedirectUri(redirectUris, redirectUri, changeEmailRedirectUrl); } catch (NoSuchClientException ignored) { } } Map<String, String> result = new HashMap<>(); result.put("userId", user.getId()); result.put("username", user.getUserName()); result.put("email", user.getPrimaryEmail()); result.put("redirect_url", redirectLocation); return result; } EmailChangeEmailService(final TemplateEngine templateEngine,
                            final MessageService messageService,
                            final ScimUserProvisioning scimUserProvisioning,
                            final ExpiringCodeStore codeStore,
                            final MultitenantClientServices clientDetailsService,
                            final IdentityZoneManager identityZoneManager); @Override void beginEmailChange(String userId, String email, String newEmail, String clientId, String redirectUri); @Override Map<String, String> completeVerification(String code);  }
@Test void completeVerification() { Map<String, String> response = setUpCompleteActivation("user-name", "app", "http: assertEquals("user-001", response.get("userId")); assertEquals("user-name", response.get("username")); assertEquals("new@example.com", response.get("email")); assertEquals("http: }
@Test void completeVerificationWithInvalidCode() { when(mockExpiringCodeStore.retrieveCode("invalid_code", zoneId)).thenReturn(null); Assertions.assertThrows(UaaException.class, () -> emailChangeEmailService.completeVerification("invalid_code")); }
@Test void completeVerificationWithInvalidIntent() { when(mockExpiringCodeStore.retrieveCode("invalid_code", zoneId)).thenReturn(new ExpiringCode("invalid_code", new Timestamp(System.currentTimeMillis()), null, "invalid-intent")); Assertions.assertThrows(UaaException.class, () -> emailChangeEmailService.completeVerification("invalid_code")); }
@Test void completeActivationWithInvalidClientId() { Map<String, String> codeData = new HashMap<>(); codeData.put("user_id", "user-001"); codeData.put("client_id", "invalid-client"); codeData.put("email", "new@example.com"); when(mockExpiringCodeStore.retrieveCode("the_secret_code", zoneId)).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(codeData), null)); ScimUser user = new ScimUser("user-001", "user@example.com", "", ""); user.setPrimaryEmail("user@example.com"); when(mockScimUserProvisioning.retrieve("user-001", zoneId)).thenReturn(user); doThrow(new NoSuchClientException("no such client")).when(mockMultitenantClientServices).loadClientByClientId("invalid-client", zoneId); Map<String, String> response = null; try { response = emailChangeEmailService.completeVerification("the_secret_code"); } catch (NoSuchClientException e) { assertNull(response.get("redirect_url")); } }