Example #1
0
  /**
   * Update the TOTP for this account.
   *
   * <p>form parameters:
   *
   * <p>totp - otp generated by authenticator totpSecret - totp secret to register
   *
   * @param formData
   * @return
   */
  @Path("totp")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response processTotpUpdate(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
      return login("totp");
    }

    require(AccountRoles.MANAGE_ACCOUNT);

    String action = formData.getFirst("submitAction");
    if (action != null && action.equals("Cancel")) {
      setReferrerOnPage();
      return account.createResponse(AccountPages.TOTP);
    }

    csrfCheck(formData);

    UserModel user = auth.getUser();

    String totp = formData.getFirst("totp");
    String totpSecret = formData.getFirst("totpSecret");

    if (Validation.isBlank(totp)) {
      setReferrerOnPage();
      return account.setError(Messages.MISSING_TOTP).createResponse(AccountPages.TOTP);
    } else if (!CredentialValidation.validOTP(realm, totp, totpSecret)) {
      setReferrerOnPage();
      return account.setError(Messages.INVALID_TOTP).createResponse(AccountPages.TOTP);
    }

    UserCredentialModel credentials = new UserCredentialModel();
    credentials.setType(realm.getOTPPolicy().getType());
    credentials.setValue(totpSecret);
    session.users().updateCredential(realm, user, credentials);

    user.setOtpEnabled(true);

    // to update counter
    UserCredentialModel cred = new UserCredentialModel();
    cred.setType(realm.getOTPPolicy().getType());
    cred.setValue(totp);
    session.users().validCredentials(realm, user, cred);

    event.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success();

    setReferrerOnPage();
    return account.setSuccess(Messages.SUCCESS_TOTP).createResponse(AccountPages.TOTP);
  }
Example #2
0
  @Path("revoke-grant")
  @POST
  public Response processRevokeGrant(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
      return login("applications");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(formData);

    String clientId = formData.getFirst("clientId");
    if (clientId == null) {
      return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS);
    }
    ClientModel client = realm.getClientById(clientId);
    if (client == null) {
      return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS);
    }

    // Revoke grant in UserModel
    UserModel user = auth.getUser();
    user.revokeConsentForClient(client.getId());
    OfflineTokenUtils.revokeOfflineToken(session, realm, user, client);

    // Logout clientSessions for this user and client
    AuthenticationManager.backchannelUserFromClient(session, realm, user, client, uriInfo, headers);

    event
        .event(EventType.REVOKE_GRANT)
        .client(auth.getClient())
        .user(auth.getUser())
        .detail(Details.REVOKED_CLIENT, client.getClientId())
        .success();
    setReferrerOnPage();

    UriBuilder builder =
        Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "applicationsPage");
    String referrer = uriInfo.getQueryParameters().getFirst("referrer");
    if (referrer != null) {
      builder.queryParam("referrer", referrer);
    }
    URI location = builder.build(realm.getName());
    return Response.seeOther(location).build();
  }
