@Override public void expireByIntent(String intent, String zoneId) { Assert.hasText(intent); store.values().stream().filter(c -> intent.equals(c.getIntent())).forEach(c -> store.remove(c.getCode() + 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(); }
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()); }
private void generateAndSendCode(String email, String clientId, String subject, String userId, String redirectUri) throws IOException { ExpiringCode expiringCode = ScimUtils.getExpiringCode(codeStore, userId, email, clientId, redirectUri, REGISTRATION); String htmlContent = getEmailHtml(expiringCode.getCode(), email); messageService.sendMessage(email, MessageType.CREATE_ACCOUNT_CONFIRMATION, subject, htmlContent); }
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"); } }
private MockHttpServletRequestBuilder createChangePasswordRequest(ScimUser user, ExpiringCode code, boolean useCSRF, String password, String passwordConfirmation) throws Exception { return createChangePasswordRequest(user,code.getCode(),useCSRF, password,passwordConfirmation); }
@RequestMapping(value="/email_verifications", method = RequestMethod.POST) public ResponseEntity<String> generateEmailVerificationCode(@RequestBody EmailChange emailChange) { String userId = emailChange.getUserId(); String email = emailChange.getEmail(); ScimUser user = scimUserProvisioning.retrieve(userId, IdentityZoneHolder.get().getId()); if (user.getUserName().equals(user.getPrimaryEmail())) { List<ScimUser> results = scimUserProvisioning.query("userName eq \"" + email + "\" and origin eq \"" + OriginKeys.UAA + "\"", IdentityZoneHolder.get().getId()); if (!results.isEmpty()) { return new ResponseEntity<>(CONFLICT); } } String code; try { code = expiringCodeStore.generateCode(JsonUtils.writeValueAsString(emailChange), new Timestamp(System.currentTimeMillis() + EMAIL_CHANGE_LIFETIME), EMAIL.name(), IdentityZoneHolder.get().getId()).getCode(); } catch (JsonUtils.JsonUtilException e) { throw new UaaException("Error while generating change email code", e); } return new ResponseEntity<>(code, CREATED); }
@Test public void testStoreLargeData() { char[] oneMb = new char[1024 * 1024]; Arrays.fill(oneMb, 'a'); String data = new String(oneMb); Timestamp expiresAt = new Timestamp(currentTime.get() + 60000); ExpiringCode expiringCode = new ExpiringCode(null, expiresAt, data, null); ExpiringCode generatedCode = codeStoreEndpoints.generateCode(expiringCode); String code = generatedCode.getCode(); ExpiringCode actualCode = codeStoreEndpoints.retrieveCode(code); assertEquals(generatedCode, actualCode); }
@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"; } }
@Test public void testGenerateCode() { String data = "{}"; Timestamp expiresAt = new Timestamp(currentTime.get() + 60000); ExpiringCode expiringCode = new ExpiringCode(null, expiresAt, data, null); ExpiringCode result = codeStoreEndpoints.generateCode(expiringCode); assertNotNull(result); assertNotNull(result.getCode()); assertTrue(result.getCode().trim().length() == 10); assertEquals(expiresAt, result.getExpiresAt()); assertEquals(data, result.getData()); }
@Test public void testGenerateCode() throws Exception { String data = "{}"; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 60000); ExpiringCode expiringCode = expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); Assert.assertNotNull(expiringCode); Assert.assertNotNull(expiringCode.getCode()); Assert.assertTrue(expiringCode.getCode().trim().length() > 0); Assert.assertEquals(expiresAt, expiringCode.getExpiresAt()); Assert.assertEquals(data, expiringCode.getData()); }
@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 public void testExpiredCodeReturnsNull() throws Exception { long generationTime = 100000L; when(timeService.getCurrentTimeMillis()).thenReturn(generationTime); String data = "{}"; Timestamp expiresAt = new Timestamp(generationTime); ExpiringCode generatedCode = expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); long expirationTime = 200000L; when(timeService.getCurrentTimeMillis()).thenReturn(expirationTime); ExpiringCode retrievedCode = expiringCodeStore.retrieveCode(generatedCode.getCode(), IdentityZoneHolder.get().getId()); Assert.assertNull(retrievedCode); }
@Test public void testRetrieveCode() { String data = "{}"; Timestamp expiresAt = new Timestamp(currentTime.get() + 60000); ExpiringCode expiringCode = new ExpiringCode(null, expiresAt, data, null); ExpiringCode generatedCode = codeStoreEndpoints.generateCode(expiringCode); ExpiringCode retrievedCode = codeStoreEndpoints.retrieveCode(generatedCode.getCode()); assertEquals(generatedCode, retrievedCode); try { codeStoreEndpoints.retrieveCode(generatedCode.getCode()); fail("One-use code already retrieved, should throw CodeStoreException."); } catch (CodeStoreException e) { assertEquals(e.getStatus(), HttpStatus.NOT_FOUND); } }
@Test public void testRetrieveCodeWithExpiredCode() { String data = "{}"; int expiresIn = 1000; Timestamp expiresAt = new Timestamp(currentTime.get() + expiresIn); ExpiringCode expiringCode = new ExpiringCode(null, expiresAt, data, null); ExpiringCode generatedCode = codeStoreEndpoints.generateCode(expiringCode); currentTime.addAndGet(expiresIn + 1); try { codeStoreEndpoints.retrieveCode(generatedCode.getCode()); fail("code is expired, should throw CodeStoreException."); } catch (CodeStoreException e) { assertEquals(e.getStatus(), HttpStatus.NOT_FOUND); } } }
@Test public void testRetrieveCode() throws Exception { String data = "{}"; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 60000); ExpiringCode generatedCode = expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); ExpiringCode retrievedCode = expiringCodeStore.retrieveCode(generatedCode.getCode(), IdentityZoneHolder.get().getId()); Assert.assertEquals(generatedCode, retrievedCode); Assert.assertNull(expiringCodeStore.retrieveCode(generatedCode.getCode(), IdentityZoneHolder.get().getId())); }
@Test public void testRetrieveCode_In_Another_Zone() throws Exception { String data = "{}"; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 60000); ExpiringCode generatedCode = expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); IdentityZoneHolder.set(MultitenancyFixture.identityZone("other","other")); Assert.assertNull(expiringCodeStore.retrieveCode(generatedCode.getCode(), IdentityZoneHolder.get().getId())); IdentityZoneHolder.clear(); ExpiringCode retrievedCode = expiringCodeStore.retrieveCode(generatedCode.getCode(), IdentityZoneHolder.get().getId()); Assert.assertEquals(generatedCode, retrievedCode); }
@Test public void testResetPasswordPageDuplicate() throws Exception { ExpiringCode code = codeStore.generateCode("{\"user_id\" : \"some-user-id\"}", new Timestamp(System.currentTimeMillis() + 1000000), null, IdentityZoneHolder.get().getId()); mockMvc.perform(get("/reset_password").param("email", "user@example.com").param("code", code.getCode())) .andExpect(status().isOk()) .andExpect(view().name("reset_password")); mockMvc.perform(get("/reset_password").param("email", "user@example.com").param("code", code.getCode())) .andExpect(status().isUnprocessableEntity()) .andExpect(view().name("forgot_password")); }
@Test public void testResetPasswordPage() throws Exception { ExpiringCode code = codeStore.generateCode("{\"user_id\" : \"some-user-id\"}", new Timestamp(System.currentTimeMillis() + 1000000), null, IdentityZoneHolder.get().getId()); mockMvc.perform(get("/reset_password").param("email", "user@example.com").param("code", code.getCode())) .andExpect(status().isOk()) .andDo(print()) .andExpect(view().name("reset_password")) .andExpect(model().attribute("email", "email")) .andExpect(model().attribute("username", "username")) .andExpect(content().string(containsString("<div class=\"email-display\">Username: username</div>"))) .andExpect(content().string(containsString("<input type=\"hidden\" name=\"username\" value=\"username\"/>"))); }
@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); }