From d574e3c797e5083452d336f43821f80226535eea Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Thu, 1 Sep 2022 14:08:36 +0200 Subject: [PATCH] Porting plugin to use new IAM credentials --- pom.xml | 7 +- .../AccountingDashboardHarvesterPlugin.java | 27 ++--- .../utils/ContextAuthorization.java | 99 +++++++++++-------- .../org/gcube/dataharvest/utils/Utils.java | 17 +++- .../AccountingDataHarvesterJupyterTest.java | 2 +- .../AccountingDataHarvesterPluginTest.java | 31 +++--- .../AccountingDataHarvesterRStudioTest.java | 2 +- .../gcube/dataharvest/utils/ContextTest.java | 83 ++++++++-------- 8 files changed, 152 insertions(+), 116 deletions(-) diff --git a/pom.xml b/pom.xml index 73f331a..f6c5833 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ org.gcube.distribution gcube-bom - 2.1.0-SNAPSHOT + 2.0.2 pom import @@ -120,6 +120,11 @@ 20171018 compile + + org.gcube.common + authorization-utils + [2.0.0, 3.0.0-SNAPSHOT) + diff --git a/src/main/java/org/gcube/dataharvest/AccountingDashboardHarvesterPlugin.java b/src/main/java/org/gcube/dataharvest/AccountingDashboardHarvesterPlugin.java index fb916b1..ff1d075 100644 --- a/src/main/java/org/gcube/dataharvest/AccountingDashboardHarvesterPlugin.java +++ b/src/main/java/org/gcube/dataharvest/AccountingDashboardHarvesterPlugin.java @@ -18,6 +18,7 @@ import org.gcube.accounting.accounting.summary.access.model.internal.Dimension; import org.gcube.accounting.accounting.summary.access.model.update.AccountingRecord; import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.authorization.utils.secret.Secret; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.dataharvest.harvester.CatalogueAccessesHarvester; @@ -214,12 +215,12 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { Properties properties = getConfigParameters(); getProperties().set(properties); - ContextAuthorization contextAuthorization = new ContextAuthorization(); + ContextAuthorization contextAuthorization = new ContextAuthorization(properties); SortedSet contexts = contextAuthorization.getContexts(); String root = contexts.first(); - Utils.setContext(contextAuthorization.getTokenForContext(root)); + Utils.setContext(contextAuthorization.getSecretForContext(root)); AccountingDao dao = AccountingDao.get(); @@ -240,16 +241,16 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { ArrayList accountingRecords = new ArrayList(); - String initialToken = SecurityTokenProvider.instance.get(); - VREAccessesHarvester vreAccessesHarvester = null; JupyterAccessesHarvester jupyterAccessesHarvester = null; RStudioAccessesHarvester rstudioAccessesHarvester = null; + Secret rootSecret = null; for (String context : contexts) { // Setting the token for the context - Utils.setContext(contextAuthorization.getTokenForContext(context)); + Secret secret = contextAuthorization.getSecretForContext(context); + Utils.setContext(secret); ScopeBean scopeBean = new ScopeBean(context); @@ -263,6 +264,8 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { if (scopeBean.is(Type.INFRASTRUCTURE)) { try { + rootSecret = secret; + CatalogueAccessesHarvester catalogueHarvester = new CatalogueAccessesHarvester(start, end); List harvested = catalogueHarvester.getAccountingRecords(); accountingRecords.addAll(harvested); @@ -291,12 +294,12 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { } // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(parent.toString())); + Utils.setContext(contextAuthorization.getSecretForContext(parent.toString())); vreAccessesHarvester = new VREAccessesHarvester(start, end); // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(context)); + Utils.setContext(contextAuthorization.getSecretForContext(context)); } } @@ -315,12 +318,12 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { } // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(parent.toString())); + Utils.setContext(contextAuthorization.getSecretForContext(parent.toString())); rstudioAccessesHarvester = new RStudioAccessesHarvester(start, end); // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(context)); + Utils.setContext(contextAuthorization.getSecretForContext(context)); } } @@ -339,12 +342,12 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { } // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(parent.toString())); + Utils.setContext(contextAuthorization.getSecretForContext(parent.toString())); jupyterAccessesHarvester = new JupyterAccessesHarvester(start, end); // Setting back token for the context - Utils.setContext(contextAuthorization.getTokenForContext(context)); + Utils.setContext(contextAuthorization.getSecretForContext(context)); } } @@ -508,7 +511,7 @@ public class AccountingDashboardHarvesterPlugin extends Plugin { } } - Utils.setContext(initialToken); + Utils.setContext(rootSecret); logger.debug("Harvest Measures from {} to {} are {}", DateUtils.format(start), DateUtils.format(end), accountingRecords); diff --git a/src/main/java/org/gcube/dataharvest/utils/ContextAuthorization.java b/src/main/java/org/gcube/dataharvest/utils/ContextAuthorization.java index ff25c00..bf1a1e3 100644 --- a/src/main/java/org/gcube/dataharvest/utils/ContextAuthorization.java +++ b/src/main/java/org/gcube/dataharvest/utils/ContextAuthorization.java @@ -1,8 +1,5 @@ package org.gcube.dataharvest.utils; -import static org.gcube.common.authorization.client.Constants.authorizationService; - -import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -10,8 +7,13 @@ import java.util.Properties; import java.util.SortedSet; import java.util.TreeSet; -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.authorization.library.provider.UserInfo; +import javax.ws.rs.InternalServerErrorException; + +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.authorization.utils.secret.JWTSecret; +import org.gcube.common.authorization.utils.secret.Secret; +import org.gcube.common.keycloak.KeycloakClientFactory; +import org.gcube.common.keycloak.model.TokenResponse; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.dataharvest.AccountingDashboardHarvesterPlugin; import org.gcube.resourcemanagement.support.server.managers.context.ContextManager; @@ -31,82 +33,99 @@ public class ContextAuthorization { public static final String SERVICE_NAME = "SERVICE_NAME"; public static final String DEFAULT_SERVICE_NAME = "accounting-harvester"; + public static final String CLIENT_ID = "accounting-dashboard-harvester-se-plugin"; + + protected String clientSecret; + /** * Contains Context full name as key and Token as Value */ - protected Map contextToToken; + protected Map contextToToken; /** * Contains Token as key and Context full name as Value */ - protected Map tokenToContext; + protected Map tokenToContext; + + protected Properties properties; + + /** + * Contains Properties used to generate tokens + */ + public ContextAuthorization(Properties properties) throws Exception { + this.properties = properties; + this.contextToToken = new HashMap<>(); + this.tokenToContext = new HashMap<>(); + retrieveContextsAndTokens(); + + } /** * Contains Properties used to generate tokens */ public ContextAuthorization() throws Exception { + this.properties = AccountingDashboardHarvesterPlugin.getProperties().get(); this.contextToToken = new HashMap<>(); this.tokenToContext = new HashMap<>(); retrieveContextsAndTokens(); } - public String generateTokenForContext(String context, Properties properties) throws Exception { - if(properties==null) { - properties = AccountingDashboardHarvesterPlugin.getProperties().get(); + private String getClientSecret(String context) { + try { + if(clientSecret==null) { + int index = context.indexOf('/', 1); + String root = context.substring(0, index == -1 ? context.length() : index); + clientSecret = properties.getProperty(root); + } + return clientSecret; + } catch(Exception e) { + throw new InternalServerErrorException( + "Unable to retrieve Application Token for context " + SecretManagerProvider.instance.get().getContext(), e); } - logger.info("Going to generate Token for Context {}", context); - UserInfo userInfo = new UserInfo(properties.getProperty(USERNAME, DEFAULT_USERNAME), - new ArrayList<>()); - String userToken = authorizationService().generateUserToken(userInfo, context); - SecurityTokenProvider.instance.set(userToken); - String generatedToken = authorizationService() - .generateExternalServiceToken(properties.getProperty(SERVICE_NAME, DEFAULT_SERVICE_NAME)); - - logger.trace("Token for Context {} is {}", context, generatedToken); - - return generatedToken; - + } + + private TokenResponse getJWTAccessToken(String context) throws Exception { + TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(CLIENT_ID, getClientSecret(context), context, null); + return tr; + } + + public Secret getCatalogueSecretForContext(String context) throws Exception { + TokenResponse tr = getJWTAccessToken(context); + Secret secret = new JWTSecret(tr.getAccessToken()); + return secret; } protected void retrieveContextsAndTokens() throws Exception { - - String initialToken = SecurityTokenProvider.instance.get(); - try { - Properties properties = AccountingDashboardHarvesterPlugin.getProperties().get(); - LinkedHashMap map = ContextManager.readContexts(); + for(String scope : map.keySet()) { try { String context = map.get(scope).toString(); - String generatedToken = generateTokenForContext(context, properties); + Secret secret = getCatalogueSecretForContext(context); - contextToToken.put(context, generatedToken); - tokenToContext.put(generatedToken, context); + contextToToken.put(context, secret); + tokenToContext.put(secret, context); } catch(Exception e) { logger.error("Error while elaborating {}", scope, e); throw e; - } finally { - SecurityTokenProvider.instance.reset(); - } + } } } catch(Exception ex) { throw ex; - } finally { - SecurityTokenProvider.instance.set(initialToken); - } + } } - public String getTokenForContext(String contextFullName) { - return contextToToken.get(contextFullName); + public Secret getSecretForContext(String context) { + return contextToToken.get(context); } - public String getContextFromToken(String token) { - return tokenToContext.get(token); + public String getContextFromSecret(Secret secret) { + return tokenToContext.get(secret); } public SortedSet getContexts() { diff --git a/src/main/java/org/gcube/dataharvest/utils/Utils.java b/src/main/java/org/gcube/dataharvest/utils/Utils.java index 84b2548..f62e3a2 100644 --- a/src/main/java/org/gcube/dataharvest/utils/Utils.java +++ b/src/main/java/org/gcube/dataharvest/utils/Utils.java @@ -11,6 +11,9 @@ import org.gcube.common.authorization.client.Constants; import org.gcube.common.authorization.client.exceptions.ObjectNotFound; import org.gcube.common.authorization.library.AuthorizationEntry; 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.authorization.utils.secret.Secret; import org.gcube.common.scope.api.ScopeProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,9 +53,17 @@ public class Utils { return context; } - public static void setContext(String token) throws ObjectNotFound, Exception { - SecurityTokenProvider.instance.set(token); - ScopeProvider.instance.set(getCurrentContext(token)); + public static void setContext(Secret secret) throws Exception { + SecretManagerProvider.instance.reset(); + SecretManager secretManager = new SecretManager(); + SecretManagerProvider.instance.set(secretManager); + secretManager.addSecret(secret); + secretManager.set(); } +// public static void setContext(String token) throws ObjectNotFound, Exception { +// SecurityTokenProvider.instance.set(token); +// ScopeProvider.instance.set(getCurrentContext(token)); +// } + } diff --git a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterJupyterTest.java b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterJupyterTest.java index 136b47b..989e301 100644 --- a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterJupyterTest.java +++ b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterJupyterTest.java @@ -101,7 +101,7 @@ public class AccountingDataHarvesterJupyterTest extends ContextTest { JupyterAccessesHarvester jupyterAccessesHarvester = new JupyterAccessesHarvester(start, end); for(String context : contexts) { - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); diff --git a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterPluginTest.java b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterPluginTest.java index ac60a69..c63db26 100644 --- a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterPluginTest.java +++ b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterPluginTest.java @@ -248,7 +248,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { for (String context : contexts) { // Setting the token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); @@ -266,12 +266,12 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { } // Setting back token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(parent.toString())); + ContextTest.set(contextAuthorization.getSecretForContext(parent.toString())); vreAccessesHarvester = new VREAccessesHarvester(start, end); // Setting back token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); } } @@ -446,7 +446,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { for (String context : contexts) { // Setting the token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); @@ -464,12 +464,12 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { } // Setting back token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(parent.toString())); + ContextTest.set(contextAuthorization.getSecretForContext(parent.toString())); vreAccessesHarvester = new VREAccessesHarvester(start, end); // Setting back token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); } } @@ -530,7 +530,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { for (String context : contexts) { // Setting the token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); try { // Collecting info on social (posts, replies and likes) logger.info("Going to harvest Social Interactions for {}", context); @@ -563,9 +563,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { ContextTest.setContextByName(ROOT); ContextAuthorization contextAuthorization = new ContextAuthorization(); - String stockAssessmentToken = contextAuthorization.generateTokenForContext(STOCK_ASSESMENT_VRE, null); - - ContextTest.setContext(stockAssessmentToken); + ContextTest.set(contextAuthorization.getSecretForContext(STOCK_ASSESMENT_VRE)); AggregationType measureType = AggregationType.MONTHLY; @@ -614,7 +612,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { for (String context : contexts) { // Setting the token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); @@ -666,9 +664,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { protected void setContextByNameAndScopeDescriptor(String contextFullName) throws ObjectNotFound, Exception { ContextAuthorization contextAuthorization = new ContextAuthorization(); - String tagMeToken = contextAuthorization.getTokenForContext(contextFullName); - - ContextTest.setContext(tagMeToken); + ContextTest.set(contextAuthorization.getSecretForContext(contextFullName)); ScopeBean scopeBean = new ScopeBean(contextFullName); ScopeDescriptor actualScopeDescriptor = AccountingDashboardHarvesterPlugin.scopeDescriptors.get() @@ -732,8 +728,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { // AccountingDao dao = AccountingDao.get(); ContextAuthorization contextAuthorization = new ContextAuthorization(); - ContextTest.setContext(contextAuthorization - .getTokenForContext("/d4science.research-infrastructures.eu/SoBigData/SportsDataScience")); + ContextTest.set(contextAuthorization.getSecretForContext("/d4science.research-infrastructures.eu/SoBigData/SportsDataScience")); AggregationType measureType = AggregationType.MONTHLY; @@ -921,7 +916,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { if (context.startsWith(TAGME_VRE)) { continue; } - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); DataMethodDownloadHarvester dataMethodDownloadHarvester = new DataMethodDownloadHarvester(start, end, contexts); List data = dataMethodDownloadHarvester.getAccountingRecords(); @@ -975,7 +970,7 @@ public class AccountingDataHarvesterPluginTest extends ContextTest { String context = E_LEARNING_AREA_VRE; // Setting the token for the context - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); ScopeDescriptor scopeDescriptor = new ScopeDescriptor(scopeBean.name(), context); diff --git a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterRStudioTest.java b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterRStudioTest.java index 33ff7a9..e8e1b7f 100644 --- a/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterRStudioTest.java +++ b/src/test/java/org/gcube/dataharvest/AccountingDataHarvesterRStudioTest.java @@ -105,7 +105,7 @@ public class AccountingDataHarvesterRStudioTest extends ContextTest { RStudioAccessesHarvester rstudioAccessesHarvester = new RStudioAccessesHarvester(start, end); for(String context : contexts) { - ContextTest.setContext(contextAuthorization.getTokenForContext(context)); + ContextTest.set(contextAuthorization.getSecretForContext(context)); ScopeBean scopeBean = new ScopeBean(context); diff --git a/src/test/java/org/gcube/dataharvest/utils/ContextTest.java b/src/test/java/org/gcube/dataharvest/utils/ContextTest.java index 9105bab..a90a77f 100644 --- a/src/test/java/org/gcube/dataharvest/utils/ContextTest.java +++ b/src/test/java/org/gcube/dataharvest/utils/ContextTest.java @@ -7,29 +7,24 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import org.gcube.common.authorization.client.Constants; -import org.gcube.common.authorization.client.exceptions.ObjectNotFound; -import org.gcube.common.authorization.library.AuthorizationEntry; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; -import org.gcube.common.authorization.library.provider.ClientInfo; -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.authorization.library.utils.Caller; -import org.gcube.common.scope.api.ScopeProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.authorization.utils.secret.Secret; +import org.gcube.common.authorization.utils.secret.SecretUtility; +import org.junit.AfterClass; +import org.junit.BeforeClass; /** * @author Luca Frosini (ISTI - CNR) - * */ public class ContextTest { - private static final Logger logger = LoggerFactory.getLogger(ContextTest.class); - protected static Properties properties; protected static final String PROPERTIES_FILENAME = "token.properties"; - public static final String DEFAULT_TEST_SCOPE_NAME; + public static final String ROOT; + public static final String VO; + public static final String VRE; static { properties = new Properties(); @@ -42,45 +37,53 @@ public class ContextTest { throw new RuntimeException(e); } - //DEFAULT_TEST_SCOPE_NAME = "/pred4s/preprod/preVRE"; - - DEFAULT_TEST_SCOPE_NAME = "/d4science.research-infrastructures.eu"; + // DEFAULT_TEST_SCOPE_NAME = "/pred4s/preprod/preVRE"; + // DEFAULT_TEST_SCOPE_NAME = "/gcube/devsec/devVRE"; + + ROOT = "/gcube"; + VO = ROOT + "/devsec"; + VRE = VO + "/devVRE"; + // VO = ROOT + "/devNext"; + // VRE = VO + "/NextNext"; + } - public static String getCurrentScope(String token) throws ObjectNotFound, Exception { - AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); - String context = authorizationEntry.getContext(); - logger.info("Context of token {} is {}", token, context); - return context; + public static void set(Secret secret) throws Exception { + SecretManagerProvider.instance.reset(); + SecretManager secretManager = new SecretManager(); + SecretManagerProvider.instance.set(secretManager); + secretManager.addSecret(secret); + secretManager.set(); } - public static void setContextByName(String fullContextName) throws ObjectNotFound, Exception { + public static void setContext(String token) throws Exception { + Secret secret = getSecret(token); + set(secret); + } + + public static void setContextByName(String fullContextName) throws Exception { + Secret secret = getSecretByContextName(fullContextName); + set(secret); + } + + private static Secret getSecret(String token) throws Exception { + Secret secret = SecretUtility.getSecretByTokenString(token); + return secret; + } + + private static Secret getSecretByContextName(String fullContextName) throws Exception { String token = ContextTest.properties.getProperty(fullContextName); - setContext(token); + return getSecret(token); } - public static void setContext(String token) throws ObjectNotFound, Exception { - SecurityTokenProvider.instance.set(token); - AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token); - ClientInfo clientInfo = authorizationEntry.getClientInfo(); - logger.debug("User : {} - Type : {}", clientInfo.getId(), clientInfo.getType().name()); - String qualifier = authorizationEntry.getQualifier(); - Caller caller = new Caller(clientInfo, qualifier); - AuthorizationProvider.instance.set(caller); - ScopeProvider.instance.set(getCurrentScope(token)); - } - - /* @BeforeClass public static void beforeClass() throws Exception { - setContextByName(DEFAULT_TEST_SCOPE_NAME); + setContextByName(VRE); } @AfterClass public static void afterClass() throws Exception { - SecurityTokenProvider.instance.reset(); - ScopeProvider.instance.reset(); + SecretManagerProvider.instance.reset(); } - */ }