From 19053a5492472bf343429c1611dcf1e34726b4d5 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Tue, 30 Apr 2024 10:15:27 +0200 Subject: [PATCH] Fixing code --- CHANGELOG.md | 4 + pom.xml | 4 +- .../gcube/common/context/ContextUtility.java | 33 ++---- .../java/org/gcube/common/ContextTest.java | 101 ++++++++++++++---- .../common/context/ContextUtilityTest.java | 35 +++++- src/test/resources/logback-test.xml | 2 +- 6 files changed, 124 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a54f70..2a53d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm # Changelog for Common Utility For Smartgears 3.X.X +## [v1.1.0-SNAPSHOT] + +- Added evaluation of SecurityTokenProvider to calculate the context + ## [v1.0.1] - Fixed issue on getCurrentContextFullName diff --git a/pom.xml b/pom.xml index 146b961..f3b091e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,12 @@ maven-parent org.gcube.tools - 1.1.0 + 1.2.0 org.gcube.common common-utility-sg3 - 1.0.1 + 1.1.0-SNAPSHOT Common Utility For Smartgears 3.X.X This library provides utility functions for APIs available in Smartgears 3 but broken in Smartgears 4. diff --git a/src/main/java/org/gcube/common/context/ContextUtility.java b/src/main/java/org/gcube/common/context/ContextUtility.java index 715f6d1..31179b1 100644 --- a/src/main/java/org/gcube/common/context/ContextUtility.java +++ b/src/main/java/org/gcube/common/context/ContextUtility.java @@ -4,9 +4,9 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.Base64; -import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; -import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; +import org.gcube.common.authorization.client.Constants; +import org.gcube.common.authorization.library.AuthorizationEntry; import org.gcube.common.authorization.library.provider.AccessTokenProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.keycloak.model.AccessToken; @@ -27,36 +27,17 @@ public class ContextUtility { String context = ScopeProvider.instance.get(); if(context==null) { logger.trace("ScopeProvider is null. Going to get context from AccessTokenProvider."); - String token = AccessTokenProvider.instance.get(); + String token = SecurityTokenProvider.instance.get(); if(token!=null) { - String realUmaTokenEncoded = token.split("\\.")[1]; - String realUmaToken = new String(Base64.getDecoder().decode(realUmaTokenEncoded.getBytes())); - ObjectMapper mapper = new ObjectMapper(); try { - JsonNode tokenJsonNode = mapper.readTree(realUmaToken); - JsonNode jsonNode = tokenJsonNode.get("aud"); - if(jsonNode.isArray()) { - ArrayNode arrayNode = (ArrayNode) jsonNode; - for (JsonNode aud : arrayNode) { - if (aud != null && aud.isTextual() && aud.asText().compareTo("") != 0) { - String audience = aud.asText(); - String contextToBeValidated = URLDecoder.decode(audience, StandardCharsets.UTF_8.toString()); - ScopeBean scopeBean = new ScopeBean(contextToBeValidated); - context = scopeBean.toString(); - return context; - } - } - } - if(jsonNode.isTextual()) { - return jsonNode.asText(); - } - throw new Exception("Unable to get Current Context"); + AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); + return authorizationEntry.getContext(); }catch (Exception e) { - new RuntimeException(e); + throw new RuntimeException(e); } }else { logger.trace("ScopeProvider AND AccessTokenProvider are null. Going to get context from SecurityTokenProvider."); - token = SecurityTokenProvider.instance.get(); + token = AccessTokenProvider.instance.get(); if(token!=null) { String realUmaTokenEncoded = token.split("\\.")[1]; String realUmaToken = new String(Base64.getDecoder().decode(realUmaTokenEncoded.getBytes())); diff --git a/src/test/java/org/gcube/common/ContextTest.java b/src/test/java/org/gcube/common/ContextTest.java index bca17c4..ff952a4 100644 --- a/src/test/java/org/gcube/common/ContextTest.java +++ b/src/test/java/org/gcube/common/ContextTest.java @@ -13,8 +13,8 @@ import org.gcube.common.authorization.utils.secret.JWTSecret; import org.gcube.common.authorization.utils.secret.Secret; import org.gcube.common.authorization.utils.secret.SecretUtility; import org.gcube.common.keycloak.KeycloakClientFactory; +import org.gcube.common.keycloak.KeycloakClientHelper; import org.gcube.common.keycloak.model.TokenResponse; -import org.gcube.common.scope.api.ScopeProvider; import org.junit.AfterClass; import org.junit.BeforeClass; import org.slf4j.Logger; @@ -23,44 +23,58 @@ import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) */ -@SuppressWarnings("deprecation") public class ContextTest { private static final Logger logger = LoggerFactory.getLogger(ContextTest.class); protected static final String CONFIG_INI_FILENAME = "config.ini"; - public static final String ROOT_DEV; - public static final String ROOT_PREPROD; - public static final String ROOT_PROD; - + public static final String DEFAULT_TEST_SCOPE; + + public static final String GCUBE; +// public static final String DEVNEXT; +// public static final String NEXTNEXT; +// public static final String DEVSEC; +// public static final String DEVVRE; +// +// private static final String ROOT_PROD; +// private static final String ROOT_PRE; + protected static final Properties properties; - protected static final String CLIENT_ID_PROPERTY_KEY = "client_id"; - protected static final String CLIENT_SECRET_PROPERTY_KEY = "client_secret"; - - protected static final String clientID; - protected static final String clientSecret; + public static final String TYPE_PROPERTY_KEY = "type"; + public static final String USERNAME_PROPERTY_KEY = "username"; + public static final String PASSWORD_PROPERTY_KEY = "password"; + public static final String CLIENT_ID_PROPERTY_KEY = "clientId"; static { + GCUBE = "/gcube"; +// DEVNEXT = GCUBE + "/devNext"; +// NEXTNEXT = DEVNEXT + "/NextNext"; +// DEVSEC = GCUBE + "/devsec"; +// DEVVRE = DEVSEC + "/devVRE"; +// +// ROOT_PROD = "/d4science.research-infrastructures.eu"; +// ROOT_PRE = "/pred4s"; + + DEFAULT_TEST_SCOPE = GCUBE; + + properties = new Properties(); InputStream input = ContextTest.class.getClassLoader().getResourceAsStream(CONFIG_INI_FILENAME); try { // load the properties file properties.load(input); - - clientID = properties.getProperty(CLIENT_ID_PROPERTY_KEY); - clientSecret = properties.getProperty(CLIENT_SECRET_PROPERTY_KEY); - } catch (IOException e) { throw new RuntimeException(e); } - ROOT_DEV = "/gcube"; - ROOT_PREPROD = "/pred4s"; - ROOT_PROD = "/d4science.research-infrastructures.eu"; } + private enum Type{ + USER, CLIENT_ID + }; + public static void set(Secret secret) throws Exception { SecretManagerProvider.instance.reset(); SecretManager secretManager = new SecretManager(); @@ -70,15 +84,56 @@ public class ContextTest { } public static void setContextByName(String fullContextName) throws Exception { + logger.debug("Going to set credentials for context {}", fullContextName); Secret secret = getSecretByContextName(fullContextName); set(secret); } private static TokenResponse getJWTAccessToken(String context) throws Exception { - ScopeProvider.instance.set(context); - TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(clientID, clientSecret, context, null); - return tr; + Type type = Type.valueOf(properties.get(TYPE_PROPERTY_KEY).toString()); + + TokenResponse tr = null; + + int index = context.indexOf('/', 1); + String root = context.substring(0, index == -1 ? context.length() : index); + + switch (type) { + case CLIENT_ID: + String clientId = properties.getProperty(CLIENT_ID_PROPERTY_KEY); + String clientSecret = properties.getProperty(root); + + tr = KeycloakClientFactory.newInstance().queryUMAToken(context, clientId, clientSecret, context, null); + break; + + case USER: + default: + String username = properties.getProperty(USERNAME_PROPERTY_KEY); + String password = properties.getProperty(PASSWORD_PROPERTY_KEY); + + switch (root) { + case "/gcube": + default: + clientId = "next.d4science.org"; + break; + + case "/pred4s": + clientId = "pre.d4science.org"; + break; + + case "/d4science.research-infrastructures.eu": + clientId = "services.d4science.org"; + break; + } + clientSecret = null; + + tr = KeycloakClientHelper.getTokenForUser(context, username, password); + break; + + } + + return tr; + } public static Secret getSecretByContextName(String context) throws Exception { @@ -98,7 +153,7 @@ public class ContextTest { } public static String getUser() { - String user = "Unknown"; + String user = "UNKNOWN"; try { user = SecretManagerProvider.instance.get().getUser().getUsername(); } catch(Exception e) { @@ -109,7 +164,7 @@ public class ContextTest { @BeforeClass public static void beforeClass() throws Exception { - setContextByName(ROOT_DEV); + setContextByName(DEFAULT_TEST_SCOPE); } @AfterClass diff --git a/src/test/java/org/gcube/common/context/ContextUtilityTest.java b/src/test/java/org/gcube/common/context/ContextUtilityTest.java index f7d758e..bca5457 100644 --- a/src/test/java/org/gcube/common/context/ContextUtilityTest.java +++ b/src/test/java/org/gcube/common/context/ContextUtilityTest.java @@ -2,22 +2,51 @@ package org.gcube.common.context; import org.gcube.common.ContextTest; import org.gcube.common.authorization.library.provider.AccessTokenProvider; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.utils.manager.SecretManager; import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.junit.Assert; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) */ public class ContextUtilityTest extends ContextTest { + private static final Logger logger = LoggerFactory.getLogger(ContextUtilityTest.class); + @Test public void testGetContext() throws Exception { SecretManager secretManager = SecretManagerProvider.instance.get(); - String token = secretManager.getCurrentSecretHolder().getSecrets().first().getToken(); + String context = secretManager.getContext(); + String newToken = secretManager.getCurrentSecretHolder().getSecrets().first().getToken(); ContextTest.afterClass(); - AccessTokenProvider.instance.set(token); - ContextUtility.getCurrentContextFullName(); + + ScopeProvider.instance.set(context); + String gotContext = ContextUtility.getCurrentContextFullName(); + logger.debug("Expected context is {} - Got Context is {}", context, gotContext); + Assert.assertTrue(context.compareTo(gotContext)==0); + ScopeProvider.instance.reset(); + + + + String oldToken = ContextTest.properties.getProperty("old_token_gcube"); + AccessTokenProvider.instance.set(oldToken); + gotContext = ContextUtility.getCurrentContextFullName(); + logger.debug("Expected context is {} - Got Context is {}", context, gotContext); + Assert.assertTrue(context.compareTo(gotContext)==0); + AccessTokenProvider.instance.reset(); + + + + SecurityTokenProvider.instance.set(newToken); + gotContext = ContextUtility.getCurrentContextFullName(); + logger.debug("Expected context is {} - Got Context is {}", context, gotContext); + Assert.assertTrue(context.compareTo(gotContext)==0); + SecurityTokenProvider.instance.reset(); } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 13f1c6e..8cb2af0 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -10,7 +10,7 @@ - +