private void forgotPassword(String username, String clientId, String redirectUri) { String subject = getSubjectText(); String htmlContent = null; String userId = null; String email = null; try { ForgotPasswordInfo forgotPasswordInfo = resetPasswordService.forgotPassword(username, clientId, redirectUri); userId = forgotPasswordInfo.getUserId(); email = forgotPasswordInfo.getEmail(); htmlContent = getCodeSentEmailHtml(forgotPasswordInfo.getResetPasswordCode().getCode()); } catch (ConflictException e) { email = e.getEmail(); htmlContent = getResetUnavailableEmailHtml(email); userId = e.getUserId(); } catch (NotFoundException e) { logger.error("User with email address " + username + " not found."); } if (htmlContent != null && userId != null) { messageService.sendMessage(email, MessageType.PASSWORD_RESET, subject, htmlContent); } }
@RequestMapping(value = "/password_resets", method = RequestMethod.POST) public ResponseEntity<PasswordResetResponse> resetPassword(@RequestBody String email, @RequestParam(required = false, value = "client_id") String clientId, @RequestParam(required = false, value = "redirect_uri") String redirectUri) throws IOException { if (clientId == null) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication instanceof OAuth2Authentication) { OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication; clientId = oAuth2Authentication.getOAuth2Request().getClientId(); } } PasswordResetResponse response = new PasswordResetResponse(); try { ForgotPasswordInfo forgotPasswordInfo = resetPasswordService.forgotPassword(email, clientId, redirectUri); response.setChangeCode(forgotPasswordInfo.getResetPasswordCode().getCode()); response.setUserId(forgotPasswordInfo.getUserId()); return new ResponseEntity<>(response, CREATED); } catch (ConflictException e) { response.setUserId(e.getUserId()); return new ResponseEntity<>(response, CONFLICT); } catch (NotFoundException e) { return new ResponseEntity<>(NOT_FOUND); } }
@Override public ForgotPasswordInfo forgotPassword(String username, String clientId, String redirectUri) { String jsonUsername = JsonUtils.writeValueAsString(username); List<ScimUser> results = scimUserProvisioning.query("userName eq " + jsonUsername + " and origin eq \"" + OriginKeys.UAA + "\"", IdentityZoneHolder.get().getId()); if (results.isEmpty()) { results = scimUserProvisioning.query("userName eq " + jsonUsername, IdentityZoneHolder.get().getId()); if (results.isEmpty()) { throw new NotFoundException(); } else { throw new ConflictException(results.get(0).getId(), results.get(0).getPrimaryEmail()); } } ScimUser scimUser = results.get(0); PasswordChange change = new PasswordChange(scimUser.getId(), scimUser.getUserName(), scimUser.getPasswordLastModified(), clientId, redirectUri); String intent = FORGOT_PASSWORD_INTENT_PREFIX+scimUser.getId(); expiringCodeStore.expireByIntent(intent, IdentityZoneHolder.get().getId()); ExpiringCode code = expiringCodeStore.generateCode(JsonUtils.writeValueAsString(change), new Timestamp(System.currentTimeMillis() + PASSWORD_RESET_LIFETIME), intent, IdentityZoneHolder.get().getId()); String email = scimUser.getPrimaryEmail(); if (email == null) { email = scimUser.getUserName(); } publish(new ResetPasswordRequestEvent(username, email, code.getCode(), SecurityContextHolder.getContext().getAuthentication())); return new ForgotPasswordInfo(scimUser.getId(), email, code); }
@Test public void forgotPasswordFallsBackToUsernameIfNoPrimaryEmail() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "firstName", "lastName"); String zoneID = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.query(contains("origin"), eq(zoneID))).thenReturn(Arrays.asList(user)); Timestamp expiresAt = new Timestamp(System.currentTimeMillis()); when(codeStore.generateCode(anyString(), any(Timestamp.class), anyString(), anyString())) .thenReturn(new ExpiringCode("code", expiresAt, "user-id-001", null)); ForgotPasswordInfo forgotPasswordInfo = uaaResetPasswordService.forgotPassword("exampleUser", "example", "redirect.example.com"); assertThat(forgotPasswordInfo.getEmail(), equalTo("user@example.com")); }
IdentityZoneHolder.get().setConfig(config); try { when(resetPasswordService.forgotPassword("user@example.com", "example", "redirect.example.com")).thenReturn(new ForgotPasswordInfo("123", "user@example.com", new ExpiringCode("code1", new Timestamp(System.currentTimeMillis()), "someData", null))); MockHttpServletRequestBuilder post = post("/forgot_password.do") .contentType(APPLICATION_FORM_URLENCODED)
@Test public void forgotPassword_ResetCodeIsReturnedSuccessfully() throws Exception { ScimUser user = new ScimUser("user-id-001","exampleUser","firstName","lastName"); user.setPasswordLastModified(new Date(1234)); user.setPrimaryEmail("user@example.com"); String zoneID = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.query(contains("origin"), eq(zoneID))).thenReturn(Arrays.asList(user)); Timestamp expiresAt = new Timestamp(System.currentTimeMillis()); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); when(codeStore.generateCode(eq("{\"user_id\":\"user-id-001\",\"username\":\"exampleUser\",\"passwordModifiedTime\":1234,\"client_id\":\"example\",\"redirect_uri\":\"redirect.example.com\"}"), any(Timestamp.class), anyString(), anyString())).thenReturn(new ExpiringCode("code", expiresAt, "user-id-001", null)); ForgotPasswordInfo forgotPasswordInfo = uaaResetPasswordService.forgotPassword("exampleUser", "example", "redirect.example.com"); verify(codeStore).expireByIntent(captor.capture(), anyString()); assertEquals(UaaResetPasswordService.FORGOT_PASSWORD_INTENT_PREFIX+user.getId(), captor.getValue()); assertThat(forgotPasswordInfo.getUserId(), equalTo("user-id-001")); assertThat(forgotPasswordInfo.getEmail(), equalTo("user@example.com")); ExpiringCode resetPasswordCode = forgotPasswordInfo.getResetPasswordCode(); assertThat(resetPasswordCode.getCode(), equalTo("code")); assertThat(resetPasswordCode.getExpiresAt(), equalTo(expiresAt)); assertThat(resetPasswordCode.getData(), equalTo("user-id-001")); }