2020-01-27 17:07:37 +01:00
|
|
|
package org.gcube.informationsystem.resourceregistry.contexts;
|
2016-07-18 11:57:12 +02:00
|
|
|
|
2017-05-04 17:24:36 +02:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
2017-11-28 17:34:43 +01:00
|
|
|
import java.util.NoSuchElementException;
|
2016-10-27 17:46:09 +02:00
|
|
|
import java.util.UUID;
|
2016-07-18 11:57:12 +02:00
|
|
|
|
2022-07-20 17:44:59 +02:00
|
|
|
import org.gcube.common.security.ContextBean;
|
|
|
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
2021-09-16 15:23:04 +02:00
|
|
|
import org.gcube.informationsystem.base.reference.IdentifiableElement;
|
2021-10-25 11:40:47 +02:00
|
|
|
import org.gcube.informationsystem.contexts.reference.entities.Context;
|
|
|
|
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
|
2021-09-16 15:23:04 +02:00
|
|
|
import org.gcube.informationsystem.model.reference.properties.Header;
|
2020-11-05 12:12:19 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
|
2016-09-12 14:45:40 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
2022-02-01 16:49:12 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException;
|
2020-01-27 17:07:37 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.contexts.security.AdminSecurityContext;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
|
2021-02-10 15:54:52 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
|
2016-12-22 17:33:10 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
2016-07-18 11:57:12 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
|
|
|
|
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
|
|
|
|
import com.orientechnologies.orient.core.record.ODirection;
|
|
|
|
import com.orientechnologies.orient.core.record.OVertex;
|
2021-09-16 15:23:04 +02:00
|
|
|
import com.orientechnologies.orient.core.record.impl.ODocument;
|
2019-11-06 12:13:19 +01:00
|
|
|
import com.orientechnologies.orient.core.sql.executor.OResult;
|
|
|
|
import com.orientechnologies.orient.core.sql.executor.OResultSet;
|
2016-07-18 11:57:12 +02:00
|
|
|
|
|
|
|
/**
|
2016-10-12 14:33:23 +02:00
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
2016-07-18 11:57:12 +02:00
|
|
|
*/
|
2016-11-11 12:01:12 +01:00
|
|
|
public class ContextUtility {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ContextUtility.class);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
private Map<UUID,SecurityContext> contexts;
|
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
private static ContextUtility contextUtility;
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-12-05 10:10:34 +01:00
|
|
|
public static ContextUtility getInstance() {
|
2017-11-30 18:06:08 +01:00
|
|
|
if(contextUtility == null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
contextUtility = new ContextUtility();
|
|
|
|
}
|
|
|
|
return contextUtility;
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
private ContextUtility() {
|
|
|
|
contexts = new HashMap<>();
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2020-10-27 15:12:11 +01:00
|
|
|
private static final InheritableThreadLocal<Boolean> hierarchicalMode = new InheritableThreadLocal<Boolean>() {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Boolean initialValue() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2020-10-27 15:12:11 +01:00
|
|
|
public static InheritableThreadLocal<Boolean> getHierarchicalMode() {
|
|
|
|
return hierarchicalMode;
|
2017-11-30 18:06:08 +01:00
|
|
|
}
|
|
|
|
|
2020-11-09 15:45:07 +01:00
|
|
|
|
|
|
|
private static final InheritableThreadLocal<Boolean> includeInstanceContexts = new InheritableThreadLocal<Boolean>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Boolean initialValue() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
public static InheritableThreadLocal<Boolean> getIncludeInstanceContexts() {
|
|
|
|
return includeInstanceContexts;
|
|
|
|
}
|
|
|
|
|
2021-01-26 16:54:20 +01:00
|
|
|
public static String getCurrentContextFullName() {
|
2022-03-07 14:16:51 +01:00
|
|
|
return SecretManagerProvider.instance.get().getContext();
|
2016-11-03 12:15:18 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
public static SecurityContext getCurrentSecurityContext() throws ResourceRegistryException {
|
|
|
|
String fullName = getCurrentContextFullName();
|
2017-11-30 18:06:08 +01:00
|
|
|
if(fullName == null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
throw new ContextException("Null Token and Scope. Please set your token first.");
|
|
|
|
}
|
2017-12-05 10:10:34 +01:00
|
|
|
return ContextUtility.getInstance().getSecurityContextByFullName(fullName);
|
2017-11-28 17:34:43 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
public static AdminSecurityContext getAdminSecurityContext() throws ResourceRegistryException {
|
2021-10-22 19:26:36 +02:00
|
|
|
AdminSecurityContext adminSecurityContext = AdminSecurityContext.getInstance();
|
2017-11-28 17:34:43 +01:00
|
|
|
return adminSecurityContext;
|
|
|
|
}
|
|
|
|
|
2017-12-05 10:10:34 +01:00
|
|
|
public synchronized void addSecurityContext(SecurityContext securityContext) {
|
|
|
|
contexts.put(securityContext.getUUID(), securityContext);
|
|
|
|
}
|
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
public synchronized void addSecurityContext(String fullname, SecurityContext securityContext) {
|
|
|
|
contexts.put(securityContext.getUUID(), securityContext);
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2021-01-28 22:53:10 +01:00
|
|
|
public synchronized SecurityContext getSecurityContextByFullName(String fullName) throws ContextException {
|
2021-09-16 15:23:04 +02:00
|
|
|
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
|
|
|
ODatabaseDocument oDatabaseDocument = null;
|
2016-07-18 11:57:12 +02:00
|
|
|
try {
|
2017-11-28 17:34:43 +01:00
|
|
|
SecurityContext securityContext = null;
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
logger.trace("Trying to get {} for {}", SecurityContext.class.getSimpleName(), fullName);
|
2020-11-05 12:12:19 +01:00
|
|
|
UUID uuid = ContextCache.getInstance().getUUIDByFullName(fullName);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2020-11-05 12:12:19 +01:00
|
|
|
if(uuid != null) {
|
|
|
|
securityContext = contexts.get(uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(securityContext==null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
logger.trace("{} for {} is not in cache. Going to get it", SecurityContext.class.getSimpleName(),
|
|
|
|
fullName);
|
2021-09-16 15:23:04 +02:00
|
|
|
oDatabaseDocument = getAdminSecurityContext().getDatabaseDocument(PermissionMode.READER);
|
|
|
|
|
|
|
|
OVertex contextVertex = getContextVertexByFullName(oDatabaseDocument, fullName);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2021-09-16 15:23:04 +02:00
|
|
|
ODocument oDocument = contextVertex.getProperty(IdentifiableElement.HEADER_PROPERTY);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2021-09-16 15:23:04 +02:00
|
|
|
uuid = UUID.fromString(oDocument.getProperty(Header.UUID_PROPERTY));
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
securityContext = getSecurityContextByUUID(uuid, contextVertex);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
addSecurityContext(fullName, securityContext);
|
2021-09-16 15:23:04 +02:00
|
|
|
|
2020-11-05 12:12:19 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
return securityContext;
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
} catch(ContextException e) {
|
2016-11-03 12:15:18 +01:00
|
|
|
throw e;
|
2017-11-30 18:06:08 +01:00
|
|
|
} catch(Exception e) {
|
2020-11-09 15:45:07 +01:00
|
|
|
throw new ContextException("Unable to retrieve Context UUID from current Context", e);
|
2021-09-16 15:23:04 +02:00
|
|
|
} finally {
|
|
|
|
if(oDatabaseDocument!=null) {
|
|
|
|
oDatabaseDocument.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(current!=null) {
|
|
|
|
current.activateOnCurrentThread();
|
|
|
|
}
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2018-06-06 19:26:19 +02:00
|
|
|
public SecurityContext getSecurityContextByUUID(UUID uuid) throws ResourceRegistryException {
|
2017-11-28 17:34:43 +01:00
|
|
|
return getSecurityContextByUUID(uuid, null);
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
public static ODatabaseDocument getCurrentODatabaseDocumentFromThreadLocal() {
|
|
|
|
ODatabaseDocument current = null;
|
|
|
|
try {
|
|
|
|
current = (ODatabaseDocument) ODatabaseRecordThreadLocal.instance().get();
|
|
|
|
}catch (Exception e) {
|
2021-02-16 13:52:23 +01:00
|
|
|
// It is possible that there is no current ODatabaseDocument
|
2019-11-05 18:36:44 +01:00
|
|
|
}
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
private OVertex getContextVertexByUUID(UUID uuid) throws ResourceRegistryException {
|
|
|
|
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
2021-09-16 15:23:04 +02:00
|
|
|
ODatabaseDocument oDatabaseDocument = null;
|
|
|
|
try {
|
|
|
|
oDatabaseDocument = getAdminSecurityContext().getDatabaseDocument(PermissionMode.READER);
|
|
|
|
OVertex oVertex = Utility.getElementByUUID(oDatabaseDocument, Context.NAME, uuid,
|
|
|
|
OVertex.class);
|
|
|
|
return oVertex;
|
|
|
|
} finally {
|
|
|
|
if(oDatabaseDocument!=null) {
|
|
|
|
oDatabaseDocument.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(current!=null) {
|
|
|
|
current.activateOnCurrentThread();
|
|
|
|
}
|
2019-11-05 18:36:44 +01:00
|
|
|
}
|
2016-10-14 15:35:20 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
private SecurityContext getSecurityContextByUUID(UUID uuid, OVertex contextVertex) throws ResourceRegistryException {
|
2017-11-28 17:34:43 +01:00
|
|
|
SecurityContext securityContext = contexts.get(uuid);
|
2017-11-30 18:06:08 +01:00
|
|
|
if(securityContext == null) {
|
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
securityContext = new SecurityContext(uuid);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
try {
|
2017-11-30 18:06:08 +01:00
|
|
|
if(contextVertex == null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
contextVertex = getContextVertexByUUID(uuid);
|
|
|
|
}
|
2019-11-05 18:36:44 +01:00
|
|
|
OVertex parentVertex = contextVertex.getVertices(ODirection.IN, IsParentOf.NAME).iterator().next();
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
if(parentVertex != null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
UUID parentUUID = Utility.getUUID(parentVertex);
|
|
|
|
securityContext.setParentSecurityContext(getSecurityContextByUUID(parentUUID, parentVertex));
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
} catch(NoSuchElementException e) {
|
2017-11-28 17:34:43 +01:00
|
|
|
// No parent
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
contexts.put(uuid, securityContext);
|
2016-10-14 15:35:20 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
return securityContext;
|
2016-10-14 15:35:20 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2021-09-16 15:23:04 +02:00
|
|
|
/*
|
2018-04-12 14:46:24 +02:00
|
|
|
protected UUID getContextUUIDFromFullName(String fullName) throws ResourceRegistryException {
|
2019-11-05 18:36:44 +01:00
|
|
|
OVertex contextVertex = getContextVertexByFullName(fullName);
|
2018-04-12 14:46:24 +02:00
|
|
|
return Utility.getUUID(contextVertex);
|
|
|
|
}
|
2021-09-16 15:23:04 +02:00
|
|
|
*/
|
2018-04-12 14:46:24 +02:00
|
|
|
|
2021-09-16 15:23:04 +02:00
|
|
|
private OVertex getContextVertexByFullName(ODatabaseDocument oDatabaseDocument, String fullName) throws ResourceRegistryException {
|
2019-11-05 18:36:44 +01:00
|
|
|
logger.trace("Going to get {} {} with full name '{}'", Context.NAME, OVertex.class.getSimpleName(), fullName);
|
2021-09-16 15:23:04 +02:00
|
|
|
|
2022-07-20 17:44:59 +02:00
|
|
|
ContextBean scopeBean = new ContextBean(fullName);
|
2016-07-18 11:57:12 +02:00
|
|
|
String name = scopeBean.name();
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-06 12:13:19 +01:00
|
|
|
// TODO Rewrite better query. This query works because all the scope parts has a different name
|
|
|
|
String select = "SELECT FROM " + Context.class.getSimpleName() + " WHERE " + Context.NAME_PROPERTY + " = :name";
|
|
|
|
Map<String, String> map = new HashMap<>();
|
|
|
|
map.put("name", name);
|
2019-11-05 18:36:44 +01:00
|
|
|
|
2021-09-16 15:23:04 +02:00
|
|
|
OResultSet resultSet = oDatabaseDocument.query(select, map);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-06 12:13:19 +01:00
|
|
|
if(resultSet == null || !resultSet.hasNext()) {
|
2017-11-28 17:34:43 +01:00
|
|
|
throw new ContextNotFoundException("Error retrieving context with name " + fullName);
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-06 12:13:19 +01:00
|
|
|
OResult oResult = resultSet.next();
|
2021-02-10 15:54:52 +01:00
|
|
|
OVertex context = ElementManagementUtility.getElementFromOptional(oResult.getVertex());
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
logger.trace("Context Representing Vertex : {}", Utility.toJsonString(context, true));
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-11-06 12:13:19 +01:00
|
|
|
if(resultSet.hasNext()) {
|
2017-11-28 17:34:43 +01:00
|
|
|
throw new ContextNotFoundException("Found more than one context with name " + name
|
|
|
|
+ "but required the one with path" + fullName + ". Please Reimplement the query");
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-07-18 11:57:12 +02:00
|
|
|
return context;
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-07-18 11:57:12 +02:00
|
|
|
}
|