catalogue-util-library/src/main/java/org/gcube/datacatalogue/utillibrary/server/utils/GCubeUtils.java

188 lines
6.5 KiB
Java

package org.gcube.datacatalogue.utillibrary.server.utils;
import java.util.List;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager;
import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO: Auto-generated Javadoc
/**
* The Class GCubeUtils.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 10, 2021
*/
public class GCubeUtils {
/**
* The Enum GCUBE_SCOPE_LEVEL.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Feb 10, 2021
*/
public static enum GCUBE_SCOPE_LEVEL {
ROOT, VO, VRE
}
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(CatalogueUtilMethods.class);
/**
* To G cube level.
*
* @param scope the scope
* @return the gcube scope level
* @throws IllegalArgumentException the illegal argument exception
*/
public static GCUBE_SCOPE_LEVEL toGCubeLevel(String scope) throws IllegalArgumentException {
LOG.debug("called toGCubeLevel on " + scope);
if (scope == null || scope.isEmpty())
throw new IllegalArgumentException("Scope is null or empty");
if (!scope.startsWith("/")) {
throw new IllegalArgumentException("Scope should start with '/' ->" + scope);
}
if (scope.endsWith("/")) {
throw new IllegalArgumentException("Scope should not end with '/' ->" + scope);
}
String[] splits = scope.split("/");
if (splits.length > 4)
throw new IllegalArgumentException("Scope is invalid, too many '/' ->" + scope);
GCUBE_SCOPE_LEVEL toReturn = null;
if (splits.length == 2) { // is a root VO
toReturn = GCUBE_SCOPE_LEVEL.ROOT;
}else if (splits.length == 3) {// is a VO
toReturn = GCUBE_SCOPE_LEVEL.VO;
} else if (splits.length == 4) {// is a VRE
toReturn = GCUBE_SCOPE_LEVEL.VRE;
}
LOG.debug("current scope detected as " + toReturn);
return toReturn;
}
/**
* Given a ckan organization name retrieve the infrastructure scope.
*
* @param organizationName (prevre, devvre, ...)
* @return the scope of the infrastructure
* @throws Exception the exception
*/
public static String retrieveScopeFromOrganizationName(String organizationName) throws Exception {
LOG.debug("retrieveScopeFromOrganizationName name " + organizationName);
String scope = null;
GroupManager gm = new LiferayGroupManager();
List<GCubeGroup> groups = gm.listGroups();
for (GCubeGroup gCubeGroup : groups) {
if(gCubeGroup.getGroupName().equalsIgnoreCase(organizationName))
scope = gm.getInfrastructureScope(gCubeGroup.getGroupId());
}
LOG.info("returning scope "+scope+" for org name: " + organizationName);
return scope;
}
/**
* Detect the organizationName context (token and scope of VRE).
* If the working context (in the thread) is a root VO or VO and setInThread is true then switch to VRE context (setting ScopeProvider and SecurityTokenProvider)
*
* @param organizationName the organization name to switch to
* @param username the username
* @param setInThread if true set the target token (in the {@link SecurityTokenProvider}) and the scope (in the {@link ScopeProvider}) detected for the OrgName
* @return the gcube context with source scope/token and target (detected for organizationName) scope/token
* @throws Exception the exception
*/
public static GcubeContext detectAndSetTheOrgNameContext(String organizationName, String username, boolean setInThread) throws Exception {
String scope = ScopeProvider.instance.get();
String token = SecurityTokenProvider.instance.get();
if (scope == null)
throw new Exception("No scope detected. You must set it");
if (token == null)
throw new Exception("No token detected. You must set it");
GcubeContext gcubeContext = new GcubeContext();
gcubeContext.setSourceScope(scope);
gcubeContext.setSourceToken(token);
GCUBE_SCOPE_LEVEL gCubeScopeLevel = GCubeUtils.toGCubeLevel(scope);
if (gCubeScopeLevel != null) {
switch (gCubeScopeLevel) {
case ROOT:
case VO:
// Jump of scope
LOG.info("ROOT VO or VO scope detected, switching to OrgName (VRE) context needed for gCat");
PortalContext pContext = PortalContext.getConfiguration();
String destinationScopeForOrg = GCubeUtils.retrieveScopeFromOrganizationName(organizationName);
LOG.debug("Destination scope detected: " + destinationScopeForOrg);
String destinationTokenForUser = pContext.getCurrentUserToken(destinationScopeForOrg, username);
LOG.debug("Destination token detected: "
+ destinationTokenForUser.substring(0, destinationTokenForUser.length() - 12) + "XXXXX"
+ " for user: " + username);
if (destinationScopeForOrg != null && destinationTokenForUser != null) {
gcubeContext.setTargetScope(destinationScopeForOrg);
gcubeContext.setTargetToken(destinationTokenForUser);
if (setInThread) {
ScopeProvider.instance.set(destinationScopeForOrg);
SecurityTokenProvider.instance.set(destinationTokenForUser);
LOG.info("jump of scope and token done towards: " + destinationScopeForOrg);
}
} else
throw new Exception("I'm not able to set the right configurations to serve the request");
break;
case VRE:
// no action required
LOG.info("VRE context detected, no switch to VRE context is required");
break;
default:
break;
}
}
return gcubeContext;
}
/**
* Revert to source context (scope and token) if the context is different to working one (read from {@link ScopeProvider} and {@link SecurityTokenProvider})
*
* @param context the context
*/
public static void revertToSourceContext(GcubeContext context){
String scope = ScopeProvider.instance.get();
String token = SecurityTokenProvider.instance.get();
//resetting original contexts if required
if(scope!=null && context.getSourceScope()!=null && scope.compareTo(context.getSourceScope())!=0) {
LOG.info("Set scope to original: "+context.getSourceScope());
ScopeProvider.instance.set(context.getSourceScope());
}
if(token!=null && context.getSourceToken()!=null && token.compareTo(context.getSourceToken())!=0) {
LOG.info("Set token to original: "+(context.getSourceToken().substring(0, context.getSourceToken().length()-12)+"XXXXX"));
ScopeProvider.instance.set((context.getSourceToken()));
}
}
}