8000 is-45364 migrate Client Api V2 tests to utilize adminClient by robson90 · Pull Request #47789 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import jakarta.ws.rs.core.HttpHeaders;

import org.keycloak.admin.api.AdminRootV2;
import org.keycloak.admin.api.client.ClientApi;
import org.keycloak.admin.api.client.ClientsApi;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.testframework.annotations.InjectAdminClient;

Expand All @@ -23,7 +26,39 @@ public String getClientsApiUrl() {
return "http://localhost:8080/admin/api/%s/clients/v2".formatted(getRealmName());
}
public String getClientApiUrl(String clientId) {
return "http://localhost:8080/admin/api/%s/clients/v2/%s".formatted(getRealmName(), clientId);
return getClientApiUrl(getRealmName(), clientId);
}

public String getClientApiUrl(String realmName, String clientId) {
return "http://localhost:8080/admin/api/%s/clients/v2/%s".formatted(realmName, clientId);
}

public ClientsApi getClientsApi() {
return adminClient.proxy(AdminRootV2.class).adminApi(getRealmName()).clientsV2();
}

public ClientsApi getClientsApi(String realmName) {
return getClientsApi(adminClient, realmName);
}

public ClientsApi getClientsApi(Keycloak adminClient) {
return getClientsApi(adminClient, getRealmName());
}

public ClientsApi getClientsApi(Keycloak adminClient, String realmName) {
return adminClient.proxy(AdminRootV2.class).adminApi(realmName).clientsV2();
}

public ClientApi getClientApi(String clientId) {
return getClientApi(getRealmName(), clientId);
}

public ClientApi getClientApi(String realmName, String clientId) {
return getClientApi(adminClient, realmName, clientId);
}

public ClientApi getClientApi(Keycloak adminClient, String realmName, String clientId) {
return adminClient.proxy(AdminRootV2.class).adminApi(realmName).clientsV2().client(clientId);
}

@BeforeAll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,16 @@

package org.keycloak.tests.admin.client.v2;

import java.io.ByteArrayInputStream;
import java.util.List;

import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;

import org.keycloak.admin.api.PatchTypeNames;
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
import org.keycloak.common.Profile;
import org.keycloak.events.admin.OperationType;
import org.keycloak.representations.admin.v2.OIDCClientRepresentation;
import org.keycloak.representations.admin.v2.SAMLClientRepresentation;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.testframework.annotations.InjectHttpClient;
import org.keycloak.testframework.annotations.InjectRealm;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.realm.ManagedRealm;
Expand All @@ -39,13 +35,6 @@
import org.keycloak.testframework.server.KeycloakServerConfig;
import org.keycloak.testframework.server.KeycloakServerConfigBuilder;

