mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-16 20:15:46 -06:00
[admin-api-v2] SPIs for Admin APIs v2 (#41943)
Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
package org.keycloak.admin.api;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface AdminApiFactory extends ProviderFactory<AdminApi> {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.admin.api;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class AdminApiSpi implements Spi {
|
||||
public static final String PROVIDER_ID = "admin-api-root";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return AdminApi.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory<AdminApi>> getProviderFactoryClass() {
|
||||
return AdminApiFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,12 @@ package org.keycloak.admin.api;
|
||||
import jakarta.ws.rs.OPTIONS;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.services.resources.admin.AdminCorsPreflightService;
|
||||
|
||||
@jakarta.ws.rs.ext.Provider
|
||||
@Provider
|
||||
@Path("admin/api")
|
||||
public class AdminRootV2 {
|
||||
|
||||
@@ -17,12 +18,12 @@ public class AdminRootV2 {
|
||||
@Path("")
|
||||
public AdminApi latestAdminApi() {
|
||||
// we could return the latest Admin API if no version is specified
|
||||
return new DefaultAdminApi(session);
|
||||
return session.getProvider(AdminApi.class);
|
||||
}
|
||||
|
||||
@Path("v2")
|
||||
public AdminApi adminApi() {
|
||||
return new DefaultAdminApi(session);
|
||||
return session.getProvider(AdminApi.class);
|
||||
}
|
||||
|
||||
@Path("{any:.*}")
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.keycloak.admin.api;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultAdminApiFactory implements AdminApiFactory {
|
||||
public static final String PROVIDER_ID = "default";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminApi create(KeycloakSession session) {
|
||||
return new DefaultAdminApi(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,20 @@ import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.PATCH;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.keycloak.admin.api.FieldValidation;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.representations.admin.v2.ClientRepresentation;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
public interface ClientApi {
|
||||
public interface ClientApi extends Provider {
|
||||
|
||||
// TODO move these
|
||||
public static final String CONENT_TYPE_MERGE_PATCH = "application/merge-patch+json";
|
||||
String CONTENT_TYPE_MERGE_PATCH = "application/merge-patch+json";
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@@ -31,7 +31,7 @@ public interface ClientApi {
|
||||
@QueryParam("fieldValidation") FieldValidation fieldValidation);
|
||||
|
||||
@PATCH
|
||||
@Consumes({MediaType.APPLICATION_JSON_PATCH_JSON, CONENT_TYPE_MERGE_PATCH})
|
||||
@Consumes({MediaType.APPLICATION_JSON_PATCH_JSON, CONTENT_TYPE_MERGE_PATCH})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
ClientRepresentation patchClient(JsonNode patch, @QueryParam("fieldValidation") FieldValidation fieldValidation);
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface ClientApiFactory extends ProviderFactory<ClientApi> {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class ClientApiSpi implements Spi {
|
||||
public static final String NAME = "admin-api-client";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return ClientApi.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory<ClientApi>> getProviderFactoryClass() {
|
||||
return ClientApiFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface ClientsApiFactory extends ProviderFactory<ClientsApi> {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class ClientsApiSpi implements Spi {
|
||||
public static final String NAME = "admin-api-clients";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return ClientsApi.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory<ClientsApi>> getProviderFactoryClass() {
|
||||
return ClientsApiFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.keycloak.admin.api.FieldValidation;
|
||||
import org.keycloak.http.HttpResponse;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.admin.v2.ClientRepresentation;
|
||||
@@ -27,21 +29,21 @@ import jakarta.ws.rs.core.Response;
|
||||
public class DefaultClientApi implements ClientApi {
|
||||
private final KeycloakSession session;
|
||||
private final RealmModel realm;
|
||||
private final String clientId;
|
||||
private final ClientModel client;
|
||||
private final ClientService clientService;
|
||||
private HttpResponse response;
|
||||
|
||||
public DefaultClientApi(KeycloakSession session, String clientId) {
|
||||
public DefaultClientApi(KeycloakSession session) {
|
||||
this.session = session;
|
||||
this.clientId = clientId;
|
||||
this.realm = session.getContext().getRealm();
|
||||
this.realm = Objects.requireNonNull(session.getContext().getRealm());
|
||||
this.client = Objects.requireNonNull(session.getContext().getClient());
|
||||
this.clientService = session.services().clients();
|
||||
this.response = session.getContext().getHttpResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientRepresentation getClient() {
|
||||
return clientService.getClient(realm, clientId, null)
|
||||
return clientService.getClient(realm, client.getClientId(), null)
|
||||
.orElseThrow(() -> new NotFoundException("Cannot find the specified client"));
|
||||
}
|
||||
|
||||
@@ -96,4 +98,9 @@ public class DefaultClientApi implements ClientApi {
|
||||
throw ErrorResponse.error("Unknown Error Occurred", Response.Status.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultClientApiFactory implements ClientApiFactory {
|
||||
public static final String PROVIDER_ID = "default";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientApi create(KeycloakSession session) {
|
||||
return new DefaultClientApi(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.groups.ConvertGroup;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import org.keycloak.admin.api.FieldValidation;
|
||||
import org.keycloak.http.HttpResponse;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
@@ -24,9 +27,9 @@ public class DefaultClientsApi implements ClientsApi {
|
||||
private final HttpResponse response;
|
||||
private final ClientService clientService;
|
||||
|
||||
public DefaultClientsApi(KeycloakSession session, RealmModel realm) {
|
||||
public DefaultClientsApi(KeycloakSession session) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.realm = Objects.requireNonNull(session.getContext().getRealm());
|
||||
this.clientService = session.services().clients();
|
||||
this.response = session.getContext().getHttpResponse();
|
||||
}
|
||||
@@ -50,7 +53,9 @@ public class DefaultClientsApi implements ClientsApi {
|
||||
|
||||
@Override
|
||||
public ClientApi client(@PathParam("id") String clientId) {
|
||||
return new DefaultClientApi(session, clientId);
|
||||
var client = Optional.ofNullable(session.clients().getClientByClientId(realm, clientId)).orElseThrow(() -> new NotFoundException("Client cannot be found"));
|
||||
session.getContext().setClient(client);
|
||||
return session.getProvider(ClientApi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.keycloak.admin.api.client;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultClientsApiFactory implements ClientsApiFactory {
|
||||
public static final String PROVIDER_ID = "default";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientsApi create(KeycloakSession session) {
|
||||
return new DefaultClientsApi(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,27 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.keycloak.admin.api.client.ClientsApi;
|
||||
import org.keycloak.admin.api.client.DefaultClientsApi;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Objects;
|
||||
|
||||
public class DefaultRealmApi implements RealmApi {
|
||||
private final KeycloakSession session;
|
||||
private final RealmModel realm;
|
||||
|
||||
public DefaultRealmApi(KeycloakSession session, String name) {
|
||||
public DefaultRealmApi(KeycloakSession session) {
|
||||
this.session = session;
|
||||
this.realm = Optional.ofNullable(session.realms().getRealmByName(name)).orElseThrow(() -> new NotFoundException("Realm cannot be found"));
|
||||
session.getContext().setRealm(realm);
|
||||
this.realm = Objects.requireNonNull(session.getContext().getRealm());
|
||||
}
|
||||
|
||||
@Path("clients")
|
||||
@Override
|
||||
public ClientsApi clients() {
|
||||
return new DefaultClientsApi(session, realm);
|
||||
return session.getProvider(ClientsApi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultRealmApiFactory implements RealmApiFactory {
|
||||
public static final String PROVIDER_ID = "default";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmApi create(KeycloakSession session) {
|
||||
return new DefaultRealmApi(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class DefaultRealmsApi implements RealmsApi {
|
||||
private final KeycloakSession session;
|
||||
|
||||
@@ -14,7 +17,9 @@ public class DefaultRealmsApi implements RealmsApi {
|
||||
@Path("{name}")
|
||||
@Override
|
||||
public RealmApi realm(@PathParam("name") String name) {
|
||||
return new DefaultRealmApi(session, name);
|
||||
var realm = Optional.ofNullable(session.realms().getRealmByName(name)).orElseThrow(() -> new NotFoundException("Realm cannot be found"));
|
||||
session.getContext().setRealm(realm);
|
||||
return session.getProvider(RealmApi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultRealmsApiFactory implements RealmsApiFactory {
|
||||
public static final String PROVIDER_ID = "default";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmsApi create(KeycloakSession session) {
|
||||
return new DefaultRealmsApi(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@ package org.keycloak.admin.api.realm;
|
||||
|
||||
import jakarta.ws.rs.Path;
|
||||
import org.keycloak.admin.api.client.ClientsApi;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
public interface RealmApi {
|
||||
public interface RealmApi extends Provider {
|
||||
|
||||
@Path("clients")
|
||||
ClientsApi clients();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface RealmApiFactory extends ProviderFactory<RealmApi> {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class RealmApiSpi implements Spi {
|
||||
public static final String NAME = "admin-api-realm";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return RealmApi.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory<RealmApi>> getProviderFactoryClass() {
|
||||
return RealmApiFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface RealmsApiFactory extends ProviderFactory<RealmsApi> {
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.keycloak.admin.api.realm;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class RealmsApiSpi implements Spi {
|
||||
public static final String NAME = "admin-api-realms";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return RealmsApi.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory<RealmsApi>> getProviderFactoryClass() {
|
||||
return RealmsApiFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.admin.api.DefaultAdminApiFactory
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.admin.api.client.DefaultClientApiFactory
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.admin.api.client.DefaultClientsApiFactory
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.admin.api.realm.DefaultRealmApiFactory
|
||||
@@ -0,0 +1 @@
|
||||
org.keycloak.admin.api.realm.DefaultRealmsApiFactory
|
||||
@@ -0,0 +1,5 @@
|
||||
org.keycloak.admin.api.AdminApiSpi
|
||||
org.keycloak.admin.api.realm.RealmsApiSpi
|
||||
org.keycloak.admin.api.realm.RealmApiSpi
|
||||
org.keycloak.admin.api.client.ClientsApiSpi
|
||||
org.keycloak.admin.api.client.ClientApiSpi
|
||||
@@ -1,13 +1,7 @@
|
||||
package org.keycloak.services.client;
|
||||
|
||||
import jakarta.enterprise.inject.spi.CDI;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Validation;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.ValidatorFactory;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.hibernate.validator.HibernateValidator;
|
||||
import org.hibernate.validator.HibernateValidatorFactory;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
@@ -16,7 +10,6 @@ import org.keycloak.models.mapper.ModelMapper;
|
||||
import org.keycloak.representations.admin.v2.ClientRepresentation;
|
||||
import org.keycloak.representations.admin.v2.validation.CreateClient;
|
||||
import org.keycloak.services.ServiceException;
|
||||
import org.keycloak.validation.jakarta.HibernateValidatorProvider;
|
||||
import org.keycloak.validation.jakarta.JakartaValidatorProvider;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -20,26 +20,18 @@ package org.keycloak.tests.admin;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.api.client.ClientApi;
|
||||
import org.keycloak.representations.admin.v2.ClientRepresentation;
|
||||
import org.keycloak.testframework.annotations.InjectHttpClient;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@KeycloakIntegrationTest()
|
||||
@@ -49,7 +41,7 @@ public class AdminV2Test {
|
||||
private static ObjectMapper mapper;
|
||||
|
||||
@InjectHttpClient
|
||||
private HttpClient client;
|
||||
CloseableHttpClient client;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupMapper() {
|
||||
@@ -59,10 +51,11 @@ public class AdminV2Test {
|
||||
@Test
|
||||
public void getClient() throws Exception {
|
||||
HttpGet request = new HttpGet(HOSTNAME_LOCAL_ADMIN + "/realms/master/clients/account");
|
||||
HttpResponse response = client.execute(request);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("account", client.getClientId());
|
||||
try (var response = client.execute(request)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("account", client.getClientId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -70,56 +63,39 @@ public class AdminV2Test {
|
||||
HttpPatch request = new HttpPatch(HOSTNAME_LOCAL_ADMIN + "/realms/master/clients/account");
|
||||
request.setEntity(new StringEntity("not json"));
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON);
|
||||
HttpResponse response = client.execute(request);
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
try (var response = client.execute(request)) {
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
request.setEntity(new StringEntity(
|
||||
"""
|
||||
[{"op": "add", "path": "/description", "value": "I'm a description"}]
|
||||
"""));
|
||||
|
||||
response = client.execute(request);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
try (var response = client.execute(request)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("I'm a description", client.getDescription());
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("I'm a description", client.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void jsonMergePatchClient() throws Exception {
|
||||
HttpPatch request = new HttpPatch(HOSTNAME_LOCAL_ADMIN + "/realms/master/clients/account");
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, ClientApi.CONENT_TYPE_MERGE_PATCH);
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, ClientApi.CONTENT_TYPE_MERGE_PATCH);
|
||||
|
||||
ClientRepresentation patch = new ClientRepresentation();
|
||||
patch.setDescription("I'm also a description");
|
||||
|
||||
request.setEntity(new StringEntity(mapper.writeValueAsString(patch)));
|
||||
|
||||
HttpResponse response = client.execute(request);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
try (var response = client.execute(request)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("I'm also a description", client.getDescription());
|
||||
ClientRepresentation client = mapper.createParser(response.getEntity().getContent()).readValueAs(ClientRepresentation.class);
|
||||
assertEquals("I'm also a description", client.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRepresentationValidation() throws Exception {
|
||||
HttpPost request = new HttpPost(HOSTNAME_LOCAL_ADMIN + "/realms/master/clients");
|
||||
request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
|
||||
|
||||
request.setEntity(new StringEntity("""
|
||||
{
|
||||
"displayName": "something",
|
||||
"appUrl": "notUrl"
|
||||
}
|
||||
"""));
|
||||
|
||||
var response = client.execute(request);
|
||||
assertThat(response, notNullValue());
|
||||
System.err.println(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8));
|
||||
assertThat(response.getStatusLine().getStatusCode(), is(400));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user