@Path("email-verification")
  @GET
  public Response emailVerification(
      @QueryParam("code") String code, @QueryParam("key") String key) {
    event.event(EventType.VERIFY_EMAIL);
    if (key != null) {
      Checks checks = new Checks();
      if (!checks.verifyCode(key, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
        return checks.response;
      }
      ClientSessionCode accessCode = checks.clientCode;
      ClientSessionModel clientSession = accessCode.getClientSession();
      UserSessionModel userSession = clientSession.getUserSession();
      UserModel user = userSession.getUser();
      initEvent(clientSession);
      user.setEmailVerified(true);

      user.removeRequiredAction(RequiredAction.VERIFY_EMAIL);

      event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();

      String actionCookieValue = getActionCookie();
      if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
        session.sessions().removeClientSession(realm, clientSession);
        return session
            .getProvider(LoginFormsProvider.class)
            .setSuccess(Messages.EMAIL_VERIFIED)
            .createInfoPage();
      }

      event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);

      return AuthenticationManager.nextActionAfterAuthentication(
          session, userSession, clientSession, clientConnection, request, uriInfo, event);
    } else {
      Checks checks = new Checks();
      if (!checks.verifyCode(code, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
        return checks.response;
      }
      ClientSessionCode accessCode = checks.clientCode;
      ClientSessionModel clientSession = accessCode.getClientSession();
      UserSessionModel userSession = clientSession.getUserSession();
      initEvent(clientSession);

      createActionCookie(realm, uriInfo, clientConnection, userSession.getId());

      return session
          .getProvider(LoginFormsProvider.class)
          .setClientSessionCode(accessCode.getCode())
          .setUser(userSession.getUser())
          .createResponse(RequiredAction.VERIFY_EMAIL);
    }
  }
  /**
   * Send a update account email to the user
   *
   * <p>An email contains a link the user can click to perform a set of required actions. The
   * redirectUri and clientId parameters are optional. The default for the redirect is the account
   * client.
   *
   * @param id User is
   * @param redirectUri Redirect uri
   * @param clientId Client id
   * @param actions required actions the user needs to complete
   * @return
   */
  @Path("{id}/execute-actions-email")
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response executeActionsEmail(
      @PathParam("id") String id,
      @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri,
      @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId,
      List<String> actions) {
    auth.requireManage();

    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
    }

    if (user.getEmail() == null) {
      return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
    }

    ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId);
    for (String action : actions) {
      clientSession.addRequiredAction(action);
    }
    ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
    accessCode.setAction(ClientSessionModel.Action.EXECUTE_ACTIONS.name());

    try {
      UriBuilder builder = Urls.executeActionsBuilder(uriInfo.getBaseUri());
      builder.queryParam("key", accessCode.getCode());

      String link = builder.build(realm.getName()).toString();
      long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());

      this.session
          .getProvider(EmailTemplateProvider.class)
          .setRealm(realm)
          .setUser(user)
          .sendExecuteActions(link, expiration);

      // audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID,
      // accessCode.getCodeId()).success();

      adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();

      return Response.ok().build();
    } catch (EmailException e) {
      logger.failedToSendActionsEmail(e);
      return ErrorResponse.error(
          "Failed to send execute actions email", Response.Status.INTERNAL_SERVER_ERROR);
    }
  }
  @Override
  public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) {
    ClientSessionModel clientSession = accessCode.getClientSession();
    setupResponseTypeAndMode(clientSession);

    String redirect = clientSession.getRedirectUri();
    OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode);
    String state = clientSession.getNote(OIDCLoginProtocol.STATE_PARAM);
    logger.debugv("redirectAccessCode: state: {0}", state);
    if (state != null) redirectUri.addParam(OAuth2Constants.STATE, state);

    // Standard or hybrid flow
    if (responseType.hasResponseType(OIDCResponseType.CODE)) {
      accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN.name());
      redirectUri.addParam(OAuth2Constants.CODE, accessCode.getCode());
    }

    // Implicit or hybrid flow
    if (responseType.isImplicitOrHybridFlow()) {
      TokenManager tokenManager = new TokenManager();
      AccessTokenResponse res =
          tokenManager
              .responseBuilder(
                  realm, clientSession.getClient(), event, session, userSession, clientSession)
              .generateAccessToken()
              .generateIDToken()
              .build();

      if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) {
        redirectUri.addParam("id_token", res.getIdToken());
      }

      if (responseType.hasResponseType(OIDCResponseType.TOKEN)) {
        redirectUri.addParam("access_token", res.getToken());
        redirectUri.addParam("token_type", res.getTokenType());
        redirectUri.addParam("session-state", res.getSessionState());
        redirectUri.addParam("expires_in", String.valueOf(res.getExpiresIn()));
      }

      redirectUri.addParam("not-before-policy", String.valueOf(res.getNotBeforePolicy()));
    }

    return redirectUri.build();
  }
Beispiel #4
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();
    }
  }