private String processErrorReload(String code, Model model, String email, HttpServletResponse response, String errorCode, String error) { ExpiringCode expiringCode = expiringCodeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); Map<String, String> codeData = JsonUtils.readValue(expiringCode.getData(), new TypeReference<Map<String, String>>() {}); try { String newCode = expiringCodeStore.generateCode(expiringCode.getData(), new Timestamp(System.currentTimeMillis() + (10 * 60 * 1000)), expiringCode.getIntent(), IdentityZoneHolder.get().getId()).getCode(); model.addAttribute(errorCode, error); model.addAttribute("code", newCode); return "redirect:accept"; } catch (EmptyResultDataAccessException noProviderFound) { logger.debug(String.format("No available invitation providers for email:%s, id:%s", codeData.get("email"), codeData.get("user_id"))); return handleUnprocessableEntity(model, response, "error_message_code", "no_suitable_idp", "invitations/accept_invite"); } }
@Test(expected = DataIntegrityViolationException.class) public void testGenerateCodeWithDuplicateCode() throws Exception { RandomValueStringGenerator generator = mock(RandomValueStringGenerator.class); Mockito.when(generator.generate()).thenReturn("duplicate"); expiringCodeStore.setGenerator(generator); String data = "{}"; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 60000); expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); }
public ExpiringCode doRetrieveCode(String code) { return codeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); }
private ExpiringCode getCode(String id, String username, String clientId) { Map<String, String> codeData = new HashMap<>(); codeData.put("user_id", id); codeData.put("username", username); codeData.put(OAuth2Utils.CLIENT_ID, clientId); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); return codeStore.generateCode(JsonUtils.writeValueAsString(codeData), new Timestamp(System.currentTimeMillis() + 5 * 60 * 1000), ExpiringCodeType.AUTOLOGIN.name(), IdentityZoneHolder.get().getId()); }
@Test public void testExpireCodeByIntent() throws Exception { ExpiringCode code = expiringCodeStore.generateCode("{}", new Timestamp(System.currentTimeMillis() + 60000), "Test Intent", IdentityZoneHolder.get().getId()); Assert.assertEquals(1, countCodes()); IdentityZoneHolder.set(MultitenancyFixture.identityZone("id","id")); expiringCodeStore.expireByIntent("Test Intent", IdentityZoneHolder.get().getId()); Assert.assertEquals(1, countCodes()); IdentityZoneHolder.clear(); expiringCodeStore.expireByIntent("Test Intent", IdentityZoneHolder.get().getId()); ExpiringCode retrievedCode = expiringCodeStore.retrieveCode(code.getCode(), IdentityZoneHolder.get().getId()); Assert.assertEquals(0, countCodes()); Assert.assertNull(retrievedCode); }
@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 testGenerateCodeWithDuplicateCode() { RandomValueStringGenerator generator = mock(RandomValueStringGenerator.class); when(generator.generate()).thenReturn("duplicate"); expiringCodeStore.setGenerator(generator); String data = "{}"; Timestamp expiresAt = new Timestamp(currentTime.get() + 60000); ExpiringCode expiringCode = new ExpiringCode(null, expiresAt, data, null); try { codeStoreEndpoints.generateCode(expiringCode); codeStoreEndpoints.generateCode(expiringCode); fail("duplicate code generated, should throw CodeStoreException."); } catch (CodeStoreException e) { assertEquals(e.getStatus(), HttpStatus.INTERNAL_SERVER_ERROR); } }
protected ExpiringCode doRetrieveCode(String code) { return expiringCodeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); }
private String generateExpiringCode(String userId, String newEmail, String clientId, String redirectUri) { Map<String, String> codeData = new HashMap<>(); codeData.put("user_id", userId); codeData.put("client_id", clientId); codeData.put("redirect_uri", redirectUri); codeData.put("email", newEmail); return codeStore.generateCode(JsonUtils.writeValueAsString(codeData), new Timestamp(System.currentTimeMillis() + EMAIL_CHANGE_LIFETIME), EMAIL.name(), IdentityZoneHolder.get().getId()).getCode(); }
@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")); }
@RequestMapping(value = "/reset_password", method = RequestMethod.GET, params = { "code" }) public String resetPasswordPage(Model model, HttpServletResponse response, @RequestParam("code") String code) { ExpiringCode expiringCode = checkIfUserExists(codeStore.retrieveCode(code, IdentityZoneHolder.get().getId())); if (expiringCode==null) { return handleUnprocessableEntity(model, response, "message_code", "bad_code"); } else { PasswordChange passwordChange = JsonUtils.readValue(expiringCode.getData(), PasswordChange.class); String userId = passwordChange.getUserId(); UaaUser uaaUser = userDatabase.retrieveUserById(userId); String newCode = codeStore.generateCode(expiringCode.getData(), new Timestamp(System.currentTimeMillis() + (10 * 60 * 1000)), expiringCode.getIntent(), IdentityZoneHolder.get().getId()).getCode(); model.addAttribute("code", newCode); model.addAttribute("email", uaaUser.getEmail()); model.addAttribute("username", uaaUser.getUsername()); return "reset_password"; } }
@RequestMapping(value = "/Codes/{code}", method = RequestMethod.GET) @ResponseBody public ExpiringCode retrieveCode(@PathVariable String code) { ExpiringCode result = null; try { result = expiringCodeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); } catch (NullPointerException e) { throw new CodeStoreException("code is required.", HttpStatus.BAD_REQUEST); } if (result == null) { throw new CodeStoreException("Code not found: " + code, HttpStatus.NOT_FOUND); } return result; }
private void refreshCode(HttpServletRequest request, ExpiringCode expiringCode) { ExpiringCode newCode = expiringCodeStore.generateCode(expiringCode.getData(), new Timestamp(System.currentTimeMillis() + 1000 * 60 * 10), expiringCode.getIntent(), IdentityZoneHolder.get().getId()); request.setAttribute("code", newCode.getCode()); }
expiringCodeStore.expireByIntent(intent, IdentityZoneHolder.get().getId()); ExpiringCode code = expiringCodeStore.generateCode( JsonUtils.writeValueAsString(pi), new Timestamp(System.currentTimeMillis() + (getCodeExpirationMillis())),
@Test public void forgotPassword_ThrowsConflictException() throws Exception { ScimUser user = new ScimUser("user-id-001","exampleUser","firstName","lastName"); user.setPrimaryEmail("user@example.com"); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.query(contains("origin"), eq(zoneId))).thenReturn(Arrays.asList(new ScimUser[]{})); when(scimUserProvisioning.query(eq("userName eq \"exampleUser\""), eq(zoneId))).thenReturn(Arrays.asList(new ScimUser[]{user})); when(codeStore.generateCode(anyString(), any(Timestamp.class), eq(null), anyString())).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), "user-id-001", null)); when(codeStore.retrieveCode(anyString(), anyString())).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), "user-id-001", null)); try { uaaResetPasswordService.forgotPassword("exampleUser", "", ""); fail(); } catch (ConflictException e) { assertThat(e.getUserId(), equalTo("user-id-001")); } }
private ExpiringCode getExpiringCode(String code) { ExpiringCode expiringCode = codeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); if (expiringCode == null) { throw new InvalidCodeException("invalid_code", "Sorry, your reset password link is no longer valid. Please request a new one", 422); } return expiringCode; }
@RequestMapping(value = { "/Codes" }, method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public ExpiringCode generateCode(@RequestBody ExpiringCode expiringCode) { try { return expiringCodeStore.generateCode(expiringCode.getData(), expiringCode.getExpiresAt(), null, IdentityZoneHolder.get().getId()); } catch (NullPointerException e) { throw new CodeStoreException("data and expiresAt are required.", HttpStatus.BAD_REQUEST); } catch (IllegalArgumentException e) { throw new CodeStoreException("expiresAt must be in the future.", HttpStatus.BAD_REQUEST); } catch (DataIntegrityViolationException e) { throw new CodeStoreException("Duplicate code generated.", HttpStatus.INTERNAL_SERVER_ERROR); } }
@Test public void testStoreLargeData() throws Exception { char[] oneMb = new char[1024 * 1024]; Arrays.fill(oneMb, 'a'); String aaaString = new String(oneMb); ExpiringCode expiringCode = expiringCodeStore.generateCode(aaaString, new Timestamp( System.currentTimeMillis() + 60000), null, IdentityZoneHolder.get().getId()); String code = expiringCode.getCode(); ExpiringCode actualCode = expiringCodeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); Assert.assertEquals(expiringCode, actualCode); }
@Test(expected = InvalidCodeException.class) public void authentication_fails_withCodeIntendedForDifferentPurpose() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("client_id", clientId); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); when(codeStore.retrieveCode("the_secret_code", IdentityZoneHolder.get().getId())).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(123), JsonUtils.writeValueAsString(codeData), null)); manager.authenticate(authenticationToken); }
@Test(expected = NullPointerException.class) public void testGenerateCodeWithNullData() throws Exception { String data = null; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 60000); expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); }