@Override public ExpiringCode retrieveCode(String code, String zoneId) { cleanExpiredEntries(); if (code == null) { throw new NullPointerException(); } try { ExpiringCode expiringCode = jdbcTemplate.queryForObject(selectAllFields, rowMapper, code, zoneId); if (expiringCode != null) { jdbcTemplate.update(delete, code, zoneId); } if (expiringCode.getExpiresAt().getTime() < timeService.getCurrentTimeMillis()) { expiringCode = null; } return expiringCode; } catch (EmptyResultDataAccessException x) { return null; } }
public JdbcExpiringCodeStore(DataSource dataSource, TimeService timeService) { setDataSource(dataSource); setTimeService(timeService); }
@Before public void initCodeStoreTests() { codeStoreEndpoints = new CodeStoreEndpoints(); currentTime = new AtomicLong(System.currentTimeMillis()); expiringCodeStore = new JdbcExpiringCodeStore(jdbcTemplate.getDataSource(), new TimeService() { @Override public long getCurrentTimeMillis() { return currentTime.get(); } }); codeStoreEndpoints.setExpiringCodeStore(expiringCodeStore); }
@After public void resetGenerator() { webApplicationContext.getBean(JdbcExpiringCodeStore.class).setGenerator(new RandomValueStringGenerator(24)); }
@Test public void changePassword_isSuccessful() throws Exception { MockMvcUtils.PredictableGenerator generator = new MockMvcUtils.PredictableGenerator(); JdbcExpiringCodeStore store = getWebApplicationContext().getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator); String code = getExpiringCode(null, null); MockHttpServletRequestBuilder post = post("/password_change") .header("Authorization", "Bearer " + loginToken) .contentType(APPLICATION_JSON) .content("{\"code\":\"" + code + "\",\"new_password\":\"new_secr3T\"}") .accept(APPLICATION_JSON); getMockMvc().perform(post) .andExpect(status().isOk()) .andExpect(jsonPath("$.user_id").exists()) .andExpect(jsonPath("$.username").value(user.getUserName())) .andExpect(jsonPath("$.code").value("test" + generator.counter.get())); ExpiringCode expiringCode = store.retrieveCode("test" + generator.counter.get(), IdentityZoneHolder.get().getId()); assertThat(expiringCode.getIntent(), is(ExpiringCodeType.AUTOLOGIN.name())); Map<String,String> data = JsonUtils.readValue(expiringCode.getData(), new TypeReference<Map<String,String>>() {}); assertThat(data.get("user_id"), is(user.getId())); assertThat(data.get("username"), is(user.getUserName())); assertThat(data.get(OAuth2Utils.CLIENT_ID), is("login")); assertThat(data.get(OriginKeys.ORIGIN), is(OriginKeys.UAA)); }
@Test public void testDatabaseDown() throws Exception { if (JdbcExpiringCodeStore.class == expiringCodeStoreClass) { javax.sql.DataSource ds = mock(javax.sql.DataSource.class); Mockito.when(ds.getConnection()).thenThrow(new SQLException()); ((JdbcExpiringCodeStore) expiringCodeStore).setDataSource(ds); try { String data = "{}"; Timestamp expiresAt = new Timestamp(System.currentTimeMillis() + 10000000); ExpiringCode generatedCode = expiringCodeStore.generateCode(data, expiresAt, null, IdentityZoneHolder.get().getId()); Assert.fail("Database is down, should not generate a code"); } catch (DataAccessException x) { } } }
private void expireAllCodes() { jdbcExpiringCodeStore.setExpirationInterval(0); Timestamp expired = new Timestamp(System.currentTimeMillis() - 5000); jdbcTemplate.update("update expiring_code_store set expiresat=?", expired.getTime()); }
@BeforeEach void setUp() throws Exception { // TODO: Why is this here? Timestamp ts = new Timestamp(Long.MAX_VALUE); ExpiringCode code = new ExpiringCode(null, ts, "{}", null); String requestBody = JsonUtils.writeValueAsString(code); MockHttpServletRequestBuilder post = post("/Codes") .header("Authorization", "Bearer " + loginToken) .contentType(APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(requestBody); MvcResult result = mockMvc.perform(post) .andExpect(status().isCreated()) .andReturn(); JsonUtils.readValue(result.getResponse().getContentAsString(), ExpiringCode.class); expireAllCodes(); priorExpirationInterval = jdbcExpiringCodeStore.getExpirationInterval(); }
@AfterEach void resetGenerator( @Autowired JdbcExpiringCodeStore jdbcExpiringCodeStore, @Autowired LoginInfoEndpoint loginInfoEndpoint, @Autowired HomeController homeController ) { jdbcExpiringCodeStore.setGenerator(new RandomValueStringGenerator(24)); loginInfoEndpoint.setGlobalLinks(globalLinks); homeController.setGlobalLinks(globalLinks); }
@Test public void changePassword_isSuccessful_withOverridenClientId() throws Exception { MockMvcUtils.PredictableGenerator generator = new MockMvcUtils.PredictableGenerator(); JdbcExpiringCodeStore store = getWebApplicationContext().getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator); String code = getExpiringCode("another-client", null); MockHttpServletRequestBuilder post = post("/password_change") .header("Authorization", "Bearer " + loginToken) .contentType(APPLICATION_JSON) .content("{\"code\":\"" + code + "\",\"new_password\":\"new_secr3T\"}") .accept(APPLICATION_JSON); getMockMvc().perform(post) .andExpect(status().isOk()) .andExpect(jsonPath("$.user_id").exists()) .andExpect(jsonPath("$.username").value(user.getUserName())) .andExpect(jsonPath("$.code").value("test" + generator.counter.get())); ExpiringCode expiringCode = store.retrieveCode("test" + generator.counter.get(), IdentityZoneHolder.get().getId()); Map<String,String> data = JsonUtils.readValue(expiringCode.getData(), new TypeReference<Map<String,String>>() {}); assertThat(data.get(OAuth2Utils.CLIENT_ID), is("another-client")); }
@AfterEach void tearDown() { jdbcExpiringCodeStore.setExpirationInterval(priorExpirationInterval); }
@Before public void initExpiringCodeStoreTests() throws Exception { expiringCodeStore = (ExpiringCodeStore) expiringCodeStoreClass.newInstance(); if (expiringCodeStore instanceof InMemoryExpiringCodeStore) { ((InMemoryExpiringCodeStore) expiringCodeStore).setTimeService(timeService); } else { // confirm that everything is clean prior to test. TestUtils.deleteFrom(jdbcTemplate.getDataSource(), JdbcExpiringCodeStore.tableName); ((JdbcExpiringCodeStore) expiringCodeStore).setDataSource(jdbcTemplate.getDataSource()); ((JdbcExpiringCodeStore) expiringCodeStore).setTimeService(timeService); } }
@After public void resetGenerator() throws Exception { getWebApplicationContext().getBean(JdbcExpiringCodeStore.class).setGenerator(new RandomValueStringGenerator(24)); }
@Override public ExpiringCode generateCode(String data, Timestamp expiresAt, String intent, String zoneId) { cleanExpiredEntries(); if (data == null || expiresAt == null) { throw new NullPointerException(); } if (expiresAt.getTime() < timeService.getCurrentTimeMillis()) { throw new IllegalArgumentException(); } int count = 0; while (count < 3) { count++; String code = generator.generate(); try { int update = jdbcTemplate.update(insert, code, expiresAt.getTime(), data, intent, zoneId); if (update == 1) { ExpiringCode expiringCode = new ExpiringCode(code, expiresAt, data, intent); return expiringCode; } else { logger.warn("Unable to store expiring code:" + code); } } catch (DataIntegrityViolationException x) { if (count == 3) { throw x; } } } return null; }
@Test void verifyExpirationIntervalWorks() throws Exception { jdbcExpiringCodeStore.setExpirationInterval(10000000); Timestamp ts = new Timestamp(System.currentTimeMillis() + 1000); ExpiringCode code = new ExpiringCode(null, ts, "{}", null); String requestBody = JsonUtils.writeValueAsString(code); MockHttpServletRequestBuilder post = post("/Codes") .header("Authorization", "Bearer " + loginToken) .contentType(APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(requestBody); mockMvc.perform(post) .andExpect(status().isCreated()) .andReturn(); assertThat(jdbcTemplate.queryForObject("select count(*) from expiring_code_store", Integer.class), is(2)); } }
@Test void testCreatingAnAccountWithNoClientRedirect() throws Exception { PredictableGenerator generator = new PredictableGenerator(); JdbcExpiringCodeStore store = webApplicationContext.getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator); mockMvc.perform(post("/create_account.do") .with(cookieCsrf()) .param("email", userEmail) .param("password", "secr3T") .param("password_confirmation", "secr3T")) .andExpect(status().isFound()) .andExpect(redirectedUrl("accounts/email_sent")); FakeJavaMailSender.MimeMessageWrapper message = fakeJavaMailSender.getSentMessages().get(0); assertTrue(message.getContentString().contains("Cloud Foundry")); assertThat(message.getMessage().getHeader("From"), hasItemInArray("Cloud Foundry <admin@localhost>")); mockMvc.perform(get("/verify_user") .param("code", "test" + generator.counter.get())) .andExpect(status().isFound()) .andExpect(redirectedUrl(LOGIN_REDIRECT)) .andReturn(); MvcResult mvcResult = loginWithAccount("") .andExpect(authenticated()) .andReturn(); SecurityContext securityContext = (SecurityContext) mvcResult.getRequest().getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); Authentication authentication = securityContext.getAuthentication(); assertThat(authentication.getPrincipal(), instanceOf(UaaPrincipal.class)); UaaPrincipal principal = (UaaPrincipal) authentication.getPrincipal(); assertThat(principal.getEmail(), equalTo(userEmail)); assertThat(principal.getOrigin(), equalTo(OriginKeys.UAA)); }
@Test(expected = EmptyResultDataAccessException.class) public void testExpirationCleaner() throws Exception { when(timeService.getCurrentTimeMillis()).thenReturn(System.currentTimeMillis()); if (JdbcExpiringCodeStore.class == expiringCodeStoreClass) { jdbcTemplate.update(JdbcExpiringCodeStore.insert, "test", System.currentTimeMillis() - 1000, "{}", null, IdentityZoneHolder.get().getId()); ((JdbcExpiringCodeStore) expiringCodeStore).cleanExpiredEntries(); jdbcTemplate.queryForObject(JdbcExpiringCodeStore.selectAllFields, new JdbcExpiringCodeStore.JdbcExpiringCodeMapper(), "test", IdentityZoneHolder.get().getId()); } else { throw new EmptyResultDataAccessException(1); } } }
@Test void testCreatingAnAccountWithAnEmptyClientId() throws Exception { PredictableGenerator generator = new PredictableGenerator(); JdbcExpiringCodeStore store = webApplicationContext.getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator); mockMvc.perform(post("/create_account.do") .with(cookieCsrf()) .param("email", userEmail) .param("password", "secr3T") .param("password_confirmation", "secr3T") .param("client_id", "")) .andExpect(status().isFound()) .andExpect(redirectedUrl("accounts/email_sent")); mockMvc.perform(get("/verify_user") .param("code", "test" + generator.counter.get())) .andExpect(status().isFound()) .andExpect(redirectedUrl(LOGIN_REDIRECT)) .andReturn(); MvcResult mvcResult = loginWithAccount("") .andExpect(authenticated()) .andReturn(); SecurityContext securityContext = (SecurityContext) mvcResult.getRequest().getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); Authentication authentication = securityContext.getAuthentication(); assertThat(authentication.getPrincipal(), instanceOf(UaaPrincipal.class)); UaaPrincipal principal = (UaaPrincipal) authentication.getPrincipal(); assertThat(principal.getEmail(), equalTo(userEmail)); assertThat(principal.getOrigin(), equalTo(OriginKeys.UAA)); }
@Test void testCreatingAnAccount() throws Exception { PredictableGenerator generator = new PredictableGenerator(); JdbcExpiringCodeStore store = webApplicationContext.getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator); mockMvc.perform(post("/create_account.do") .with(cookieCsrf()) .param("email", userEmail) .param("password", "secr3T") .param("password_confirmation", "secr3T")) .andExpect(status().isFound()) .andExpect(redirectedUrl("accounts/email_sent")); JdbcScimUserProvisioning scimUserProvisioning = webApplicationContext.getBean(JdbcScimUserProvisioning.class); ScimUser scimUser = scimUserProvisioning.query("userName eq '" + userEmail + "' and origin eq '" + OriginKeys.UAA + "'", IdentityZoneHolder.get().getId()).get(0); assertFalse(scimUser.isVerified()); mockMvc.perform(get("/verify_user") .param("code", "test" + generator.counter.get())) .andExpect(status().isFound()) .andExpect(redirectedUrl(LOGIN_REDIRECT)) .andReturn(); MvcResult mvcResult = loginWithAccount("") .andExpect(authenticated()) .andReturn(); SecurityContext securityContext = (SecurityContext) mvcResult.getRequest().getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY); Authentication authentication = securityContext.getAuthentication(); assertThat(authentication.getPrincipal(), instanceOf(UaaPrincipal.class)); UaaPrincipal principal = (UaaPrincipal) authentication.getPrincipal(); assertThat(principal.getEmail(), equalTo(userEmail)); assertThat(principal.getOrigin(), equalTo(OriginKeys.UAA)); }
private void createAccount(String expectedRedirectUri, String redirectUri) throws Exception { PredictableGenerator generator = new PredictableGenerator(); JdbcExpiringCodeStore store = webApplicationContext.getBean(JdbcExpiringCodeStore.class); store.setGenerator(generator);