From 91caeb280baa0464ce555c7ca2505771294ffaeb Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Tue, 5 Apr 2022 18:20:49 +0200 Subject: [PATCH 1/5] Added the support to new JWT token via URI Resolver [#23107] --- CHANGELOG.md | 5 + pom.xml | 16 ++-- .../is/InformationSystemUtils.java | 67 +++++++++++++ .../synchserver/mapping/TokenManager.java | 93 ++++++++++++++++--- .../synchserver/mapping/TokenManagerTest.java | 26 ++++++ 5 files changed, 185 insertions(+), 22 deletions(-) create mode 100644 src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/is/InformationSystemUtils.java create mode 100644 src/test/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManagerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f2570..9021c91 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog for "dataminer" +## [v1.9.0-SNAPSHOT] - 2022-04-05 + +- Support new JWT token via URI Resolver [#23107] + + ## [v1.8.1] - 2022-03-21 - Update wps service to support not writing of the computation status to the user's workspace [#23054] diff --git a/pom.xml b/pom.xml index e39eaf4..ca80aec 100755 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - 4.0.0 @@ -9,10 +10,10 @@ org.gcube.dataanalysis dataminer - 1.8.1 + 1.9.0-SNAPSHOT dataminer An e-Infrastructure service providing state-of-the art DataMining algorithms and ecological modelling approaches under the Web Processing Service (WPS) standard. - + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git @@ -39,14 +40,14 @@ - + ${project.build.directory}/${project.build.finalName} distro UTF-8 UTF-8 - + @@ -145,6 +146,7 @@ + junit junit diff --git a/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/is/InformationSystemUtils.java b/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/is/InformationSystemUtils.java new file mode 100644 index 0000000..d1d9904 --- /dev/null +++ b/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/is/InformationSystemUtils.java @@ -0,0 +1,67 @@ +package org.gcube.dataanalysis.wps.statisticalmanager.synchserver.is; + +import java.util.List; + +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Runtime; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.resources.discovery.icclient.ICFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InformationSystemUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(InformationSystemUtils.class); + private static final String URI_RESOLVER_SERVICE_CATEGORY = "Service"; + private static final String URI_RESOLVER_SERVICE_NAME = "HTTP-URI-Resolver"; + + public static String retrieveUriResolverOat(String scope) throws Exception { + try { + LOGGER.info("Retrieve URI Resolver Oat Service Info"); + + if (scope == null || scope.length() == 0) { + String error="Invalid request scope: " + scope; + LOGGER.error(error); + throw new Exception(error); + } + + ScopeProvider.instance.set(scope); + + SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Category/text() eq '" + URI_RESOLVER_SERVICE_CATEGORY + "'") + .addCondition("$resource/Profile/Name/text() eq '" + URI_RESOLVER_SERVICE_NAME + "'") + .setResult("$resource/Profile/RunTime"); + DiscoveryClient client = ICFactory.clientFor(Runtime.class); + + List runtimeList = client.submit(query); + String serviceAddress = null; + if (runtimeList != null && !runtimeList.isEmpty()) { + for (int i = 0; i < runtimeList.size(); i++) { + Runtime accessPoint = runtimeList.get(i); + if (accessPoint != null) { + StringBuilder sb=new StringBuilder(); + sb.append("https://"); + sb.append(accessPoint.hostedOn()); + sb.append("/oat/get"); + serviceAddress=sb.toString(); + break; + } + } + } else { + String error="RuntimeList error: "+runtimeList; + LOGGER.error(error); + throw new Exception(error); + } + + LOGGER.info("Uri Resolver Oat Service Info: " + serviceAddress); + return serviceAddress; + + } catch (Throwable e) { + LOGGER.error("Error in discovery Uri Resolver Oat Service Endpoint in scope: " + scope); + LOGGER.error(e.getLocalizedMessage(),e); + throw e; + } + } +} diff --git a/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManager.java b/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManager.java index 8896f5f..c7b9c8a 100755 --- a/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManager.java +++ b/src/main/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManager.java @@ -2,59 +2,122 @@ package org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mapping; import static org.gcube.common.authorization.client.Constants.authorizationService; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import javax.ws.rs.core.Response; + import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.AccessTokenProvider; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.dataanalysis.wps.statisticalmanager.synchserver.is.InformationSystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TokenManager { - private static final Logger LOGGER= LoggerFactory.getLogger(TokenManager.class); + private static final Logger LOGGER = LoggerFactory.getLogger(TokenManager.class); String username; String scope; String token; String tokenQualifier; - - public String getScope(){ + + public String getScope() { return scope; } - public String getUserName(){ + public String getUserName() { return username; } - public String getToken(){ + public String getToken() { return token; } - + public String getTokenQualifier() { return tokenQualifier; } public void getCredentials() { - try{ - LOGGER.debug("Retrieving token credentials"); - //get username from SmartGears + try { + LOGGER.info("Retrieving token credentials"); + // get username from SmartGears username = AuthorizationProvider.instance.get().getClient().getId(); token = SecurityTokenProvider.instance.get(); + if (token == null || token.isEmpty()) { + String jwtToken = AccessTokenProvider.instance.get(); + scope = ScopeProvider.instance.get(); + token = getGcubeTokenFromUriResolver(jwtToken, scope); + } AuthorizationEntry entry = authorizationService().get(token); scope = entry.getContext(); tokenQualifier = entry.getQualifier(); - - }catch(Exception e){ - LOGGER.error("Error Retrieving token credentials ",e); + } catch (Exception e) { + LOGGER.error("Error Retrieving token credentials: "+e.getLocalizedMessage(),e); scope = null; - username= null; + username = null; } - if ((scope==null || username==null) && ConfigurationManager.isSimulationMode()){ + if ((scope == null || username == null) && ConfigurationManager.isSimulationMode()) { scope = ConfigurationManager.defaultScope; username = ConfigurationManager.defaultUsername; } - LOGGER.debug("Retrieved scope: {} Username: {} Token {} SIMULATION MODE: {} ",scope, username, token, ConfigurationManager.isSimulationMode()); + LOGGER.info("Retrieved scope: {} Username: {} Token {} SIMULATION MODE: {} ", scope, username, token, + ConfigurationManager.isSimulationMode()); } + public String getGcubeTokenFromUriResolver(String jwtToken, String scope) throws Exception { + String gcubeToken = null; + String uriResolverOatURL = InformationSystemUtils.retrieveUriResolverOat(scope); + try { + LOGGER.info("Create Request: "+ uriResolverOatURL); + URL urlObj = new URL(uriResolverOatURL); + HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Authorization", "Bearer " + jwtToken); + connection.setDoOutput(true); + try (AutoCloseable conc = () -> connection.disconnect()) { + int responseCode = connection.getResponseCode(); + LOGGER.info("Response Code: " + responseCode); + + if (Response.Status.fromStatusCode(responseCode).compareTo(Response.Status.OK) == 0) { + try (InputStream ins = connection.getInputStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(ins))) { + String inputLine = null; + while ((inputLine = in.readLine()) != null) { + break; + } + gcubeToken = inputLine; + } + } else { + String error = "Invalid Response Code retrieving GCube Token from Uri Resolver: " + responseCode; + LOGGER.error(error); + try (InputStream ins = connection.getErrorStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(ins))) { + String inputLine = null; + while ((inputLine = in.readLine()) != null) { + LOGGER.error(inputLine); + } + } + throw new Exception(error); + } + } + + } catch (IOException e) { + LOGGER.error("Error retrieving GcubeToken from Uri Resolver: "+e.getLocalizedMessage()); + e.printStackTrace(); + throw e; + } + LOGGER.info("Retrieved GcubeToken: "+gcubeToken); + return gcubeToken; + } + } diff --git a/src/test/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManagerTest.java b/src/test/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManagerTest.java new file mode 100644 index 0000000..b9887a2 --- /dev/null +++ b/src/test/java/org/gcube/dataanalysis/wps/statisticalmanager/synchserver/mapping/TokenManagerTest.java @@ -0,0 +1,26 @@ +package org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mapping; + +import org.apache.log4j.BasicConfigurator; +import org.junit.Test; + +public class TokenManagerTest { + + private static final String JWT_TOKEN = ""; + private static final String SCOPE = "/gcube/devsec/devVRE"; + + + @Test + public void retrieveTokenFromUriResolver() throws Exception { + try { + BasicConfigurator.configure(); + System.out.println("Test Retrieve Token From Uri Resolver"); + TokenManager tm = new TokenManager(); + String token = tm.getGcubeTokenFromUriResolver(JWT_TOKEN, SCOPE); + System.out.println("GcubeToken retrieved: "+token); + } catch (Exception e) { + System.out.println(e.getLocalizedMessage()); + e.getStackTrace(); + } + } + +} From 2585b6142dd96bdd3d9c3f40994a614b99658ebf Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Tue, 5 Apr 2022 18:23:49 +0200 Subject: [PATCH 2/5] Updated Changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9021c91..8764810 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [v1.9.0-SNAPSHOT] - 2022-04-05 -- Support new JWT token via URI Resolver [#23107] +- Added support to new JWT token via URI Resolver [#23107] ## [v1.8.1] - 2022-03-21 From 176b4281ed87ed71abd464ab6d8e9a8e47f8c52b Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Tue, 5 Apr 2022 18:27:06 +0200 Subject: [PATCH 3/5] Updated for Dev Env --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca80aec..f2dcdc1 100755 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.gcube.distribution gcube-bom - 2.0.2 + 2.1.0-SNAPSHOT pom import From d95a4908baaf2a7819d55acbc27662ef31294b6d Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Wed, 6 Apr 2022 16:39:33 +0200 Subject: [PATCH 4/5] Updated for pre --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2dcdc1..ca80aec 100755 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.gcube.distribution gcube-bom - 2.1.0-SNAPSHOT + 2.0.2 pom import From 8d02cd3e83bfa24eabb07922030e8200e5d981fe Mon Sep 17 00:00:00 2001 From: Giancarlo Panichi Date: Thu, 7 Apr 2022 15:18:08 +0200 Subject: [PATCH 5/5] Update for gCube Release 5.10.1 --- CHANGELOG.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8764810..fd051ee 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog for "dataminer" -## [v1.9.0-SNAPSHOT] - 2022-04-05 +## [v1.9.0] - 2022-04-05 - Added support to new JWT token via URI Resolver [#23107] diff --git a/pom.xml b/pom.xml index ca80aec..63ba6d5 100755 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.dataanalysis dataminer - 1.9.0-SNAPSHOT + 1.9.0 dataminer An e-Infrastructure service providing state-of-the art DataMining algorithms and ecological modelling approaches under the Web Processing Service (WPS) standard.