private String extractPhoneNumber(final ScimUser user) {
   String phoneNumber = null;
   if (user.getPhoneNumbers() != null && !user.getPhoneNumbers().isEmpty()) {
     phoneNumber = user.getPhoneNumbers().get(0).getValue();
   }
   return phoneNumber;
 }
  @Test
  public void testUnlockAccountWhenNotLocked() throws Exception {
    ScimUser userToLockout = createUser(uaaAdminToken);

    UserAccountStatus alteredAccountStatus = new UserAccountStatus();
    alteredAccountStatus.setLocked(false);
    String jsonStatus = JsonUtils.writeValueAsString(alteredAccountStatus);
    getMockMvc()
        .perform(
            patch("/Users/" + userToLockout.getId() + "/status")
                .header("Authorization", "Bearer " + uaaAdminToken)
                .accept(APPLICATION_JSON)
                .contentType(APPLICATION_JSON)
                .content(jsonStatus))
        .andExpect(status().isOk())
        .andExpect(content().json(jsonStatus));

    getMockMvc()
        .perform(
            post("/login.do")
                .with(cookieCsrf())
                .param("username", userToLockout.getUserName())
                .param("password", userToLockout.getPassword()))
        .andExpect(redirectedUrl("/"));
  }
  @Test
  public void testUpdateUserPasswordDoesntChange() throws Exception {
    String username = "******" + new RandomValueStringGenerator().generate() + "@test.org";
    ScimUser scimUser = new ScimUser(null, username, "User", "Example");
    ScimUser.Email email = new ScimUser.Email();
    email.setValue(username);
    scimUser.setEmails(Arrays.asList(email));
    scimUser.setSalt("salt");
    scimUser = db.createUser(scimUser, "password");
    assertNotNull(scimUser);
    assertEquals("salt", scimUser.getSalt());
    scimUser.setSalt("newsalt");

    String passwordHash =
        jdbcTemplate.queryForObject(
            "select password from users where id=?", new Object[] {scimUser.getId()}, String.class);
    assertNotNull(passwordHash);

    db.changePassword(scimUser.getId(), null, "password");
    assertEquals(
        passwordHash,
        jdbcTemplate.queryForObject(
            "select password from users where id=?",
            new Object[] {scimUser.getId()},
            String.class));

    db.changePassword(scimUser.getId(), "password", "password");
    assertEquals(
        passwordHash,
        jdbcTemplate.queryForObject(
            "select password from users where id=?",
            new Object[] {scimUser.getId()},
            String.class));
  }
  @Test
  public void testCreateUserWithDuplicateUsernameInOtherIdp() throws Exception {
    addUser(
        "cba09242-aa43-4247-9aa0-b5c75c281f94",
        "*****@*****.**",
        "password",
        "*****@*****.**",
        "first",
        "user",
        "90438",
        defaultIdentityProviderId,
        "uaa");

    String origin = "test-origin";
    createOtherIdentityProvider(origin, IdentityZone.getUaa().getId());

    ScimUser scimUser = new ScimUser(null, "*****@*****.**", "User", "Example");
    ScimUser.Email email = new ScimUser.Email();
    email.setValue("*****@*****.**");
    scimUser.setEmails(Arrays.asList(email));
    scimUser.setPassword("password");
    scimUser.setOrigin(origin);
    String userId2 = db.create(scimUser).getId();
    assertNotNull(userId2);
    assertNotEquals("cba09242-aa43-4247-9aa0-b5c75c281f94", userId2);
  }
  @Test
  @OAuth2ContextConfiguration(
      resource = OAuth2ContextConfiguration.Implicit.class,
      initialize = false)
  public void testUserMustSupplyOldPassword() throws Exception {

    MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
    parameters.set("source", "credentials");
    parameters.set("username", joe.getUserName());
    parameters.set("password", "pas5Word");
    context.getAccessTokenRequest().putAll(parameters);

    PasswordChangeRequest change = new PasswordChangeRequest();
    change.setPassword("Newpasswo3d");

    HttpHeaders headers = new HttpHeaders();
    ResponseEntity<Void> result =
        client.exchange(
            serverRunning.getUrl(userEndpoint) + "/{id}/password",
            HttpMethod.PUT,
            new HttpEntity<>(change, headers),
            Void.class,
            joe.getId());
    assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode());
  }
  @Test
  public void testResetPasswordSuccess() throws Exception {
    ScimUser user = new ScimUser("user-id", "*****@*****.**", "firstName", "lastName");
    user.setMeta(
        new ScimMeta(
            new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)),
            new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)),
            0));
    user.setPrimaryEmail("*****@*****.**");
    when(resetPasswordService.resetPassword("secret_code", "password")).thenReturn(user);

    MockHttpServletRequestBuilder post =
        post("/reset_password.do")
            .contentType(APPLICATION_FORM_URLENCODED)
            .param("code", "secret_code")
            .param("email", "*****@*****.**")
            .param("password", "password")
            .param("password_confirmation", "password");
    mockMvc
        .perform(post)
        .andExpect(status().isFound())
        .andExpect(redirectedUrl("home"))
        .andExpect(model().attributeDoesNotExist("code"))
        .andExpect(model().attributeDoesNotExist("password"))
        .andExpect(model().attributeDoesNotExist("password_confirmation"));
  }
 @Override
 public ScimUser verifyUser(String id, int version)
     throws ScimResourceNotFoundException, InvalidScimResourceException {
   logger.debug("Verifying user: "******" and version=?",
             true,
             id,
             IdentityZoneHolder.get().getId(),
             version);
   }
   ScimUser user = retrieve(id);
   if (updated == 0) {
     throw new OptimisticLockingFailureException(
         String.format(
             "Attempt to update a user (%s) with wrong version: expected=%d but found=%d",
             user.getId(), user.getVersion(), version));
   }
   if (updated > 1) {
     throw new IncorrectResultSizeDataAccessException(1);
   }
   return user;
 }
  @Test
  public void testCreateUserWithDuplicateUsername() throws Exception {
    addUser(
        "cba09242-aa43-4247-9aa0-b5c75c281f94",
        "*****@*****.**",
        "password",
        "*****@*****.**",
        "first",
        "user",
        "90438",
        defaultIdentityProviderId,
        "uaa");
    ScimUser scimUser = new ScimUser("user-id-2", "*****@*****.**", "User", "Example");
    ScimUser.Email email = new ScimUser.Email();
    email.setValue("*****@*****.**");
    scimUser.setEmails(Arrays.asList(email));
    scimUser.setPassword("password");

    try {
      db.create(scimUser);
      fail("Should have thrown an exception");
    } catch (ScimResourceAlreadyExistsException e) {
      Map<String, Object> userDetails = new HashMap<>();
      userDetails.put("active", true);
      userDetails.put("verified", false);
      userDetails.put("user_id", "cba09242-aa43-4247-9aa0-b5c75c281f94");
      assertEquals(HttpStatus.CONFLICT, e.getStatus());
      assertEquals("Username already in use: [email protected]", e.getMessage());
      assertEquals(userDetails, e.getExtraInfo());
    }
  }
  @Test
  public void acceptInvitationWithInvalidRedirectUri() throws Exception {
    ScimUser user = new ScimUser("user-id-001", "*****@*****.**", "first", "last");
    user.setOrigin(UAA);
    BaseClientDetails clientDetails =
        new BaseClientDetails("client-id", null, null, null, null, "http://example.com/redirect");
    when(scimUserProvisioning.verifyUser(anyString(), anyInt())).thenReturn(user);
    when(scimUserProvisioning.update(anyString(), anyObject())).thenReturn(user);
    when(scimUserProvisioning.retrieve(eq("user-id-001"))).thenReturn(user);
    when(clientDetailsService.loadClientByClientId("acmeClientId")).thenReturn(clientDetails);
    Map<String, String> userData = new HashMap<>();
    userData.put(USER_ID, "user-id-001");
    userData.put(EMAIL, "*****@*****.**");
    userData.put(REDIRECT_URI, "http://someother/redirect");
    userData.put(CLIENT_ID, "acmeClientId");
    when(expiringCodeStore.retrieveCode(anyString()))
        .thenReturn(
            new ExpiringCode(
                "code",
                new Timestamp(System.currentTimeMillis()),
                JsonUtils.writeValueAsString(userData)));

    String redirectLocation =
        emailInvitationsService.acceptInvitation("code", "password").getRedirectUri();

    verify(scimUserProvisioning).verifyUser(user.getId(), user.getVersion());
    verify(scimUserProvisioning).changePassword(user.getId(), null, "password");
    assertEquals("/home", redirectLocation);
  }
 @Test
 public void canCreateUserWithExclamationMarkInUsername() {
   String userName = "******";
   ScimUser user = new ScimUser(null, userName, "Jo", "User");
   user.addEmail(userName);
   ScimUser created = db.createUser(user, "j7hyqpassX");
   assertEquals(userName, created.getUserName());
 }
 @Test
 public void updateWithEmptyPhoneNumberWorks() {
   ScimUser jo = new ScimUser(null, "josephine", "Jo", "NewUser");
   PhoneNumber emptyNumber = new PhoneNumber();
   jo.addEmail("*****@*****.**");
   jo.setPhoneNumbers(Arrays.asList(emptyNumber));
   ScimUser joe = db.update(JOE_ID, jo);
 }
 @Test
 public void test_Create_User_More_Than_One_Email() throws Exception {
   ScimUser scimUser = getScimUser();
   String secondEmail = "joe@" + generator.generate().toLowerCase() + ".com";
   scimUser.addEmail(secondEmail);
   createUserAndReturnResult(scimUser, scimReadWriteToken, null, null)
       .andExpect(status().isBadRequest());
 }
 private ScimUser getScimUser() {
   String email = "joe@" + generator.generate().toLowerCase() + ".com";
   ScimUser user = new ScimUser();
   user.setUserName(email);
   user.setName(new ScimUser.Name("Joe", "User"));
   user.addEmail(email);
   return user;
 }
 @Test(expected = OptimisticLockingFailureException.class)
 public void updateWithWrongVersionIsError() {
   ScimUser jo = new ScimUser(null, "josephine", "Jo", "NewUser");
   jo.addEmail("*****@*****.**");
   jo.setVersion(1);
   ScimUser joe = db.update(JOE_ID, jo);
   assertEquals("joe", joe.getUserName());
 }
 @Test(expected = InvalidScimResourceException.class)
 public void updateWithBadUsernameIsError() {
   ScimUser jo = new ScimUser(null, "jo$ephine", "Jo", "NewUser");
   jo.addEmail("*****@*****.**");
   jo.setVersion(1);
   ScimUser joe = db.update(JOE_ID, jo);
   assertEquals("joe", joe.getUserName());
 }
 @Test
 public void testCanCreateUserWithExclamationMark() throws Exception {
   String email = "joe!!@" + generator.generate().toLowerCase() + ".com";
   ScimUser user = getScimUser();
   user.getEmails().clear();
   user.setUserName(email);
   user.setPrimaryEmail(email);
   createUser(user, scimReadWriteToken, null);
 }
 private void validate(final ScimUser user) throws InvalidScimResourceException {
   if (!usernamePattern.matcher(user.getUserName()).matches()) {
     throw new InvalidScimResourceException(
         "Username must match pattern: " + usernamePattern.pattern());
   }
   if (user.getEmails() == null || user.getEmails().isEmpty()) {
     throw new InvalidScimResourceException("An email must be provided.");
   }
 }
 @Test
 public void testCreatedUserNotVerified() {
   String tmpUserIdString = createUserForDelete();
   boolean verified = template.queryForObject(verifyUserSqlFormat, Boolean.class, tmpUserIdString);
   assertFalse(verified);
   ScimUser user = db.retrieve(tmpUserIdString);
   assertFalse(user.isVerified());
   removeUser(tmpUserIdString);
 }
 @Test
 public void testUpdatedVersionedUserVerified() {
   String tmpUserIdString = createUserForDelete();
   ScimUser user = db.retrieve(tmpUserIdString);
   assertFalse(user.isVerified());
   user = db.verifyUser(tmpUserIdString, user.getVersion());
   assertTrue(user.isVerified());
   removeUser(tmpUserIdString);
 }
 @Test
 public void testCreatedUserNotVerified() {
   String tmpUserIdString = createUserForDelete();
   boolean verified =
       jdbcTemplate.queryForObject(VERIFY_USER_SQL_FORMAT, Boolean.class, tmpUserIdString);
   assertFalse(verified);
   ScimUser user = db.retrieve(tmpUserIdString);
   assertFalse(user.isVerified());
   removeUser(tmpUserIdString);
 }
 @Test
 public void testUserVerifiedThroughUpdate() {
   String tmpUserIdString = createUserForDelete();
   ScimUser user = db.retrieve(tmpUserIdString);
   assertFalse(user.isVerified());
   user.setVerified(true);
   user = db.update(tmpUserIdString, user);
   assertTrue(user.isVerified());
   removeUser(tmpUserIdString);
 }
 @After
 public void clean() {
   JdbcTemplate jdbcTemplate = new JdbcTemplate(database);
   if (joel != null) {
     jdbcTemplate.update("delete from users where id=?", joel.getId());
   }
   if (dale != null) {
     jdbcTemplate.update("delete from users where id=?", dale.getId());
   }
 }
  @Test
  public void verification_link_is_authorized_endpoint() throws Exception {
    ScimUser joel = setUpScimUser();

    MockHttpServletRequestBuilder get =
        MockMvcRequestBuilders.get("/Users/" + joel.getId() + "/verify-link")
            .param("redirect_uri", HTTP_REDIRECT_EXAMPLE_COM)
            .accept(APPLICATION_JSON);

    getMockMvc().perform(get).andExpect(status().isUnauthorized());
  }
 @Test(expected = OptimisticLockingFailureException.class)
 public void testUpdatedIncorrectVersionUserVerified() {
   String tmpUserIdString = createUserForDelete();
   try {
     ScimUser user = db.retrieve(tmpUserIdString);
     assertFalse(user.isVerified());
     user = db.verifyUser(tmpUserIdString, user.getVersion() + 50);
     assertTrue(user.isVerified());
   } finally {
     removeUser(tmpUserIdString);
   }
 }
 @Test(expected = ScimResourceNotFoundException.class)
 public void testUserVerifiedInvalidUserId() {
   String tmpUserIdString = createUserForDelete();
   try {
     ScimUser user = db.retrieve(tmpUserIdString);
     assertFalse(user.isVerified());
     user = db.verifyUser("-1-1-1", -1);
     assertTrue(user.isVerified());
   } finally {
     removeUser(tmpUserIdString);
   }
 }
 @Test(expected = ScimResourceAlreadyExistsException.class)
 public void cannotDeactivateExistingUserAndThenCreateHimAgain() {
   String tmpUserId = createUserForDelete();
   ScimUser deletedUser = db.delete(tmpUserId, 0);
   deletedUser.setActive(true);
   try {
     db.createUser(deletedUser, "foobarspam1234");
   } catch (ScimResourceAlreadyExistsException e) {
     removeUser(tmpUserId);
     throw e;
   }
 }
  @Test
  public void canAddNonExistentGroupThroughEvent() throws Exception {
    String[] externalAuthorities = new String[] {"extTest1", "extTest2", "extTest3"};
    String[] userAuthorities = new String[] {"usrTest1", "usrTest2", "usrTest3"};
    String origin = "testOrigin";
    String email = "*****@*****.**";
    String firstName = "FirstName";
    String lastName = "LastName";
    String password = "";
    String externalId = null;
    String userId = new RandomValueStringGenerator().generate();
    String username = new RandomValueStringGenerator().generate();
    UaaUser user =
        getUaaUser(
            userAuthorities,
            origin,
            email,
            firstName,
            lastName,
            password,
            externalId,
            userId,
            username);
    ScimUserBootstrap bootstrap = new ScimUserBootstrap(db, gdb, mdb, Arrays.asList(user));
    bootstrap.afterPropertiesSet();

    List<ScimUser> users =
        db.query("userName eq \"" + username + "\" and origin eq \"" + origin + "\"");
    assertEquals(1, users.size());
    userId = users.get(0).getId();
    user =
        getUaaUser(
            userAuthorities,
            origin,
            email,
            firstName,
            lastName,
            password,
            externalId,
            userId,
            username);
    bootstrap.onApplicationEvent(
        new ExternalGroupAuthorizationEvent(user, getAuthorities(externalAuthorities)));

    users = db.query("userName eq \"" + username + "\" and origin eq \"" + origin + "\"");
    assertEquals(1, users.size());
    ScimUser created = users.get(0);
    Set<ScimGroup> groups = mdb.getGroupsWithMember(created.getId(), true);
    String[] expected = merge(externalAuthorities, userAuthorities);
    String[] actual = getGroupNames(groups);
    assertThat(actual, IsArrayContainingInAnyOrder.arrayContainingInAnyOrder(expected));
  }
 @Test
 public void canDeactivateExistingUser() {
   String tmpUserId = createUserForDelete();
   ScimUser deletedUser = db.delete(tmpUserId, 0);
   assertEquals(
       1,
       template
           .queryForList("select * from users where id=? and active=?", tmpUserId, false)
           .size());
   assertFalse(deletedUser.isActive());
   assertEquals(1, db.query("username eq \"" + tmpUserId + "\" and active eq false").size());
   removeUser(tmpUserId);
 }
  @Test
  public void getUserFromOtherZoneWithUaaAdminToken() throws Exception {
    IdentityZone otherIdentityZone = getIdentityZone();

    ScimUser user = setUpScimUser(otherIdentityZone);

    MockHttpServletRequestBuilder get =
        MockMvcRequestBuilders.get("/Users/", user.getId())
            .header("Authorization", "Bearer " + uaaAdminToken)
            .accept(APPLICATION_JSON);

    getMockMvc().perform(get).andExpect(status().isOk());
  }
 @Test
 public void test_cannot_delete_uaa_provider_users_in_other_zone() throws Exception {
   String id = generator.generate();
   IdentityZone zone = MultitenancyFixture.identityZone(id, id);
   IdentityZoneHolder.set(zone);
   ScimUser user = new ScimUser(null, "*****@*****.**", "Jo", "User");
   user.addEmail("*****@*****.**");
   user.setOrigin(UAA);
   ScimUser created = db.createUser(user, "j7hyqpassX");
   assertEquals("*****@*****.**", created.getUserName());
   assertNotNull(created.getId());
   assertEquals(UAA, created.getOrigin());
   assertEquals(zone.getId(), created.getZoneId());
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from users where origin=? and identity_zone_id=?",
           new Object[] {UAA, zone.getId()},
           Integer.class),
       is(1));
   IdentityProvider loginServer =
       new IdentityProvider().setOriginKey(UAA).setIdentityZoneId(zone.getId());
   db.onApplicationEvent(new EntityDeletedEvent<>(loginServer));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from users where origin=? and identity_zone_id=?",
           new Object[] {UAA, zone.getId()},
           Integer.class),
       is(1));
 }