@Test
  public void patch_user_to_inactive_then_login() throws Exception {
    ScimUser user = setUpScimUser();
    user.setVerified(true);
    boolean active = true;
    user.setActive(active);
    getMockMvc()
        .perform(
            patch("/Users/" + user.getId())
                .header("Authorization", "Bearer " + scimReadWriteToken)
                .header("If-Match", "\"" + user.getVersion() + "\"")
                .contentType(APPLICATION_JSON)
                .content(JsonUtils.writeValueAsString(user)))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.active", equalTo(active)));

    performAuthentication(user, true);

    active = false;
    user.setActive(active);
    getMockMvc()
        .perform(
            patch("/Users/" + user.getId())
                .header("Authorization", "Bearer " + scimReadWriteToken)
                .header("If-Match", "\"" + (user.getVersion() + 1) + "\"")
                .contentType(APPLICATION_JSON)
                .content(JsonUtils.writeValueAsString(user)))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.active", equalTo(active)));

    performAuthentication(user, false);
  }
  @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 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("/"));
  }
Ejemplo n.º 4
0
 private String getData(Approval source) {
   try {
     return JsonUtils.writeValueAsString(new ApprovalModifiedEventData(source));
   } catch (JsonUtils.JsonUtilException e) {
     logger.error("error writing approval event data", e);
   }
   return null;
 }
  // TODO: add cases for username no existing external user with username not email
  @Test
  public void accept_invitation_with_external_user_that_does_not_have_email_as_their_username() {
    String userId = "user-id-001";
    String email = "*****@*****.**";
    String actualUsername = "******";
    ScimUser userBeforeAccept = new ScimUser(userId, email, "first", "last");
    userBeforeAccept.setPrimaryEmail(email);
    userBeforeAccept.setOrigin(Origin.SAML);

    when(scimUserProvisioning.verifyUser(eq(userId), anyInt())).thenReturn(userBeforeAccept);
    when(scimUserProvisioning.retrieve(eq(userId))).thenReturn(userBeforeAccept);

    BaseClientDetails clientDetails =
        new BaseClientDetails("client-id", null, null, null, null, "http://example.com/redirect");
    when(clientDetailsService.loadClientByClientId("acmeClientId")).thenReturn(clientDetails);

    Map<String, String> userData = new HashMap<>();
    userData.put(USER_ID, userBeforeAccept.getId());
    userData.put(EMAIL, userBeforeAccept.getPrimaryEmail());
    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)));

    ScimUser userAfterAccept =
        new ScimUser(
            userId,
            actualUsername,
            userBeforeAccept.getGivenName(),
            userBeforeAccept.getFamilyName());
    userAfterAccept.setPrimaryEmail(email);

    when(scimUserProvisioning.verifyUser(eq(userId), anyInt())).thenReturn(userAfterAccept);

    ScimUser acceptedUser = emailInvitationsService.acceptInvitation("code", "password").getUser();
    assertEquals(userAfterAccept.getUserName(), acceptedUser.getUserName());
    assertEquals(userAfterAccept.getName(), acceptedUser.getName());
    assertEquals(userAfterAccept.getPrimaryEmail(), acceptedUser.getPrimaryEmail());

    verify(scimUserProvisioning).verifyUser(eq(userId), anyInt());
  }
  @Test
  public void create_user_without_email() throws Exception {
    ScimUser joel = new ScimUser(null, "a_user", "Joel", "D'sa");

    getMockMvc()
        .perform(
            post("/Users")
                .header("Authorization", "Bearer " + scimReadWriteToken)
                .contentType(APPLICATION_JSON)
                .content(JsonUtils.writeValueAsString(joel)))
        .andExpect(status().isBadRequest())
        .andExpect(
            content()
                .string(
                    JsonObjectMatcherUtils.matchesJsonObject(
                        new JSONObject()
                            .put("error_description", "Exactly one email must be provided.")
                            .put("message", "Exactly one email must be provided.")
                            .put("error", "invalid_scim_resource"))));
  }
  @Test
  public void create_user_then_update_without_email() throws Exception {
    ScimUser user = setUpScimUser();
    user.setEmails(null);

    getMockMvc()
        .perform(
            put("/Users/" + user.getId())
                .header("Authorization", "Bearer " + scimReadWriteToken)
                .header("If-Match", "\"" + user.getVersion() + "\"")
                .contentType(APPLICATION_JSON)
                .content(JsonUtils.writeValueAsString(user)))
        .andExpect(status().isBadRequest())
        .andExpect(
            content()
                .string(
                    JsonObjectMatcherUtils.matchesJsonObject(
                        new JSONObject()
                            .put("error_description", "Exactly one email must be provided.")
                            .put("message", "Exactly one email must be provided.")
                            .put("error", "invalid_scim_resource"))));
  }
  @Test
  public void testAccountStatusEmptyPatchDoesNotUnlock() throws Exception {
    ScimUser userToLockout = createUser(uaaAdminToken);
    attemptFailedLogin(5, userToLockout.getUserName(), "");

    String jsonStatus = JsonUtils.writeValueAsString(Collections.emptyMap());
    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("/login?error=account_locked"));
  }
