/**
   * Create a new authentication flow
   *
   * @param flow Authentication flow representation
   * @return
   */
  @Path("/flows")
  @POST
  @NoCache
  @Consumes(MediaType.APPLICATION_JSON)
  public Response createFlow(AuthenticationFlowRepresentation flow) {
    auth.requireManage();

    if (flow.getAlias() == null || flow.getAlias().isEmpty()) {
      return ErrorResponse.exists("Failed to create flow with empty alias name");
    }

    if (realm.getFlowByAlias(flow.getAlias()) != null) {
      return ErrorResponse.exists("Flow " + flow.getAlias() + " already exists");
    }

    AuthenticationFlowModel createdModel =
        realm.addAuthenticationFlow(RepresentationToModel.toModel(flow));

    flow.setId(createdModel.getId());
    adminEvent
        .operation(OperationType.CREATE)
        .resourcePath(uriInfo, createdModel.getId())
        .representation(flow)
        .success();
    return Response.status(201).build();
  }
Esempio n. 2
0
  /**
   * Set up a temporary password for the user
   *
   * <p>User will have to reset the temporary password next time they log in.
   *
   * @param id User id
   * @param pass A Temporary password
   */
  @Path("{id}/reset-password")
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public void resetPassword(@PathParam("id") String id, CredentialRepresentation pass) {
    auth.requireManage();

    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      throw new NotFoundException("User not found");
    }
    if (pass == null
        || pass.getValue() == null
        || !CredentialRepresentation.PASSWORD.equals(pass.getType())) {
      throw new BadRequestException("No password provided");
    }

    UserCredentialModel cred = RepresentationToModel.convertCredential(pass);
    try {
      session.users().updateCredential(realm, user, cred);
    } catch (IllegalStateException ise) {
      throw new BadRequestException("Resetting to N old passwords is not allowed.");
    } catch (ModelReadOnlyException mre) {
      throw new BadRequestException("Can't reset password as account is read only");
    }
    if (pass.isTemporary() != null && pass.isTemporary())
      user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);

    adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
  }
  /**
   * Update the top-level information of the realm
   *
   * <p>Any user, roles or client information in the representation will be ignored. This will only
   * update top-level attributes of the realm.
   *
   * @param rep
   * @return
   */
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response updateRealm(final RealmRepresentation rep) {
    auth.requireManage();

    logger.debug("updating realm: " + realm.getName());

    if (Config.getAdminRealm().equals(realm.getName())
        && (rep.getRealm() != null && !rep.getRealm().equals(Config.getAdminRealm()))) {
      return ErrorResponse.error("Can't rename master realm", Status.BAD_REQUEST);
    }

    try {
      if (!Constants.GENERATE.equals(rep.getPublicKey())
          && (rep.getPrivateKey() != null && rep.getPublicKey() != null)) {
        try {
          KeyPairVerifier.verify(rep.getPrivateKey(), rep.getPublicKey());
        } catch (VerificationException e) {
          return ErrorResponse.error(e.getMessage(), Status.BAD_REQUEST);
        }
      }

      if (!Constants.GENERATE.equals(rep.getPublicKey()) && (rep.getCertificate() != null)) {
        try {
          X509Certificate cert = PemUtils.decodeCertificate(rep.getCertificate());
          if (cert == null) {
            return ErrorResponse.error("Failed to decode certificate", Status.BAD_REQUEST);
          }
        } catch (Exception e) {
          return ErrorResponse.error("Failed to decode certificate", Status.BAD_REQUEST);
        }
      }

      RepresentationToModel.updateRealm(rep, realm, session);

      // Refresh periodic sync tasks for configured federationProviders
      List<UserStorageProviderModel> federationProviders = realm.getUserStorageProviders();
      UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
      for (final UserStorageProviderModel fedProvider : federationProviders) {
        usersSyncManager.notifyToRefreshPeriodicSync(session, realm, fedProvider, false);
      }

      adminEvent
          .operation(OperationType.UPDATE)
          .representation(StripSecretsUtils.strip(rep))
          .success();
      return Response.noContent().build();
    } catch (PatternSyntaxException e) {
      return ErrorResponse.error(
          "Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST);
    } catch (ModelDuplicateException e) {
      return ErrorResponse.exists("Realm with same name exists");
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      return ErrorResponse.error("Failed to update realm", Response.Status.INTERNAL_SERVER_ERROR);
    }
  }
  /**
   * Create new authenticator configuration
   *
   * @param rep JSON describing new authenticator configuration
   * @deprecated Use {@link #newExecutionConfig(String, AuthenticatorConfigRepresentation)} instead
   */
  @Path("config")
  @POST
  @NoCache
  public Response createAuthenticatorConfig(AuthenticatorConfigRepresentation rep) {
    auth.requireManage();

    AuthenticatorConfigModel config =
        realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
    adminEvent
        .operation(OperationType.CREATE)
        .resourcePath(uriInfo, config.getId())
        .representation(rep)
        .success();
    return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
  }
  /**
   * Update the top-level information of the realm
   *
   * <p>Any user, roles or client information in the representation will be ignored. This will only
   * update top-level attributes of the realm.
   *
   * @param rep
   * @return
   */
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response updateRealm(final RealmRepresentation rep) {
    auth.requireManage();

    logger.debug("updating realm: " + realm.getName());
    try {
      RepresentationToModel.updateRealm(rep, realm);
      if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) {
        CacheRealmProvider cacheRealmProvider = (CacheRealmProvider) session.realms();
        cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled());
      }
      if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) {
        CacheUserProvider cache = (CacheUserProvider) session.userStorage();
        cache.setEnabled(rep.isUserCacheEnabled());
      }

      // Refresh periodic sync tasks for configured federationProviders
      List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
      UsersSyncManager usersSyncManager = new UsersSyncManager();
      for (final UserFederationProviderModel fedProvider : federationProviders) {
        usersSyncManager.refreshPeriodicSyncForProvider(
            session.getKeycloakSessionFactory(),
            session.getProvider(TimerProvider.class),
            fedProvider,
            realm.getId());
      }

      adminEvent.operation(OperationType.UPDATE).representation(rep).success();
      return Response.noContent().build();
    } catch (PatternSyntaxException e) {
      return ErrorResponse.error(
          "Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST);
    } catch (ModelDuplicateException e) {
      throw e;
    } catch (Exception e) {
      logger.error(e);
      return ErrorResponse.error(
          "Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR);
    }
  }
Esempio n. 6
0
  public void updateClientFromRep(
      ClientRepresentation rep, ClientModel client, KeycloakSession session)
      throws ModelDuplicateException {
    if (TRUE.equals(rep.isServiceAccountsEnabled()) && !client.isServiceAccountsEnabled()) {
      new ClientManager(new RealmManager(session)).enableServiceAccount(client);
    }

    if (!rep.getClientId().equals(client.getClientId())) {
      new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId());
    }

    RepresentationToModel.updateClient(rep, client);

    if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
      if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
        authorization().enable();
      } else {
        authorization().disable();
      }
    }
  }
  /**
   * Update execution with new configuration
   *
   * @param execution Execution id
   * @param json JSON with new configuration
   * @return
   */
  @Path("/executions/{executionId}/config")
  @POST
  @NoCache
  @Consumes(MediaType.APPLICATION_JSON)
  public Response newExecutionConfig(
      @PathParam("executionId") String execution, AuthenticatorConfigRepresentation json) {
    auth.requireManage();

    AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
    if (model == null) {
      session.getTransaction().setRollbackOnly();
      throw new NotFoundException("Illegal execution");
    }
    AuthenticatorConfigModel config = RepresentationToModel.toModel(json);
    config = realm.addAuthenticatorConfig(config);
    model.setAuthenticatorConfig(config.getId());
    realm.updateAuthenticatorExecution(model);

    json.setId(config.getId());
    adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(json).success();
    return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
  }
  /**
   * Add new authentication execution
   *
   * @param execution JSON model describing authentication execution
   */
  @Path("/executions")
  @POST
  @NoCache
  @Consumes(MediaType.APPLICATION_JSON)
  public Response addExecution(AuthenticationExecutionRepresentation execution) {
    auth.requireManage();

    AuthenticationExecutionModel model = RepresentationToModel.toModel(realm, execution);
    AuthenticationFlowModel parentFlow = getParentFlow(model);
    if (parentFlow.isBuiltIn()) {
      throw new BadRequestException("It is illegal to add execution to a built in flow");
    }
    model.setPriority(getNextPriority(parentFlow));
    model = realm.addAuthenticatorExecution(model);

    adminEvent
        .operation(OperationType.CREATE)
        .resourcePath(uriInfo, model.getId())
        .representation(execution)
        .success();
    return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
  }
Esempio n. 9
0
  /**
   * Should not be called from an import. This really expects that the client is created from the
   * admin console.
   *
   * @param session
   * @param realm
   * @param rep
   * @param addDefaultRoles
   * @return
   */
  public static ClientModel createClient(
      KeycloakSession session,
      RealmModel realm,
      ClientRepresentation rep,
      boolean addDefaultRoles) {
    ClientModel client = RepresentationToModel.createClient(session, realm, rep, addDefaultRoles);

    if (rep.getProtocol() != null) {
      LoginProtocolFactory providerFactory =
          (LoginProtocolFactory)
              session
                  .getKeycloakSessionFactory()
                  .getProviderFactory(LoginProtocol.class, rep.getProtocol());
      providerFactory.setupClientDefaults(rep, client);
    }

    // remove default mappers if there is a template
    if (rep.getProtocolMappers() == null && rep.getClientTemplate() != null) {
      Set<ProtocolMapperModel> mappers = client.getProtocolMappers();
      for (ProtocolMapperModel mapper : mappers) client.removeProtocolMapper(mapper);
    }
    return client;
  }