@Test
  public void createUserInOtherZoneWithUaaAdminTokenFromNonDefaultZone() throws Exception {
    IdentityZone identityZone = getIdentityZone();

    String authorities = "uaa.admin";
    clientDetails =
        utils()
            .createClient(
                this.getMockMvc(),
                uaaAdminToken,
                "testClientId",
                "testClientSecret",
                null,
                null,
                Collections.singletonList("client_credentials"),
                authorities,
                null,
                identityZone);
    String uaaAdminTokenFromOtherZone =
        testClient.getClientCredentialsOAuthAccessToken(
            "testClientId", "testClientSecret", "uaa.admin", identityZone.getSubdomain());

    byte[] requestBody = JsonUtils.writeValueAsBytes(getScimUser());
    MockHttpServletRequestBuilder post =
        post("/Users")
            .header("Authorization", "Bearer " + uaaAdminTokenFromOtherZone)
            .contentType(APPLICATION_JSON)
            .content(requestBody);
    post.with(new SetServerNameRequestPostProcessor(identityZone.getSubdomain() + ".localhost"));
    post.header(IdentityZoneSwitchingFilter.HEADER, IdentityZone.getUaa().getId());

    getMockMvc().perform(post).andExpect(status().isForbidden());
  }
 @Test
 public void test_cannot_delete_uaa_zone_users() throws Exception {
   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());
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from users where origin=? and identity_zone_id=?",
           new Object[] {UAA, IdentityZone.getUaa().getId()},
           Integer.class),
       is(3));
   IdentityProvider loginServer =
       new IdentityProvider().setOriginKey(UAA).setIdentityZoneId(IdentityZone.getUaa().getId());
   db.onApplicationEvent(new EntityDeletedEvent<>(loginServer));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from users where origin=? and identity_zone_id=?",
           new Object[] {UAA, IdentityZone.getUaa().getId()},
           Integer.class),
       is(3));
 }
 @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));
 }
  @Test
  public void createUserInOtherZoneWithUaaAdminToken() throws Exception {
    IdentityZone otherIdentityZone = getIdentityZone();

    createUser(
        getScimUser(),
        uaaAdminToken,
        IdentityZone.getUaa().getSubdomain(),
        otherIdentityZone.getId());
  }
  @Test
  public void test_can_delete_zone_users() 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));
    addApprovalAndMembership(created.getId(), created.getOrigin());
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from authz_approvals where user_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(1));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where member_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(1));

    db.onApplicationEvent(new EntityDeletedEvent<>(zone));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from users where origin=? and identity_zone_id=?",
            new Object[] {UAA, zone.getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from authz_approvals where user_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where member_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(0));
  }
  @Test
  public void test_can_delete_provider_users_in_default_zone() throws Exception {
    ScimUser user = new ScimUser(null, "*****@*****.**", "Jo", "User");
    user.addEmail("*****@*****.**");
    user.setOrigin(LOGIN_SERVER);
    ScimUser created = db.createUser(user, "j7hyqpassX");
    assertEquals("*****@*****.**", created.getUserName());
    assertNotNull(created.getId());
    assertEquals(LOGIN_SERVER, created.getOrigin());
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from users where origin=? and identity_zone_id=?",
            new Object[] {LOGIN_SERVER, IdentityZone.getUaa().getId()},
            Integer.class),
        is(1));
    addApprovalAndMembership(created.getId(), created.getOrigin());
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from authz_approvals where user_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(1));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where member_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(1));

    IdentityProvider loginServer =
        new IdentityProvider()
            .setOriginKey(LOGIN_SERVER)
            .setIdentityZoneId(IdentityZone.getUaa().getId());
    db.onApplicationEvent(new EntityDeletedEvent<>(loginServer));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from users where origin=? and identity_zone_id=?",
            new Object[] {LOGIN_SERVER, IdentityZone.getUaa().getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from authz_approvals where user_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where member_id=?",
            new Object[] {created.getId()},
            Integer.class),
        is(0));
  }
  @Before
  public void initJdbcScimGroupMembershipManagerTests() {

    JdbcTemplate template = new JdbcTemplate(dataSource);

    JdbcPagingListFactory pagingListFactory = new JdbcPagingListFactory(template, limitSqlAdapter);
    udao = new JdbcScimUserProvisioning(template, pagingListFactory);
    gdao = new JdbcScimGroupProvisioning(template, pagingListFactory);

    dao = new JdbcScimGroupMembershipManager(template, pagingListFactory);
    dao.setScimGroupProvisioning(gdao);
    dao.setScimUserProvisioning(udao);
    dao.setDefaultUserGroups(Collections.singleton("uaa.user"));

    for (String id : Arrays.asList(zone.getId(), IdentityZone.getUaa().getId())) {
      String g1 = id.equals(zone.getId()) ? zone.getId() + "-" + "g1" : "g1";
      String g2 = id.equals(zone.getId()) ? zone.getId() + "-" + "g2" : "g2";
      String g3 = id.equals(zone.getId()) ? zone.getId() + "-" + "g3" : "g3";
      String m1 = id.equals(zone.getId()) ? zone.getId() + "-" + "m1" : "m1";
      String m2 = id.equals(zone.getId()) ? zone.getId() + "-" + "m2" : "m2";
      String m3 = id.equals(zone.getId()) ? zone.getId() + "-" + "m3" : "m3";
      addGroup(g1, "test1", id);
      addGroup(g2, "test2", id);
      addGroup(g3, "test3", id);
      addUser(m1, "test", id);
      addUser(m2, "test", id);
      addUser(m3, "test", id);
      mapExternalGroup(g1, g1 + "-external", UAA);
      mapExternalGroup(g2, g2 + "-external", LOGIN_SERVER);
      mapExternalGroup(g3, g3 + "-external", UAA);
    }
    validateCount(0);
  }
  @Test
  public void testCreateZoneWithNonUniqueSubdomain() {
    IdentityZone idZone1 = new IdentityZone();
    String id1 = UUID.randomUUID().toString();
    idZone1.setId(id1);
    idZone1.setSubdomain(id1 + "non-unique");
    idZone1.setName("testCreateZone() " + id1);
    ResponseEntity<Void> response1 =
        client.exchange(
            serverRunning.getUrl("/identity-zones"),
            HttpMethod.POST,
            new HttpEntity<>(idZone1),
            new ParameterizedTypeReference<Void>() {},
            id1);
    assertEquals(HttpStatus.CREATED, response1.getStatusCode());

    IdentityZone idZone2 = new IdentityZone();
    String id2 = UUID.randomUUID().toString();
    idZone2.setId(id2);
    idZone2.setSubdomain(id1 + "non-unique");
    idZone2.setName("testCreateZone() " + id2);
    ResponseEntity<Map<String, String>> response2 =
        client.exchange(
            serverRunning.getUrl("/identity-zones"),
            HttpMethod.POST,
            new HttpEntity<>(idZone2),
            new ParameterizedTypeReference<Map<String, String>>() {},
            id2);
    assertEquals(HttpStatus.CONFLICT, response2.getStatusCode());
    Assert.assertTrue(
        response2.getBody().get("error_description").toLowerCase().contains("subdomain"));
  }
  @Before
  public void initScimExternalGroupBootstrapTests() {
    JdbcPagingListFactory pagingListFactory =
        new JdbcPagingListFactory(jdbcTemplate, limitSqlAdapter);
    gDB = new JdbcScimGroupProvisioning(jdbcTemplate, pagingListFactory);
    eDB = new JdbcScimGroupExternalMembershipManager(jdbcTemplate, pagingListFactory);
    ((JdbcScimGroupExternalMembershipManager) eDB).setScimGroupProvisioning(gDB);
    assertEquals(0, gDB.retrieveAll().size());

    gDB.create(new ScimGroup(null, "acme", IdentityZone.getUaa().getId()));
    gDB.create(new ScimGroup(null, "acme.dev", IdentityZone.getUaa().getId()));

    bootstrap = new ScimExternalGroupBootstrap(gDB, eDB);
  }
 @Test
 public void test_cannot_delete_uaa_provider() {
   IdentityZoneHolder.set(zone);
   addMembers(LOGIN_SERVER);
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from groups where identity_zone_id=?",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(3));
   IdentityProvider loginServer =
       new IdentityProvider().setOriginKey(UAA).setIdentityZoneId(zone.getId());
   gdao.onApplicationEvent(new EntityDeletedEvent<>(loginServer, null));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from groups where identity_zone_id=?",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(3));
 }
 @Test
 public void test_cannot_delete_uaa_zone() {
   addMembers();
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from groups where identity_zone_id=?",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
   gdao.onApplicationEvent(new EntityDeletedEvent<>(IdentityZone.getUaa(), null));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
   assertThat(
       jdbcTemplate.queryForObject(
           "select count(*) from groups where identity_zone_id=?",
           new Object[] {IdentityZoneHolder.get().getId()},
           Integer.class),
       is(4));
 }
  @Test
  public void listUsers_in_anotherZone() throws Exception {
    String subdomain = generator.generate();
    MockMvcUtils.IdentityZoneCreationResult result =
        utils()
            .createOtherIdentityZoneAndReturnResult(
                subdomain, getMockMvc(), getWebApplicationContext(), null);
    String zoneAdminToken = result.getZoneAdminToken();
    createUser(
        getScimUser(),
        zoneAdminToken,
        IdentityZone.getUaa().getSubdomain(),
        result.getIdentityZone().getId());

    MockHttpServletRequestBuilder get =
        MockMvcRequestBuilders.get("/Users")
            .header("X-Identity-Zone-Subdomain", subdomain)
            .header("Authorization", "Bearer " + zoneAdminToken)
            .accept(APPLICATION_JSON);

    MvcResult mvcResult = getMockMvc().perform(get).andExpect(status().isOk()).andReturn();
    SearchResults searchResults =
        JsonUtils.readValue(mvcResult.getResponse().getContentAsString(), SearchResults.class);
    MatcherAssert.assertThat(searchResults.getResources().size(), is(1));
  }
  @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
  public void testDeleteUserInOtherZoneWithUaaAdminToken() throws Exception {
    IdentityZone identityZone = getIdentityZone();
    ScimUser user = setUpScimUser(identityZone);

    getMockMvc()
        .perform(
            (delete("/Users/" + user.getId()))
                .header("Authorization", "Bearer " + uaaAdminToken)
                .header(IdentityZoneSwitchingFilter.HEADER, identityZone.getId())
                .contentType(APPLICATION_JSON)
                .content(JsonUtils.writeValueAsBytes(user)))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.userName").value(user.getUserName()))
        .andExpect(jsonPath("$.emails[0].value").value(user.getPrimaryEmail()))
        .andExpect(jsonPath("$.name.givenName").value(user.getGivenName()))
        .andExpect(jsonPath("$.name.familyName").value(user.getFamilyName()));
  }
  @Test
  public void testCreateZoneWithClient() throws IOException {
    IdentityZone idZone = new IdentityZone();
    String id = UUID.randomUUID().toString();
    idZone.setId(id);
    idZone.setSubdomain(id);
    idZone.setName("testCreateZone() " + id);
    ResponseEntity<Void> response =
        client.exchange(
            serverRunning.getUrl("/identity-zones"),
            HttpMethod.POST,
            new HttpEntity<>(idZone),
            new ParameterizedTypeReference<Void>() {},
            id);
    assertEquals(HttpStatus.CREATED, response.getStatusCode());

    BaseClientDetails clientDetails =
        new BaseClientDetails("test123", null, "openid", "authorization_code", "uaa.resource");
    clientDetails.setClientSecret("testSecret");
    clientDetails.addAdditionalInformation(
        ClientConstants.ALLOWED_PROVIDERS, Collections.singleton(Origin.UAA));

    ResponseEntity<Void> clientCreateResponse =
        client.exchange(
            serverRunning.getUrl("/identity-zones/" + id + "/clients"),
            HttpMethod.POST,
            new HttpEntity<>(clientDetails),
            new ParameterizedTypeReference<Void>() {},
            id);

    assertEquals(HttpStatus.CREATED, clientCreateResponse.getStatusCode());

    ResponseEntity<Void> clientDeleteResponse =
        client.exchange(
            serverRunning.getUrl(
                "/identity-zones/" + id + "/clients/" + clientDetails.getClientId()),
            HttpMethod.DELETE,
            null,
            new ParameterizedTypeReference<Void>() {},
            id);

    assertEquals(HttpStatus.OK, clientDeleteResponse.getStatusCode());
  }
 // we do not yet support default user groups for other zones
 public void setDefaultUserGroups(Set<String> groupNames) {
   Set<ScimGroup> usergroups = new HashSet<>();
   for (String name : groupNames) {
     List<ScimGroup> g =
         groupProvisioning.query(
             String.format(
                 "displayName co \"%s\" and identity_zone_id eq \""
                     + IdentityZone.getUaa().getId()
                     + "\"",
                 name));
     if (!g.isEmpty()) {
       usergroups.add(g.get(0));
     } else { // default group must exist, hence if not already present,
       // create it
       usergroups.add(
           groupProvisioning.create(new ScimGroup(null, name, IdentityZone.getUaa().getId())));
     }
   }
   defaultUserGroups.put(IdentityZone.getUaa(), usergroups);
 }
 @Test
 public void testCreateUserInZoneUsingZoneAdminUser() throws Exception {
   String subdomain = generator.generate();
   MockMvcUtils.IdentityZoneCreationResult result =
       utils()
           .createOtherIdentityZoneAndReturnResult(
               subdomain, getMockMvc(), getWebApplicationContext(), null);
   String zoneAdminToken = result.getZoneAdminToken();
   createUser(
       getScimUser(),
       zoneAdminToken,
       IdentityZone.getUaa().getSubdomain(),
       result.getIdentityZone().getId());
 }
  @Test
  public void testUserSelfAccess_Get_and_Post() throws Exception {
    ScimUser user = getScimUser();
    user.setPassword("secret");
    user = createUser(user, scimReadWriteToken, IdentityZone.getUaa().getSubdomain());

    String selfToken =
        testClient.getUserOAuthAccessToken("cf", "", user.getUserName(), "secret", "");

    user.setName(new ScimUser.Name("Given1", "Family1"));
    user = updateUser(selfToken, HttpStatus.OK.value(), user);

    user = getAndReturnUser(HttpStatus.OK.value(), user, selfToken);
  }
  @Before
  public void setUp() throws Exception {
    SecurityContextHolder.clearContext();
    IdentityZoneHolder.set(IdentityZone.getUaa());
    resetPasswordService = mock(ResetPasswordService.class);
    messageService = mock(MessageService.class);
    ResetPasswordController controller =
        new ResetPasswordController(
            resetPasswordService,
            messageService,
            templateEngine,
            new UaaUrlUtils("http://foo/uaa"),
            "pivotal");

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/WEB-INF/jsp");
    viewResolver.setSuffix(".jsp");
    mockMvc = MockMvcBuilders.standaloneSetup(controller).setViewResolvers(viewResolver).build();
  }
  @Test
  public void test_zone_deleted() {
    String zoneAdminId = generator.generate();
    addGroup(zoneAdminId, "zones." + zone.getId() + ".admin", IdentityZone.getUaa().getId());
    addMember(zoneAdminId, "m1", "USER", "MEMBER", OriginKeys.UAA);

    IdentityZoneHolder.set(zone);
    addMembers();
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(4));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from groups where identity_zone_id=?",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(3));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from external_group_mapping where group_id in (select id from groups where identity_zone_id=?)",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(3));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=? and displayName like ?)",
            new Object[] {
              IdentityZone.getUaa().getId(), "zones." + IdentityZoneHolder.get().getId() + ".%"
            },
            Integer.class),
        is(1));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from groups where identity_zone_id=? and displayName like ?",
            new Object[] {
              IdentityZone.getUaa().getId(), "zones." + IdentityZoneHolder.get().getId() + ".%"
            },
            Integer.class),
        is(1));
    gdao.onApplicationEvent(new EntityDeletedEvent<>(zone, null));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=?)",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from groups where identity_zone_id=?",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from external_group_mapping where group_id in (select id from groups where identity_zone_id=?)",
            new Object[] {IdentityZoneHolder.get().getId()},
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from group_membership where group_id in (select id from groups where identity_zone_id=? and displayName like ?)",
            new Object[] {
              IdentityZone.getUaa().getId(), "zones." + IdentityZoneHolder.get().getId() + ".%"
            },
            Integer.class),
        is(0));
    assertThat(
        jdbcTemplate.queryForObject(
            "select count(*) from groups where identity_zone_id=? and displayName like ?",
            new Object[] {
              IdentityZone.getUaa().getId(), "zones." + IdentityZoneHolder.get().getId() + ".%"
            },
            Integer.class),
        is(0));
  }
 @After
 public void tearDown() {
   SecurityContextHolder.clearContext();
   IdentityZoneHolder.set(IdentityZone.getUaa());
 }