Ejemplo n.º 9
0
  @RequestMapping(
      value = "/invite_users",
      method = RequestMethod.POST,
      consumes = "application/json")
  public ResponseEntity<InvitationsResponse> inviteUsers(
      @RequestBody InvitationsRequest invitations,
      @RequestParam(value = "client_id", required = false) String clientId,
      @RequestParam(value = "redirect_uri") String redirectUri) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication instanceof OAuth2Authentication) {
      OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication;

      if (clientId == null) {
        clientId = oAuth2Authentication.getOAuth2Request().getClientId();
      }
    }

    InvitationsResponse invitationsResponse = new InvitationsResponse();

    DomainFilter filter = new DomainFilter();
    List<IdentityProvider> activeProviders =
        providers.retrieveActive(IdentityZoneHolder.get().getId());
    ClientDetails client = clients.loadClientByClientId(clientId);
    for (String email : invitations.getEmails()) {
      try {
        List<IdentityProvider> providers = filter.filter(activeProviders, client, email);
        if (providers.size() == 1) {
          ScimUser user = findOrCreateUser(email, providers.get(0).getOriginKey());

          String accountsUrl = UaaUrlUtils.getUaaUrl("/invitations/accept");

          Map<String, String> data = new HashMap<>();
          data.put(InvitationConstants.USER_ID, user.getId());
          data.put(InvitationConstants.EMAIL, user.getPrimaryEmail());
          data.put(CLIENT_ID, clientId);
          data.put(REDIRECT_URI, redirectUri);
          data.put(ORIGIN, user.getOrigin());
          Timestamp expiry =
              new Timestamp(
                  System.currentTimeMillis() + (INVITATION_EXPIRY_DAYS * 24 * 60 * 60 * 1000));
          ExpiringCode code =
              expiringCodeStore.generateCode(JsonUtils.writeValueAsString(data), expiry, null);

          String invitationLink = accountsUrl + "?code=" + code.getCode();
          try {
            URL inviteLink = new URL(invitationLink);
            invitationsResponse
                .getNewInvites()
                .add(
                    InvitationsResponse.success(
                        user.getPrimaryEmail(), user.getId(), user.getOrigin(), inviteLink));
          } catch (MalformedURLException mue) {
            invitationsResponse
                .getFailedInvites()
                .add(
                    InvitationsResponse.failure(
                        email,
                        "invitation.exception.url",
                        String.format("Malformed url", invitationLink)));
          }
        } else if (providers.size() == 0) {
          invitationsResponse
              .getFailedInvites()
              .add(
                  InvitationsResponse.failure(
                      email, "provider.non-existent", "No authentication provider found."));
        } else {
          invitationsResponse
              .getFailedInvites()
              .add(
                  InvitationsResponse.failure(
                      email, "provider.ambiguous", "Multiple authentication providers found."));
        }
      } catch (ScimResourceConflictException x) {
        invitationsResponse
            .getFailedInvites()
            .add(
                InvitationsResponse.failure(
                    email,
                    "user.ambiguous",
                    "Multiple users with the same origin matched to the email address."));
      } catch (UaaException uaae) {
        invitationsResponse
            .getFailedInvites()
            .add(InvitationsResponse.failure(email, "invitation.exception", uaae.getMessage()));
      }
    }
    return new ResponseEntity<>(invitationsResponse, HttpStatus.OK);
  }
Ejemplo n.º 10
0
  @Test
  public void inviteUsers() throws Exception {
    String[] emails = new String[] {"user1@" + domain, "user2@" + domain};
    String redirectUri = "example.com";

    InvitationsRequest invitationsRequest = new InvitationsRequest(emails);
    String requestBody = JsonUtils.writeValueAsString(invitationsRequest);

    Snippet requestFields =
        requestFields(
            fieldWithPath("emails")
                .attributes(key("constraints").value("Required"))
                .description(
                    "User is invited by providing an email address. More than one email addresses can be provided."));

    Snippet requestParameters =
        requestParameters(
            parameterWithName("client_id")
                .attributes(key("constraints").value("Optional"), key("type").value(STRING))
                .description(
                    "A unique string representing the registration information provided by the client"),
            parameterWithName("redirect_uri")
                .attributes(key("constraints").value("Required"), key("type").value(STRING))
                .description(
                    "The user will be redirected to this uri, when user accepts the invitation. The redirect_uri will be validated against allowed redirect_uri for the client."));

    Snippet responseFields =
        responseFields(
            fieldWithPath("new_invites[].email")
                .type(STRING)
                .description("Primary email id of the invited user"),
            fieldWithPath("new_invites[].userId")
                .type(STRING)
                .description("A unique string for the invited user"),
            fieldWithPath("new_invites[].origin")
                .type(STRING)
                .description("Unique alias of the provider"),
            fieldWithPath("new_invites[].success")
                .type(BOOLEAN)
                .description("Flag to determine whether the invitation was sent successfully"),
            fieldWithPath("new_invites[].errorCode")
                .type(STRING)
                .description("Error code in case of failure to send invitation"),
            fieldWithPath("new_invites[].errorMessage")
                .type(STRING)
                .description("Error message in case of failure to send invitation"),
            fieldWithPath("new_invites[].inviteLink")
                .type(STRING)
                .description("Invitation link to invite users"),
            fieldWithPath("failed_invites")
                .type(STRING)
                .description("List of invites having exception in sending the invitation"));

    getMockMvc()
        .perform(
            post("/invite_users?"
                    + String.format("%s=%s&%s=%s", CLIENT_ID, clientId, REDIRECT_URI, redirectUri))
                .header("Authorization", "Bearer " + token)
                .contentType(APPLICATION_JSON)
                .content(requestBody))
        .andExpect(status().isOk())
        .andDo(
            document(
                "{ClassName}/{methodName}",
                preprocessRequest(prettyPrint()),
                preprocessResponse(prettyPrint()),
                requestHeaders(
                    headerWithName("Authorization")
                        .description("Bearer token containing `scim.invite`")),
                requestParameters,
                requestFields,
                responseFields));
  }