diff --git a/src/main/java/org/gcube/common/keycloak/KeycloakClientHelper.java b/src/main/java/org/gcube/common/keycloak/KeycloakClientHelper.java new file mode 100644 index 0000000..af6bce4 --- /dev/null +++ b/src/main/java/org/gcube/common/keycloak/KeycloakClientHelper.java @@ -0,0 +1,48 @@ +package org.gcube.common.keycloak; + +import org.gcube.common.keycloak.model.AccessToken; +import org.gcube.common.keycloak.model.RefreshToken; +import org.gcube.common.keycloak.model.TokenResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KeycloakClientHelper { + + protected static Logger logger = LoggerFactory.getLogger(KeycloakClientHelper.class); + + /** + * The public GW used to obtain the token, is not declared final since it can be changed if necessary at runtime + */ + private static String GATEWAY_CLIENT_ID = "d4science-internal-gateway"; + + /** + * Sets the new default GW clientId used for all the queries to the Keycloak server. + * Note: The operation will logged as WARN to be visible. + * @param gatewayClientId the new GW clientId + */ + public static void setDefaultGWClientID(String gatewayClientId) { + logger.warn("The default GW clientId will be changed to: {}", gatewayClientId); + GATEWAY_CLIENT_ID = gatewayClientId; + } + + /** + * Gets a new {@link TokenResponse}, containing the {@link AccessToken} and the {@link RefreshToken} from the Keycloak server in the environment of the context represented by the context parameter. + * The context parameter is also used as audience for the token. + * + * @param context the context ot be used for discovery and for audience + * @param username the user's username + * @param password the user's password + * @return the token response from the Keycloak server + * @throws KeycloakClientException if an error occurs during the process + */ + public static TokenResponse getTokenForUser(String context, String username, String password) throws KeycloakClientException { + logger.debug("Getting new token for user '{}' in context '{}'", username, context); + logger.trace("Getting OIDC token for user '{}' using configured default GW clientId '{}'", username, GATEWAY_CLIENT_ID); + TokenResponse oidcTR = KeycloakClientFactory.newInstance().queryOIDCTokenOfUser(context, GATEWAY_CLIENT_ID, + "", username, password); + + logger.trace("Getting UMA token in the '{}' context", context); + return KeycloakClientFactory.newInstance().queryUMAToken(context, oidcTR, context, null); + } + +} diff --git a/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java b/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java index d4969e3..ccd39a1 100644 --- a/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java +++ b/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java @@ -47,7 +47,7 @@ public class TestKeycloakClient { @Test public void test00TokenEndpointConstruction() throws Exception { - logger.info("*** [0.0] Start testing Keycloak token endpoint construction from base URL..."); + logger.info("*** [0.0] Start testing Keycloak token endpoint construction from base URL computed from context..."); KeycloakClient client = KeycloakClientFactory.newInstance(); tokenURL = client.getTokenEndpointURL(client.getRealmBaseURL(DEV_ROOT_CONTEXT)); Assert.assertNotNull(tokenURL); @@ -69,7 +69,7 @@ public class TestKeycloakClient { @Test public void test02IntrospectEndpointCompute() throws Exception { - logger.info("*** [0.2] Start testing Keycloak userinfo endpoint computed from provided URL..."); + logger.info("*** [0.2] Start testing Keycloak userinfo endpoint computed from provided URL string..."); KeycloakClient client = KeycloakClientFactory.newInstance(); URL url = client .computeIntrospectionEndpointURL(client.getTokenEndpointURL(client.getRealmBaseURL(DEV_ROOT_CONTEXT))); @@ -83,7 +83,7 @@ public class TestKeycloakClient { @Test public void test12QueryOIDCToken() throws Exception { - logger.info("*** [1.2] Start testing query OIDC token from Keycloak with URL..."); + logger.info("*** [1.2] Start testing query OIDC token from Keycloak with context..."); oidcTR = KeycloakClientFactory.newInstance().queryOIDCToken(DEV_ROOT_CONTEXT, CLIENT_ID, CLIENT_SECRET); @@ -107,7 +107,7 @@ public class TestKeycloakClient { @Test public void test13QueryOIDCTokenOfUser() throws Exception { - logger.info("*** [1.3] Start testing query OIDC token from Keycloak with URL for user..."); + logger.info("*** [1.3] Start testing query OIDC token from Keycloak with context for user..."); oidcTR = KeycloakClientFactory.newInstance().queryOIDCTokenOfUser(DEV_ROOT_CONTEXT, CLIENT_ID, CLIENT_SECRET, TEST_USER_USERNAME, TEST_USER_PASSWORD); @@ -119,19 +119,39 @@ public class TestKeycloakClient { @Test public void test13aQueryOIDCTokenOfUserWithContext() throws Exception { - logger.info("*** [1.3] Start testing query OIDC token from Keycloak with URL for user..."); + logger.info("*** [1.3a] Start testing query OIDC token for audience from Keycloak with context for user..."); oidcTR = KeycloakClientFactory.newInstance().queryOIDCTokenOfUserWithContext(DEV_ROOT_CONTEXT, CLIENT_ID, CLIENT_SECRET, TEST_USER_USERNAME, TEST_USER_PASSWORD, TEST_AUDIENCE); - logger.info("*** [1.3] OIDC access token: {}", oidcTR.getAccessToken()); - logger.info("*** [1.3] OIDC refresh token: {}", oidcTR.getRefreshToken()); + logger.info("*** [1.3a] OIDC access token: {}", oidcTR.getAccessToken()); + logger.info("*** [1.3a] OIDC refresh token: {}", oidcTR.getRefreshToken()); TestModels.checkTokenResponse(oidcTR); TestModels.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcTR), TEST_USER_USERNAME, true); } + + @Test + public void test13bQueryOIDCTokenAndUMAOfUser() throws Exception { + logger.info("*** [1.3b] Start testing query OIDC and UMA tokens from Keycloak with context for user..."); + oidcTR = KeycloakClientFactory.newInstance().queryOIDCTokenOfUser(DEV_ROOT_CONTEXT, CLIENT_ID, + CLIENT_SECRET, TEST_USER_USERNAME, TEST_USER_PASSWORD); + + logger.info("*** [1.3b] OIDC access token: {}", oidcTR.getAccessToken()); + logger.info("*** [1.3b] OIDC refresh token: {}", oidcTR.getRefreshToken()); + TestModels.checkTokenResponse(oidcTR); + TestModels.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcTR), TEST_USER_USERNAME, false); + + umaTR = KeycloakClientFactory.newInstance().queryUMAToken(DEV_ROOT_CONTEXT, oidcTR, TEST_AUDIENCE, null); + + logger.info("*** [1.3b] UMA access token: {}", umaTR.getAccessToken()); + logger.info("*** [1.3b] UMA refresh token: {}", umaTR.getRefreshToken()); + + TestModels.checkTokenResponse(umaTR); + TestModels.checkAccessToken(ModelUtils.getAccessTokenFrom(umaTR), TEST_USER_USERNAME, true); + } @Test public void test24QueryUMAToken() throws Exception { - logger.info("*** [2.4] Start testing query UMA token from Keycloak with URL..."); + logger.info("*** [2.4] Start testing query UMA token from Keycloak with context..."); umaTR = KeycloakClientFactory.newInstance().queryUMAToken(DEV_ROOT_CONTEXT, CLIENT_ID, CLIENT_SECRET, TEST_AUDIENCE, null); @@ -144,7 +164,7 @@ public class TestKeycloakClient { @Test public void test24aQueryUMAToken() throws Exception { - logger.info("*** [2.4a] Start testing query UMA token from Keycloak with URL..."); + logger.info("*** [2.4a] Start testing query UMA token from Keycloak with context..."); umaTR = KeycloakClientFactory.newInstance().queryUMAToken(tokenURL, CLIENT_ID, CLIENT_SECRET, TEST_AUDIENCE, null); @@ -246,4 +266,16 @@ public class TestKeycloakClient { Assert.assertFalse(KeycloakClientFactory.newInstance().isAccessTokenVerified( introspectionURL, CLIENT_ID, CLIENT_SECRET, OLD_UMA_ACCESS_TOKEN)); } + + @Test + public void test4GetTokenOfUser() throws Exception { + logger.info("*** [4] Start testing query token from Keycloak for user..."); + TokenResponse tokenResponse = KeycloakClientHelper.getTokenForUser(DEV_ROOT_CONTEXT, TEST_USER_USERNAME, TEST_USER_PASSWORD); + + logger.info("*** [4] UMA access token: {}", tokenResponse.getAccessToken()); + logger.info("*** [4] UMA refresh token: {}", tokenResponse.getRefreshToken()); + + TestModels.checkTokenResponse(tokenResponse); + TestModels.checkAccessToken(ModelUtils.getAccessTokenFrom(tokenResponse), TEST_USER_USERNAME, true); + } }