import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -61,6 +50,7 @@
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
Expand All @@ -71,30 +61,32 @@
public class AdminEventV2Test extends AbstractClientApiV2Test {
private static final String TEST_CLIENT_ID = "v2-rep-test-client";

@InjectHttpClient
CloseableHttpClient client;

@InjectRealm(attachTo = "master", ref = "master")
ManagedRealm masterRealm;

@InjectRunOnServer
RunOnServerClient runOnServer;

@InjectRealm
ManagedRealm testRealm;

@Override
public String getRealmName() {
return testRealm.getName();
}

@BeforeEach
public void setupAndClearEvents() {
runOnServer.run(session -> {
// enable Admin v2 events on the server
System.setProperty("kc.admin-v2.client-service.events.enabled", "true");
});

// Enable admin events on master realm
RealmEventsConfigRepresentation eventsConfig = masterRealm.admin().getRealmEventsConfig();
// Enable admin events on test realm
RealmEventsConfigRepresentation eventsConfig = testRealm.admin().getRealmEventsConfig();
eventsConfig.setAdminEventsEnabled(true);
eventsConfig.setAdminEventsDetailsEnabled(true);
masterRealm.admin().updateRealmEventsConfig(eventsConfig);
testRealm.admin().updateRealmEventsConfig(eventsConfig);

// Clear any existing events
masterRealm.admin().clearAdminEvents();
testRealm.admin().clearAdminEvents();
}

@AfterEach
Expand All @@ -110,7 +102,7 @@ public void createClientFiresV2Event() throws Exception {
createTestClient();
try {
// Verify v2 events were fired
List<AdminEventRepresentation> events = masterRealm.admin().getAdminEvents();
List<AdminEventRepresentation> events = testRealm.admin().getAdminEvents();

// Should have at least 1 event
assertThat("Should have at least 1 event", events.size(), greaterThanOrEqualTo(1));
Expand All @@ -133,20 +125,13 @@ public void createClientFiresV2Event() throws Exception {
public void updateClientFiresV2Event() throws Exception {
createTestClient();
try {
masterRealm.admin().clearAdminEvents();

HttpPut updateRequest = new HttpPut(getClientsApiUrl() + "/" + TEST_CLIENT_ID);
setAuthHeader(updateRequest);
updateRequest.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);

testRealm.admin().clearAdminEvents();
OIDCClientRepresentation rep = getTestClientRepresentation();
// update the client
rep.setDescription("Updated description");

updateRequest.setEntity(new StringEntity(mapper.writeValueAsString(rep)));

try (var response = client.execute(updateRequest)) {
assertEquals(200, response.getStatusLine().getStatusCode());
try (var response = getClientApi(TEST_CLIENT_ID).createOrUpdateClient(rep)) {
assertEquals(200, response.getStatus());
}

assertUpdateEventFired("Updated description");
Expand All @@ -159,21 +144,12 @@ public void updateClientFiresV2Event() throws Exception {
public void patchClientFiresV2Event() throws Exception {
createTestClient();
try {
masterRealm.admin().clearAdminEvents();

HttpPatch patchRequest = new HttpPatch(getClientsApiUrl() + "/" + TEST_CLIENT_ID);
setAuthHeader(patchRequest);

patchRequest.setHeader(HttpHeaders.CONTENT_TYPE, PatchTypeNames.JSON_MERGE);
testRealm.admin().clearAdminEvents();

OIDCClientRepresentation patch = new OIDCClientRepresentation();
patch.setDescription("Patched description");

patchRequest.setEntity(new StringEntity(mapper.writeValueAsString(patch)));

try (var response = client.execute(patchRequest)) {
assertEquals(200, response.getStatusLine().getStatusCode());
}
assertNotNull(getClientApi(TEST_CLIENT_ID).patchClient(new ByteArrayInputStream(mapper.writeValueAsBytes(patch))));

assertUpdateEventFired("Patched description");
} finally {
Expand All @@ -185,17 +161,14 @@ public void patchClientFiresV2Event() throws Exception {
public void deleteClientFiresV2Event() throws Exception {
createTestClient();
try {
masterRealm.admin().clearAdminEvents();
testRealm.admin().clearAdminEvents();

HttpDelete deleteRequest = new HttpDelete(getClientsApiUrl() + "/" + TEST_CLIENT_ID);
setAuthHeader(deleteRequest);

try (var response = client.execute(deleteRequest)) {
assertEquals(204, response.getStatusLine().getStatusCode());
try (var response = getClientApi(TEST_CLIENT_ID).deleteClient()) {
assertEquals(204, response.getStatus());
}

// Verify v2 DELETE event was fired
List<AdminEventRepresentation> events = masterRealm.admin().getAdminEvents();
List<AdminEventRepresentation> events = testRealm.admin().getAdminEvents();

// Find the v2 event
AdminEventRepresentation v2Event = events.stream()
Expand Down Expand Up @@ -227,21 +200,19 @@ public void deleteClientFiresV2Event() throws Exception {
assertThat(eventRepresentation.getAuth().getSecret(), is(not(testClientRep.getAuth().getSecret())));
assertThat(eventRepresentation.getAuth().getSecret(), is("**********"));

try (var response = client.execute(deleteRequest)) {
assertEquals(404, response.getStatusLine().getStatusCode());
try (var response = getClientApi(TEST_CLIENT_ID).deleteClient()) {
assertEquals(404, response.getStatus());
}
} finally {
HttpDelete deleteRequest = new HttpDelete(getClientsApiUrl() + "/" + TEST_CLIENT_ID);
setAuthHeader(deleteRequest);
try (var response = client.execute(deleteRequest)) {
assertThat(response.getStatusLine().getStatusCode(), anyOf(is(204), is(404)));
try (var response = getClientApi(TEST_CLIENT_ID).deleteClient()) {
assertThat(response.getStatus(), anyOf(is(204), is(404)));
}
}
}

private void assertUpdateEventFired(String newDescription){
// Verify v2 UPDATE event was fired
List<AdminEventRepresentation> events = masterRealm.admin().getAdminEvents();
List<AdminEventRepresentation> events = testRealm.admin().getAdminEvents();

// Find the v2 event (has apiVersion=v2 in details)
AdminEventRepresentation v2Event = events.stream()
Expand All @@ -264,7 +235,7 @@ public void v2EventContainsV2Representation() throws Exception {
createTestClient();
try {
// Verify v2 event contains the v2 representation format
List<AdminEventRepresentation> events = masterRealm.admin().getAdminEvents();
List<AdminEventRepresentation> events = testRealm.admin().getAdminEvents();

// Find the v2 event
AdminEventRepresentation v2Event = events.stream()
Expand Down Expand Up @@ -292,10 +263,6 @@ public void v2EventContainsV2Representation() throws Exception {
public void stripSamlSigningCertificateFromRepresentation() throws Exception {
var SAML_CLIENT_ID = "saml-with-certificate";

HttpPost request = new HttpPost(getClientsApiUrl());
setAuthHeader(request);
request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);

SAMLClientRepresentation samlRep = new SAMLClientRepresentation();
samlRep.setEnabled(true);
samlRep.setClientId(SAML_CLIENT_ID);
Expand All @@ -311,15 +278,13 @@ public void stripSamlSigningCertificateFromRepresentation() throws Exception {
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL+...
-----END CERTIFICATE-----
""");
request.setEntity(new StringEntity(mapper.writeValueAsString(samlRep)));

try (var response = client.execute(request)) {
EntityUtils.consumeQuietly(response.getEntity());
assertEquals(201, response.getStatusLine().getStatusCode());
try (var response = getClientsApi().createClient(samlRep)) {
assertEquals(201, response.getStatus());
}

try {
List<AdminEventRepresentation> events = masterRealm.admin().getAdminEvents();
List<AdminEventRepresentation> events = testRealm.admin().getAdminEvents();

// Find the v2 event
AdminEventRepresentation v2Event = events.stream()
Expand All @@ -339,15 +304,8 @@ public void stripSamlSigningCertificateFromRepresentation() throws Exception {

private void createTestClient() throws Exception {
// Create a client via v2 API (representation details already enabled in @BeforeEach)
HttpPost request = new HttpPost(getClientsApiUrl());
setAuthHeader(request);
request.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);

request.setEntity(new StringEntity(mapper.writeValueAsString(getTestClientRepresentation())));

try (var response = client.execute(request)) {
EntityUtils.consumeQuietly(response.getEntity());
assertEquals(201, response.getStatusLine().getStatusCode());
try (var response = getClientsApi().createClient(getTestClientRepresentation())) {
assertEquals(201, response.getStatus());
}
}

Expand All @@ -356,10 +314,8 @@ private void deleteTestClient() throws Exception {
}

private void deleteClient(String clientId) throws Exception {
HttpDelete deleteRequest = new HttpDelete(getClientsApiUrl() + "/" + clientId);
setAuthHeader(deleteRequest);
try (var response = client.execute(deleteRequest)) {
assertEquals(204, response.getStatusLine().getStatusCode());
try (var response = getClientApi(clientId).deleteClient()) {
assertEquals(204, response.getStatus());
}
}

Expand Down
Loading
Loading
0