Skip to content

Commit

Permalink
tests: Imporve coverage and remove duplicated logic
Browse files Browse the repository at this point in the history
  • Loading branch information
JBWatenbergScality committed Apr 2, 2024
1 parent 01e18f0 commit 863798b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 31 deletions.
22 changes: 7 additions & 15 deletions src/test/java/com/scality/keycloak/GroupWithLinkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@

import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.AccessTokenResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.output.Slf4jLogConsumer;
Expand All @@ -33,19 +30,14 @@ record ProviderAndMapper(String providerID, String mapperID) {
public class GroupWithLinkTest {

private Logger logger = LoggerFactory.getLogger(GroupWithLinkTest.class);

private String getToken(KeycloakContainer keycloak) {
Keycloak keycloakClient = keycloak.getKeycloakAdminClient();
AccessTokenResponse accessTokenResponse = keycloakClient.tokenManager().getAccessToken();
return accessTokenResponse.getToken();
}
private TokenProvider tokenProvider = new TokenProvider();

private ProviderAndMapper createLdapConfigurationAndLdapGroupMapper(KeycloakContainer keycloak) throws IOException {
/// Retrieve Master realm id
URL urlMasterRealm = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master");
HttpURLConnection connMasterRealm = (HttpURLConnection) urlMasterRealm.openConnection();
connMasterRealm.setRequestMethod("GET");
connMasterRealm.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
connMasterRealm.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
int responseCodeMasterRealm = connMasterRealm.getResponseCode();
if (responseCodeMasterRealm != 200) {
System.out.println("Get Master Realm responseCode = " + responseCodeMasterRealm);
Expand All @@ -66,7 +58,7 @@ private ProviderAndMapper createLdapConfigurationAndLdapGroupMapper(KeycloakCont
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/components");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write(
Expand Down Expand Up @@ -179,7 +171,7 @@ private ProviderAndMapper createLdapConfigurationAndLdapGroupMapper(KeycloakCont
url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/components");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write(
Expand Down Expand Up @@ -250,7 +242,7 @@ private void syncLdapGroups(KeycloakContainer keycloak, ProviderAndMapper provid
+ "/mappers/" + providerAndMapper.mapperID() + "/sync?direction=fedToKeycloak");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write("{}".getBytes());
Expand Down Expand Up @@ -278,7 +270,7 @@ private Stream<GroupWithLinkRepresentation> getGroupsWithLink(KeycloakContainer
+ "&search=" + search);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));

int responseCode = conn.getResponseCode();

Expand Down Expand Up @@ -344,7 +336,7 @@ public void groups_with_links_should_be_returned_when_listing_groups()
keycloak.getAuthServerUrl() + "/admin/realms/master/groups");
HttpURLConnection connLocalGroup = (HttpURLConnection) urlLocalGroup.openConnection();
connLocalGroup.setRequestMethod("POST");
connLocalGroup.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
connLocalGroup.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
connLocalGroup.setRequestProperty("Content-Type", "application/json");
connLocalGroup.setDoOutput(true);
connLocalGroup.getOutputStream().write(
Expand Down
31 changes: 31 additions & 0 deletions src/test/java/com/scality/keycloak/TokenProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.scality.keycloak;

import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.AccessTokenResponse;

import dasniko.testcontainers.keycloak.KeycloakContainer;
import jakarta.ws.rs.NotAuthorizedException;

public class TokenProvider {
private int getTokenFailedAttemps = 0;

public String getToken(KeycloakContainer keycloak) {
try {
Keycloak keycloakClient = keycloak.getKeycloakAdminClient();
AccessTokenResponse accessTokenResponse = keycloakClient.tokenManager().getAccessToken();
return accessTokenResponse.getToken();
} catch (NotAuthorizedException e) {
if (this.getTokenFailedAttemps > 3) {
throw e;
}
this.getTokenFailedAttemps++;
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// ignore
}
return getToken(keycloak);
}

}
}
44 changes: 28 additions & 16 deletions src/test/java/com/scality/keycloak/TrustStoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import java.util.List;

import org.junit.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.AccessTokenResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.Container;
Expand All @@ -30,6 +28,7 @@
public class TrustStoreTest {

private Logger logger = LoggerFactory.getLogger(TrustStoreTest.class);
private TokenProvider tokenProvider = new TokenProvider();

@Test
public void truststore_provider_should_be_registered() throws IOException {
Expand All @@ -43,7 +42,7 @@ public void truststore_provider_should_be_registered() throws IOException {
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/certificates");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));

List<CertificateRepresentation> certificates = objectMapper.readValue(conn.getInputStream(),
new TypeReference<>() {
Expand All @@ -53,17 +52,11 @@ public void truststore_provider_should_be_registered() throws IOException {

}

private String getToken(KeycloakContainer keycloak) {
Keycloak keycloakClient = keycloak.getKeycloakAdminClient();
AccessTokenResponse accessTokenResponse = keycloakClient.tokenManager().getAccessToken();
return accessTokenResponse.getToken();
}

private Boolean isLDAPWithStartTlsConnectionWorking(KeycloakContainer keycloak) throws IOException {
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/testLDAPConnection");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write(("{\n" + //
Expand All @@ -89,7 +82,7 @@ private List<CertificateRepresentation> getCertificates(KeycloakContainer keyclo
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/certificates");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
ObjectMapper objectMapper = new ObjectMapper();
List<CertificateRepresentation> certificates = objectMapper.readValue(conn.getInputStream(),
new TypeReference<>() {
Expand All @@ -102,7 +95,7 @@ private HttpURLConnection addCertificateConnection(KeycloakContainer keycloak, S
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/certificates");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write(("{\n" + //
Expand All @@ -118,7 +111,7 @@ private CertificateRepresentation upsertCertificateConnection(KeycloakContainer
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/certificates/" + alias);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("PUT");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.getOutputStream().write(("{\n" + //
Expand All @@ -132,7 +125,7 @@ private void removeCertificateConnection(KeycloakContainer keycloak, String alia
URL url = new URL(keycloak.getAuthServerUrl() + "/admin/realms/master/certificates/" + alias);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("DELETE");
conn.setRequestProperty("Authorization", "Bearer " + getToken(keycloak));
conn.setRequestProperty("Authorization", "Bearer " + tokenProvider.getToken(keycloak));
conn.getResponseCode();
}

Expand Down Expand Up @@ -167,20 +160,39 @@ public void truststore_provider_should_be_taken_in_account_when_setup_ldap()
HttpURLConnection conn = addCertificateConnection(keycloak, alias, base64Ca);
int responseCode = conn.getResponseCode();

// V
// V -- Is the LDAPS connection working once the CA is trusted?
assertTrue(responseCode == 204);
assertTrue(isLDAPWithStartTlsConnectionWorking(keycloak));

// V
// V -- Does list certificate returns the trusted CA ?
List<CertificateRepresentation> certificates = getCertificates(keycloak);

assertFalse(certificates.isEmpty());
assertTrue(certificates.stream().anyMatch(it -> it.alias().equals("ldap.local")));

// E
removeCertificateConnection(keycloak, alias);
// V -- Does list certificate returns the trusted CA ?
List<CertificateRepresentation> certificatesPostDeletion = getCertificates(keycloak);
assertTrue(certificatesPostDeletion.isEmpty());
// E
CertificateRepresentation upsertedCertificate = upsertCertificateConnection(keycloak, alias, base64Ca);
// V -- Does the certificate get created?
assertEquals("docker-light-baseimage", upsertedCertificate.commonName());
List<CertificateRepresentation> certificatesPostUpsert = getCertificates(keycloak);
assertFalse(certificatesPostUpsert.isEmpty());
assertTrue(certificatesPostUpsert.stream().anyMatch(it -> it.alias().equals(alias)));

// E -- Update the certificate
String base64CaUpdated = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdKakNDQkE2Z0F3SUJBZ0lKQVBNS280QVhCSGlhTUEwR0NTcUdTSWIzRFFFQkN3VUFNSHd4Q3pBSkJnTlYKQkFZVEFrUkZNUkl3RUFZRFZRUUlEQWxHY21GdWEyOXVhV0V4RWpBUUJnTlZCQWNNQ1U1MWNtVnRZbVZ5WnpFVApNQkVHQTFVRUNnd0tiWGtnUTI5dGNHRnVlVEVXTUJRR0ExVUVDd3dOYlhrZ1JHVndZWEowYldWdWRERVlNQllHCkExVUVBd3dQVFhrZ2NtOXZkQ0JEUVNBeU1ERTNNQjRYRFRJeU1UQXlNVEUyTkRreE5Gb1hEVE15TVRBeE9ERTIKTkRreE5Gb3dmREVMTUFrR0ExVUVCaE1DUkVVeEVqQVFCZ05WQkFnTUNVWnlZVzVyYjI1cFlURVNNQkFHQTFVRQpCd3dKVG5WeVpXMWlaWEpuTVJNd0VRWURWUVFLREFwdGVTQkRiMjF3WVc1NU1SWXdGQVlEVlFRTERBMXRlU0JFClpYQmhjblJ0Wlc1ME1SZ3dGZ1lEVlFRRERBOU5lU0J5YjI5MElFTkJJREl3TVRjd2dnSWlNQTBHQ1NxR1NJYjMKRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFEeFkrTE9wc2p0OFhiYittY3hJblBsTHN4emY0d09xaDcrYVpFWgpJR01DRzVjN1RMeklmTThIcVpCb1NVNHE1cnFpMzFwK3JrWlFiS1RGWnhBSzB0TzlNSFE0dVdMSFJlNnNLaGFUCmtmbzNRRDBybU51a0JkQ1ZvNkhXR00yY3E1WU1haHBrb0VEMmZHMVFSRjEvSk8wWWdwYVp0dTA1dVowd0dHNW4KWjFIcmxDNUZzczJ0dXRydFc1VmZtbWNNNVNUYVdwRWUwZ0gwVTdHVnNNVzliN1l6UGRQb1FUVGZSa2F2OFpEagpXWktRaFU4Umh4VE9FT2RGMzlwNnJFNzBOQ3RGNlFaNGNPV2lTVWo0eVZ6V0d3UGpuL3Z3ZXZpeFhrZ0w3cWJHClZmTzBTQ1VPZEJpSGMxR1FaVjFTdDdHd3ZtUHdmS1JzcWhTbUs2TUZ5czhBcUFUUDZxNVdMMU9CeU1LRWNud04KWnpjdG03Y2RlOVYyRFpmSU82aDhEdjM4clhxb1VNNHJFWUNKWHVZb1NQYkRSSFVlM0lKQ1VITzJoWDNuYmpKaQpGdWlXM2YvUFFQWHU0NzhxNjdXeGwrK29pWFR5dW5kalMzL3dDM1NVUDgvNzVrQUF6OUh6ZkttdzRvY0tqQnpKCnpJdi92NHI3dnhOTWI2M0dJWjRqbys5V09nazRRMU5UdVRZM0cyclVvYndZTTVxMkZxckU4R2tQSlEvL0xvSmEKK3oyQUE2ZXVxb3RNRTJ1ZHlaR29lZ0FPdTFlZ3dGTUpKUzVYckUrVU02eEZBY0JPbUhIL0RUbzF4L01BNC9Qegp1cDJCb3dpcER6UlEzelptd1U4NTFKemZSbmluMU9pNFBsTTVWK0tiSGE5dCtIVW9RWVRiYStzdE5TcGwyVHNnCnEvYUNRUUlEQVFBQm80R3FNSUduTUIwR0ExVWREZ1FXQkJSbVZWNU5QeWRNY1gyYUs1QWcrVTFWZFJOdm5qQWYKQmdOVkhTTUVHREFXZ0JSbVZWNU5QeWRNY1gyYUs1QWcrVTFWZFJOdm5qQVBCZ05WSFJNQkFmOEVCVEFEQVFILwpNQTRHQTFVZER3RUIvd1FFQXdJQkJqQkVCZ05WSFI4RVBUQTdNRG1nTjZBMWhqTm9kSFJ3T2k4dmVXOTFja1J2CmJXRnBiaTV2Y21jdlkzSnNMMmx1ZEdWeWJXVmthV0YwWldOaExXTmhMV055YkM1d1pXMHdEUVlKS29aSWh2Y04KQVFFTEJRQURnZ0lCQUlpSXdKZ2VRT1V0VE9HVkNwdlN4bTFhVVByYThOdllQSUVlR3ZZSGQ3VzYwajEzcFZIbAp2N3ZOSVRIUjBlazY1bm03VmZYR0U2VjBxcTZ1eU9JcytUSVg4R3hjYkh3Vm1rM2lWZitkNG9wemtjQmxvV3FTCkU4bTVpUWYrZXovUXk3YkRTWVRVMlFjQjBSS2NKR085Ti9uSUpQaVBFY2JFc0t1ekpmNHB5VGRaYTZKdjVRRmcKUGpza1ppdjVRRWNhM3RrVjdiMDlJMXZFb0QxcWs5Tlg4QXc3TFA1ZDlOamNFWmNWZng3d09Dcm9Kc0wwdDZLMwpMZTN5RkI5ek43enFTdkFhdmRIV2VVZUV6MUFIVEJqaS9DVDlBQTJTY3I3UlNCUzFOODRzWTRSUkVoenE3WW44CkRKLzBlNE1kbi9tcDVkQkRyNTg3dWlDdGZzeG1RZS81b1VsYzg5WVVuNlRkNVRnV2ZqRlU1ZmloWWhJZmhtVG4KcFFkNkRYTVNOYkp3VHNya3RaUi9Nd2x4cHorQ2hqY2l1TC9KemZzWS9KTk5oakJiSnd6Wk9JODhHcG1jSHo1ZQpMQ2JTMTl3NStvVjRXOUVYS3VaMGVDMHBlNm50Q0VSYjRPRHh0VytnRG4zZ0JBVGxZczNVYTJNZEZWUTU2U01OCk40ajFRajdUc0JNV2lzTmI3eUNZbndOZm5yZURKcWdtMm8vS2x5SzdzdndpbU45OUpIeGxNNnMwYlRaK3dyOEoKRFBhYlU4TVFFM1Z6bkdqaXlwVFNNQUQvcXZtVytTNUFka0U0RmpJTWdZZkdhQ0I2aHJCQkdXcWE3MENlN3ZITApKdU1lRWVNbSs4S3JFWTVoTWpMYmNHWTY3RXdiVHl0bDc2SFBSM0J5Wm03ZCt1SlJscExVN1ZxVwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==";
CertificateRepresentation updatedCertificate = upsertCertificateConnection(keycloak, alias,
base64CaUpdated);
// V -- Does the certificate get updated?
assertEquals("My root CA 2017", updatedCertificate.commonName());
List<CertificateRepresentation> certificatesPostUpdate = getCertificates(keycloak);
assertTrue(certificatesPostUpdate.stream().anyMatch(it -> it.commonName().equals("My root CA 2017")));
assertFalse(certificatesPostUpdate.stream()
.anyMatch(it -> it.commonName().equals("docker-light-baseimage")));
}
}

Expand Down

0 comments on commit 863798b

Please sign in to comment.