package org.gcube.datatransfer.resolver.services; import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; import java.util.Collection; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.encryption.StringEncrypter; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.resources.gcore.ServiceEndpoint.Property; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.requesthandler.RequestHandler; import org.gcube.datatransfer.resolver.services.error.ExceptionManager; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // TODO: Auto-generated Javadoc /** * The Class WekeoResolver. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Mar 30, 2021 */ @Path("wekeo") public class WekeoResolver { private static Logger logger = LoggerFactory.getLogger(WekeoResolver.class); private final static String RUNTIME_WKEO_RESOURCE_NAME = "WekeoDataBroker"; private final static String CATEGORY_WEKEO_TYPE = "OnlineService"; private static String helpURI = "https://wiki.gcube-system.org/gcube/URI_Resolver#Wekeo_Resolver"; /** * Gets the token. * * @param req the req * @return the token * @throws WebApplicationException the web application exception */ @GET @Path("/gettoken") public Response getToken(@Context HttpServletRequest req) throws WebApplicationException{ logger.info(this.getClass().getSimpleName()+" getToken starts..."); String wekeoToken = ""; try { String contextToken = SecurityTokenProvider.instance.get(); String scope = ScopeProvider.instance.get(); logger.info("ScopeProvider has scope: "+scope); String appToken = req.getServletContext().getInitParameter(RequestHandler.ROOT_APP_TOKEN); if(contextToken.compareTo(appToken)==0){ logger.error("Token not passed, SecurityTokenProvider contains the root app token: "+appToken.substring(0,10)+"..."); throw ExceptionManager.unauthorizedException(req, "You are not authorized. You must pass a token of VRE", this.getClass(), helpURI); } List endPoints = getConfigurationFromIS(); if(endPoints==null || endPoints.size()==0) { String error = String.format("Missing the RR with Name '%s' and Category '%s' in the scope '%s'. Please contact the support.",RUNTIME_WKEO_RESOURCE_NAME,CATEGORY_WEKEO_TYPE,scope); throw ExceptionManager.internalErrorException(req, error, this.getClass(), helpURI); } String wekeoEndPoint = readWekeoServiceEndpoint(req, scope); return Response.ok(wekeoToken).build(); }catch (Exception e) { //ALREADY MANAGED AS WebApplicationException logger.error("Exception:", e); throw (WebApplicationException) e; } } /** * Retrieve the wekeo endpoint information from IS. * * @return list of endpoints for ckan database * @throws Exception the exception */ private static List getConfigurationFromIS() throws Exception{ SimpleQuery query = queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_WKEO_RESOURCE_NAME +"'"); query.addCondition("$resource/Profile/Cateogory/Name/text() eq '"+ CATEGORY_WEKEO_TYPE +"'"); DiscoveryClient client = clientFor(ServiceEndpoint.class); List toReturn = client.submit(query); return toReturn; } /** * Reads the wekeo endpoint information from IS. {The SE name is: @link WekeoResolver#RUNTIME_WKEO_RESOURCE_NAME} * * @param req the req * @param scope the scope * @return the string */ private static String readWekeoServiceEndpoint(HttpServletRequest req, String scope){ String callerScope = null; String gCubeAppToken = null; try{ callerScope = ScopeProvider.instance.get(); ScopeProvider.instance.set(scope); logger.info("Searching SE "+RUNTIME_WKEO_RESOURCE_NAME+" configurations in the scope: "+ScopeProvider.instance.get()); SimpleQuery query = queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_WKEO_RESOURCE_NAME +"'"); query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY_WEKEO_TYPE +"'"); DiscoveryClient client = clientFor(ServiceEndpoint.class); List toReturn = client.submit(query); logger.info("The query returned "+toReturn.size()+ " ServiceEndpoint/s"); if(toReturn.size()==0){ String errorMessage = String.format("Missing the RR with Name '%s' and Category '%s' in the scope '%s'. Please contact the support.",RUNTIME_WKEO_RESOURCE_NAME,CATEGORY_WEKEO_TYPE,ScopeProvider.instance.get()); logger.error(errorMessage); throw ExceptionManager.internalErrorException(req, errorMessage, AnalyticsCreateResolver.class, helpURI); } ServiceEndpoint se = toReturn.get(0); Collection theAccessPoints = se.profile().accessPoints().asCollection(); for (AccessPoint accessPoint : theAccessPoints) { Collection properties = accessPoint.properties().asCollection(); for (Property property : properties) { // if(property.name().equalsIgnoreCase(GCUBE_TOKEN)){ // logger.info("gcube-token as property was found, returning it"); // gCubeAppToken = property.value(); // break; // } } if(gCubeAppToken!=null) break; } if(gCubeAppToken!=null){ String decryptedPassword = StringEncrypter.getEncrypter().decrypt(gCubeAppToken); logger.info("Returning decrypted Application Token registered into "+RUNTIME_WKEO_RESOURCE_NAME +" SE: "+decryptedPassword.substring(0,decryptedPassword.length()/2)+"...."); return decryptedPassword; } return null; // // String errorMessage = "No "+GCUBE_TOKEN+" as Property saved in the "+RUNTIME_WKEO_RESOURCE_NAME+" SE registered in the scope: "+ScopeProvider.instance.get(); // logger.error(errorMessage); // throw ExceptionManager.internalErrorException(req, errorMessage, AnalyticsCreateResolver.class, helpURI); }catch(Exception e){ String errorMessage = "Error occurred on reading the "+RUNTIME_WKEO_RESOURCE_NAME+" SE registered in the scope: "+ScopeProvider.instance.get(); logger.error(errorMessage, e); throw ExceptionManager.internalErrorException(req, errorMessage, AnalyticsCreateResolver.class, helpURI); }finally{ if(callerScope!=null){ logger.info("Setting to the callerScope scope: "+callerScope); ScopeProvider.instance.set(callerScope); }else{ logger.info("Reset scope"); ScopeProvider.instance.reset(); } } } }