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()); }
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 ExpiringCode createCode(Map<String, String> codeData) { return new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(codeData), INVITATION.name()); }
@Test(expected = BadCredentialsException.class) public void authentication_fails_withInvalidClient() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("client_id", "actual-client-id"); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); codeData.put("action", ExpiringCodeType.AUTOLOGIN.name()); 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); }
@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(expected = BadCredentialsException.class) public void authentication_fails_withNoClientId() { Map<String,String> codeData = new HashMap<>(); codeData.put("user_id", "test-user-id"); codeData.put("username", "test-username"); codeData.put(OriginKeys.ORIGIN, OriginKeys.UAA); codeData.put("action", ExpiringCodeType.AUTOLOGIN.name()); 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 public void acceptInvitation_onlyMarksInternalUsersAsVerified() { ScimUser user = new ScimUser("ldap-user-id", "ldapuser", "Charlie", "Brown"); user.setOrigin(LDAP); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.retrieve(eq("ldap-user-id"), eq(zoneId))).thenReturn(user); Map<String, String> userData = new HashMap<>(); userData.put(USER_ID, "ldap-user-id"); userData.put(EMAIL, "ldapuser"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); emailInvitationsService.acceptInvitation("code", "").getRedirectUri(); verify(scimUserProvisioning, never()).verifyUser(anyString(), anyInt(), anyString()); }
private void setUpForBeginEmailChange() { ScimUser user = new ScimUser("user-001", "user-name", "test-name", "test-name"); user.setPrimaryEmail("user@example.com"); Map<String, String> codeData = new HashMap<>(); codeData.put("user_id", "user-001"); codeData.put("client_id", "app"); codeData.put("redirect_uri", "http://app.com"); codeData.put("email", "new@example.com"); IdentityZone identityZone = new IdentityZone(); String zoneId = RandomStringUtils.random(10); identityZone.setId(zoneId); identityZone.setName(IDENTITY_ZONE_NAME); IdentityZoneHolder.set(identityZone); when(scimUserProvisioning.retrieve("user-001", zoneId)).thenReturn(user); when(scimUserProvisioning.query(anyString(), eq(zoneId))).thenReturn(Collections.singletonList(new ScimUser())); String data = JsonUtils.writeValueAsString(codeData); when(codeStore.generateCode(eq(data), any(Timestamp.class), eq(EMAIL.name()), anyString())).thenReturn(new ExpiringCode("the_secret_code", new Timestamp(System.currentTimeMillis()), data, EMAIL.name())); emailChangeEmailService.beginEmailChange("user-001", "user@example.com", "new@example.com", "app", "http://app.com"); verify(codeStore).generateCode(eq(JsonUtils.writeValueAsString(codeData)), any(Timestamp.class), eq(EMAIL.name()), eq(zoneId)); }
@Test public void acceptInvitation_withoutPasswordUpdate() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last"); user.setOrigin(UAA); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.retrieve(eq("user-id-001"), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); Map<String,String> userData = new HashMap<>(); userData.put(USER_ID, "user-id-001"); userData.put(EMAIL, "user@example.com"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); emailInvitationsService.acceptInvitation("code", "").getRedirectUri(); verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion(), zoneId); verify(scimUserProvisioning, never()).changePassword(anyString(), anyString(), anyString(), eq(zoneId)); }
@Test public void testBeginActivation() throws Exception { String redirectUri = ""; String data = setUpForSuccess(redirectUri); String zoneId = "BeginActivationZone"; identityZone.setId(zoneId); identityZone.setSubdomain("uaa"); IdentityZoneHolder.set(identityZone); when(scimUserProvisioning.createUser(any(ScimUser.class), anyString(), eq(zoneId))).thenReturn(user); when(codeStore.generateCode(eq(data), any(Timestamp.class), eq(REGISTRATION.name()), anyString())).thenReturn(code); emailAccountCreationService.beginActivation("user@example.com", "password", "login", redirectUri); String emailBody = captorEmailBody("Activate your account"); assertThat(emailBody, containsString("an account")); assertThat(emailBody, containsString("<a href=\"http://uaa.example.com/verify_user?code=the_secret_code\">Activate your account</a>")); }
@Test public void acceptInvitationNoClientId() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last"); user.setOrigin(UAA); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.retrieve(eq("user-id-001"), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.update(anyString(), any(), eq(zoneId))).thenReturn(user); Map<String,String> userData = new HashMap<>(); userData.put(USER_ID, "user-id-001"); userData.put(EMAIL, "user@example.com"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); String redirectLocation = emailInvitationsService.acceptInvitation("code", "password").getRedirectUri(); verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion(), zoneId); verify(scimUserProvisioning).changePassword(user.getId(), null, "password", zoneId); assertEquals("/home", redirectLocation); }
@Override public AccountCreationResponse completeActivation(String code) throws IOException { ExpiringCode expiringCode = codeStore.retrieveCode(code, IdentityZoneHolder.get().getId()); if ((null == expiringCode) || ((null != expiringCode.getIntent()) && !REGISTRATION.name().equals(expiringCode.getIntent()))) { throw new HttpClientErrorException(BAD_REQUEST); } Map<String, String> data = JsonUtils.readValue(expiringCode.getData(), new TypeReference<Map<String, String>>() {}); ScimUser user = scimUserProvisioning.retrieve(data.get("user_id"), IdentityZoneHolder.get().getId()); user = scimUserProvisioning.verifyUser(user.getId(), user.getVersion(), IdentityZoneHolder.get().getId()); String clientId = data.get("client_id"); String redirectUri = data.get("redirect_uri") != null ? data.get("redirect_uri") : ""; String redirectLocation = getRedirect(clientId, redirectUri); return new AccountCreationResponse(user.getId(), user.getUserName(), user.getUserName(), redirectLocation); }
@Test public void acceptInvitationWithClientNotFound() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last"); user.setOrigin(OriginKeys.UAA); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.update(anyString(), any(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.retrieve(eq("user-id-001"), eq(zoneId))).thenReturn(user); doThrow(new NoSuchClientException("Client not found")).when(clientDetailsService).loadClientByClientId("client-not-found"); Map<String,String> userData = new HashMap<>(); userData.put(USER_ID, "user-id-001"); userData.put(EMAIL, "user@example.com"); userData.put(CLIENT_ID, "client-not-found"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); String redirectLocation = emailInvitationsService.acceptInvitation("code", "password").getRedirectUri(); verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion(), zoneId); verify(scimUserProvisioning).changePassword(user.getId(), null, "password", zoneId); assertEquals("/home", redirectLocation); }
@Test public void acceptInvitationWithValidRedirectUri() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last"); user.setOrigin(UAA); BaseClientDetails clientDetails = new BaseClientDetails("client-id", null, null, null, null, "http://example.com/*/"); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.retrieve(eq("user-id-001"), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.update(anyString(), any(), eq(zoneId))).thenReturn(user); when(clientDetailsService.loadClientByClientId("acmeClientId", "uaa")).thenReturn(clientDetails); Map<String,String> userData = new HashMap<>(); userData.put(USER_ID, "user-id-001"); userData.put(EMAIL, "user@example.com"); userData.put(CLIENT_ID, "acmeClientId"); userData.put(REDIRECT_URI, "http://example.com/redirect/"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); String redirectLocation = emailInvitationsService.acceptInvitation("code", "password").getRedirectUri(); verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion(), zoneId); verify(scimUserProvisioning).changePassword(user.getId(), null, "password", zoneId); assertEquals("http://example.com/redirect/", redirectLocation); }
@Test public void acceptInvitationWithInvalidRedirectUri() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com", "first", "last"); user.setOrigin(UAA); BaseClientDetails clientDetails = new BaseClientDetails("client-id", null, null, null, null, "http://example.com/redirect"); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.update(anyString(), any(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.retrieve(eq("user-id-001"), eq(zoneId))).thenReturn(user); when(clientDetailsService.loadClientByClientId("acmeClientId")).thenReturn(clientDetails); Map<String,String> userData = new HashMap<>(); userData.put(USER_ID, "user-id-001"); userData.put(EMAIL, "user@example.com"); userData.put(REDIRECT_URI, "http://someother/redirect"); userData.put(CLIENT_ID, "acmeClientId"); when(expiringCodeStore.retrieveCode(anyString(), eq(zoneId))).thenReturn(new ExpiringCode("code", new Timestamp(System.currentTimeMillis()), JsonUtils.writeValueAsString(userData), INVITATION.name())); String redirectLocation = emailInvitationsService.acceptInvitation("code", "password").getRedirectUri(); verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion(), zoneId); verify(scimUserProvisioning).changePassword(user.getId(), null, "password", zoneId); assertEquals("/home", redirectLocation); }
@Test public void testAcceptInvite_doesNotDisplayConsentCheckboxWhenNotConfiguredForZone() throws Exception { IdentityProvider identityProvider = new IdentityProvider(); identityProvider.setType(OriginKeys.UAA); when(providerProvisioning.retrieveByOrigin(anyString(), anyString())).thenReturn(identityProvider); Map<String,String> codeData = getInvitationsCode(OriginKeys.UAA); String codeDataString = JsonUtils.writeValueAsString(codeData); ExpiringCode expiringCode = new ExpiringCode("thecode", new Timestamp(1), codeDataString, INVITATION.name()); when(expiringCodeStore.retrieveCode("thecode", IdentityZoneHolder.get().getId())) .thenReturn(expiringCode, null); when(expiringCodeStore.generateCode(anyString(), any(), eq(INVITATION.name()), eq(IdentityZoneHolder.get().getId()))) .thenReturn(expiringCode); mockMvc.perform(get("/invitations/accept") .param("code", "thecode")) .andExpect(content().string(not(containsString("I agree")))); }
@Test public void testBeginActivationWithUnverifiedExistingUser() throws Exception { String data = setUpForSuccess("existing-user-id", null); user.setId("existing-user-id"); user.setVerified(false); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.createUser(any(ScimUser.class), anyString(), eq(zoneId))).thenThrow(new ScimResourceAlreadyExistsException("duplicate")); when(scimUserProvisioning.query(anyString(), eq(zoneId))).thenReturn(Arrays.asList(new ScimUser[]{user})); when(codeStore.generateCode(eq(data), any(Timestamp.class), eq(REGISTRATION.name()), anyString())).thenReturn(code); MockHttpServletRequest request = new MockHttpServletRequest(); request.setProtocol("http"); request.setContextPath("/login"); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); emailAccountCreationService.beginActivation("user@example.com", "password", "login", null); verify(messageService).sendMessage( eq("user@example.com"), eq(MessageType.CREATE_ACCOUNT_CONFIRMATION), anyString(), anyString() ); }
@Test public void testAcceptInvite() throws Exception { ScimUser user = new ScimUser("user-id-001", "user@example.com","fname", "lname"); user.setPrimaryEmail(user.getUserName()); MockHttpServletRequestBuilder post = startAcceptInviteFlow("passw0rd","passw0rd"); Map<String,String> codeData = getInvitationsCode(OriginKeys.UAA); String codeDataString = JsonUtils.writeValueAsString(codeData); ExpiringCode thecode = new ExpiringCode("thecode", new Timestamp(1), codeDataString, INVITATION.name()); ExpiringCode thenewcode = new ExpiringCode("thenewcode", new Timestamp(1), codeDataString, INVITATION.name()); ExpiringCode thenewcode2 = new ExpiringCode("thenewcode2", new Timestamp(1), codeDataString, INVITATION.name()); when(expiringCodeStore.retrieveCode("thecode", IdentityZoneHolder.get().getId())).thenReturn(thecode, null); when(expiringCodeStore.retrieveCode("thenewcode", IdentityZoneHolder.get().getId())).thenReturn(thenewcode, null); when(expiringCodeStore.generateCode(eq(codeDataString), any(), eq(INVITATION.name()), eq(IdentityZoneHolder.get().getId()))) .thenReturn(thenewcode) .thenReturn(thenewcode2); when(invitationsService.acceptInvitation(anyString(), eq("passw0rd"))).thenReturn(new InvitationsService.AcceptedInvitation("/home", user)); MvcResult res = mockMvc.perform(post) .andExpect(status().isFound()) .andExpect(redirectedUrl("/login?success=invite_accepted")).andReturn(); verify(invitationsService).acceptInvitation(anyString(), eq("passw0rd")); }
private String setUpForSuccess(String userId, String redirectUri) throws Exception { user = new ScimUser( userId, "user@example.com", "givenName", "familyName"); user.setPrimaryEmail("user@example.com"); user.setPassword("password"); user.setOrigin(OriginKeys.UAA); user.setActive(true); user.setVerified(false); Timestamp ts = new Timestamp(System.currentTimeMillis() + (60 * 60 * 1000)); // 1 hour Map<String, Object> data = new HashMap<>(); data.put("user_id", userId); data.put("email", "user@example.com"); data.put("client_id", "login"); if (redirectUri != null) { data.put("redirect_uri", redirectUri); } code = new ExpiringCode("the_secret_code", ts, JsonUtils.writeValueAsString(data), REGISTRATION.name()); when(details.getClientId()).thenReturn("login"); when(details.getRegisteredRedirectUri()).thenReturn(Collections.singleton("http://example.com/*")); return JsonUtils.writeValueAsString(data); }