Example #3
0
  @Path("federated-identity-update")
  @GET
  public Response processFederatedIdentityUpdate(
      @QueryParam("action") String action,
      @QueryParam("provider_id") String providerId,
      @QueryParam("stateChecker") String stateChecker) {
    if (auth == null) {
      return login("identity");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(stateChecker);
    UserModel user = auth.getUser();

    if (Validation.isEmpty(providerId)) {
      setReferrerOnPage();
      return account
          .setError(Messages.MISSING_IDENTITY_PROVIDER)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }
    AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action);
    if (accountSocialAction == null) {
      setReferrerOnPage();
      return account
          .setError(Messages.INVALID_FEDERATED_IDENTITY_ACTION)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    boolean hasProvider = false;

    for (IdentityProviderModel model : realm.getIdentityProviders()) {
      if (model.getAlias().equals(providerId)) {
        hasProvider = true;
      }
    }

    if (!hasProvider) {
      setReferrerOnPage();
      return account
          .setError(Messages.IDENTITY_PROVIDER_NOT_FOUND)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    if (!user.isEnabled()) {
      setReferrerOnPage();
      return account
          .setError(Messages.ACCOUNT_DISABLED)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    switch (accountSocialAction) {
      case ADD:
        String redirectUri =
            UriBuilder.fromUri(
                    Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName()))
                .build()
                .toString();

        try {
          ClientSessionModel clientSession = auth.getClientSession();
          ClientSessionCode clientSessionCode = new ClientSessionCode(realm, clientSession);
          clientSessionCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
          clientSession.setRedirectUri(redirectUri);
          clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString());

          return Response.temporaryRedirect(
                  Urls.identityProviderAuthnRequest(
                      this.uriInfo.getBaseUri(),
                      providerId,
                      realm.getName(),
                      clientSessionCode.getCode()))
              .build();
        } catch (Exception spe) {
          setReferrerOnPage();
          return account
              .setError(Messages.IDENTITY_PROVIDER_REDIRECT_ERROR)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      case REMOVE:
        FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
        if (link != null) {

          // Removing last social provider is not possible if you don't have other possibility to
          // authenticate
          if (session.users().getFederatedIdentities(user, realm).size() > 1
              || user.getFederationLink() != null
              || isPasswordSet(user)) {
            session.users().removeFederatedIdentity(realm, user, providerId);

            logger.debugv(
                "Social provider {0} removed successfully from user {1}",
                providerId, user.getUsername());

            event
                .event(EventType.REMOVE_FEDERATED_IDENTITY)
                .client(auth.getClient())
                .user(auth.getUser())
                .detail(Details.USERNAME, link.getUserId() + "@" + link.getIdentityProvider())
                .success();

            setReferrerOnPage();
            return account
                .setSuccess(Messages.IDENTITY_PROVIDER_REMOVED)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          } else {
            setReferrerOnPage();
            return account
                .setError(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          }
        } else {
          setReferrerOnPage();
          return account
              .setError(Messages.FEDERATED_IDENTITY_NOT_ACTIVE)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      default:
        throw new IllegalArgumentException();
    }
  }
Example #4
0
  /**
   * Update account password
   *
   * <p>Form params:
   *
   * <p>password - old password password-new pasword-confirm
   *
   * @param formData
   * @return
   */
  @Path("password")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response processPasswordUpdate(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
      return login("password");
    }

    require(AccountRoles.MANAGE_ACCOUNT);

    String action = formData.getFirst("submitAction");
    if (action != null && action.equals("Cancel")) {
      setReferrerOnPage();
      return account.createResponse(AccountPages.PASSWORD);
    }

    csrfCheck(formData);
    UserModel user = auth.getUser();

    boolean requireCurrent = isPasswordSet(user);
    account.setPasswordSet(requireCurrent);

    String password = formData.getFirst("password");
    String passwordNew = formData.getFirst("password-new");
    String passwordConfirm = formData.getFirst("password-confirm");

    if (requireCurrent) {
      if (Validation.isBlank(password)) {
        setReferrerOnPage();
        return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
      }

      UserCredentialModel cred = UserCredentialModel.password(password);
      if (!session.users().validCredentials(realm, user, cred)) {
        setReferrerOnPage();
        return account
            .setError(Messages.INVALID_PASSWORD_EXISTING)
            .createResponse(AccountPages.PASSWORD);
      }
    }

    if (Validation.isEmpty(passwordNew)) {
      setReferrerOnPage();
      return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
    }

    if (!passwordNew.equals(passwordConfirm)) {
      setReferrerOnPage();
      return account
          .setError(Messages.INVALID_PASSWORD_CONFIRM)
          .createResponse(AccountPages.PASSWORD);
    }

    try {
      session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
    } catch (ModelReadOnlyException mre) {
      setReferrerOnPage();
      return account.setError(Messages.READ_ONLY_PASSWORD).createResponse(AccountPages.PASSWORD);
    } catch (ModelException me) {
      logger.error("Failed to update password", me);
      setReferrerOnPage();
      return account
          .setError(me.getMessage(), me.getParameters())
          .createResponse(AccountPages.PASSWORD);
    } catch (Exception ape) {
      logger.error("Failed to update password", ape);
      setReferrerOnPage();
      return account.setError(ape.getMessage()).createResponse(AccountPages.PASSWORD);
    }

    List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user);
    for (UserSessionModel s : sessions) {
      if (!s.getId().equals(auth.getSession().getId())) {
        AuthenticationManager.backchannelLogout(
            session, realm, s, uriInfo, clientConnection, headers, true);
      }
    }

    event.event(EventType.UPDATE_PASSWORD).client(auth.getClient()).user(auth.getUser()).success();

    setReferrerOnPage();
    return account
        .setPasswordSet(true)
        .setSuccess(Messages.ACCOUNT_PASSWORD_UPDATED)
        .createResponse(AccountPages.PASSWORD);
  }
Example #5
0
  /**
   * Update account information.
   *
   * <p>Form params:
   *
   * <p>firstName lastName email
   *
   * @param formData
   * @return
   */
  @Path("/")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response processAccountUpdate(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
      return login(null);
    }

    require(AccountRoles.MANAGE_ACCOUNT);

    String action = formData.getFirst("submitAction");
    if (action != null && action.equals("Cancel")) {
      setReferrerOnPage();
      return account.createResponse(AccountPages.ACCOUNT);
    }

    csrfCheck(formData);

    UserModel user = auth.getUser();

    List<FormMessage> errors = Validation.validateUpdateProfileForm(realm, formData);
    if (errors != null && !errors.isEmpty()) {
      setReferrerOnPage();
      return account
          .setErrors(errors)
          .setProfileFormData(formData)
          .createResponse(AccountPages.ACCOUNT);
    }

    try {
      if (realm.isEditUsernameAllowed()) {
        String username = formData.getFirst("username");

        UserModel existing = session.users().getUserByUsername(username, realm);
        if (existing != null && !existing.getId().equals(user.getId())) {
          throw new ModelDuplicateException(Messages.USERNAME_EXISTS);
        }

        user.setUsername(username);
      }
      user.setFirstName(formData.getFirst("firstName"));
      user.setLastName(formData.getFirst("lastName"));

      String email = formData.getFirst("email");
      String oldEmail = user.getEmail();
      boolean emailChanged = oldEmail != null ? !oldEmail.equals(email) : email != null;
      if (emailChanged) {
        UserModel existing = session.users().getUserByEmail(email, realm);
        if (existing != null && !existing.getId().equals(user.getId())) {
          throw new ModelDuplicateException(Messages.EMAIL_EXISTS);
        }
      }

      user.setEmail(email);

      AttributeFormDataProcessor.process(formData, realm, user);

      event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()).success();

      if (emailChanged) {
        user.setEmailVerified(false);
        event
            .clone()
            .event(EventType.UPDATE_EMAIL)
            .detail(Details.PREVIOUS_EMAIL, oldEmail)
            .detail(Details.UPDATED_EMAIL, email)
            .success();
      }
      setReferrerOnPage();
      return account.setSuccess(Messages.ACCOUNT_UPDATED).createResponse(AccountPages.ACCOUNT);
    } catch (ModelReadOnlyException roe) {
      setReferrerOnPage();
      return account
          .setError(Messages.READ_ONLY_USER)
          .setProfileFormData(formData)
          .createResponse(AccountPages.ACCOUNT);
    } catch (ModelDuplicateException mde) {
      setReferrerOnPage();
      return account
          .setError(mde.getMessage())
          .setProfileFormData(formData)
          .createResponse(AccountPages.ACCOUNT);
    }
  }