Adding support for contexts extra info

This commit is contained in:
Luca Frosini 2024-07-01 17:39:48 +02:00
parent e42b2bde0a
commit 69ad3803eb
6 changed files with 114 additions and 34 deletions

View File

@ -23,7 +23,6 @@ import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCacheRenewal; import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCacheRenewal;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextManagement; import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextManagement;
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
import org.gcube.informationsystem.resourceregistry.requests.RequestUtility; import org.gcube.informationsystem.resourceregistry.requests.RequestUtility;
import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo; import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo;
import org.gcube.informationsystem.serialization.ElementMapper; import org.gcube.informationsystem.serialization.ElementMapper;
@ -40,8 +39,8 @@ public class ServerContextCache extends ContextCache {
protected List<Context> contextsMetaPrivacy; protected List<Context> contextsMetaPrivacy;
protected Map<UUID, Context> uuidToContextMetaPrivacy; protected Map<UUID, Context> uuidToContextMetaPrivacy;
protected List<Context> contextsNoMeta; protected List<Context> contextsBasicInfo;
protected Map<UUID, Context> uuidToContextNoMeta; protected Map<UUID, Context> uuidToContextBasicInfo;
protected boolean includeMeta; protected boolean includeMeta;
@ -64,8 +63,8 @@ public class ServerContextCache extends ContextCache {
super.cleanCache(now); super.cleanCache(now);
contextsMetaPrivacy = null; contextsMetaPrivacy = null;
uuidToContextMetaPrivacy = null; uuidToContextMetaPrivacy = null;
contextsNoMeta = null; contextsBasicInfo = null;
uuidToContextNoMeta = null; uuidToContextBasicInfo = null;
} }
public ServerContextCache() { public ServerContextCache() {
@ -102,18 +101,15 @@ public class ServerContextCache extends ContextCache {
setContextCacheRenewal(contextCacheRenewal); setContextCacheRenewal(contextCacheRenewal);
} }
protected boolean isUserAllowedToGetPrivacyMeta() {
return ElementManagement.isUserAllowedToGetPrivacyMeta();
}
@Override @Override
public synchronized List<Context> getContexts() throws ResourceRegistryException { public synchronized List<Context> getContexts() throws ResourceRegistryException {
refreshContextsIfNeeded(); refreshContextsIfNeeded();
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){ if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){
return contextsNoMeta; return contextsBasicInfo;
} }
if(isUserAllowedToGetPrivacyMeta()) { ContextManagement contextManagement = new ContextManagement();
if(contextManagement.isUserAllowedToGetPrivacyMeta()) {
return contexts; return contexts;
}else { }else {
return contextsMetaPrivacy; return contextsMetaPrivacy;
@ -125,15 +121,25 @@ public class ServerContextCache extends ContextCache {
refreshContextsIfNeeded(); refreshContextsIfNeeded();
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){ if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){
return uuidToContextNoMeta.get(uuid); return uuidToContextBasicInfo.get(uuid);
} }
if(isUserAllowedToGetPrivacyMeta()) { ContextManagement contextManagement = new ContextManagement();
if(contextManagement.isUserAllowedToGetPrivacyMeta()) {
return uuidToContext.get(uuid); return uuidToContext.get(uuid);
}else { }else {
return uuidToContextMetaPrivacy.get(uuid); return uuidToContextMetaPrivacy.get(uuid);
} }
} }
/**
* USer internally to the service to get info such as state
* @param uuid
* @return
* @throws ResourceRegistryException
*/
public synchronized Context getContextByUUIDFullInfo(UUID uuid) throws ResourceRegistryException {
return uuidToContext.get(uuid);
}
protected Metadata getMetadataForPrivacy(ObjectMapper objectMapper, Metadata metadata) { protected Metadata getMetadataForPrivacy(ObjectMapper objectMapper, Metadata metadata) {
ObjectNode objectNode = objectMapper.valueToTree(metadata); ObjectNode objectNode = objectMapper.valueToTree(metadata);
@ -155,8 +161,8 @@ public class ServerContextCache extends ContextCache {
this.contextsMetaPrivacy = new ArrayList<>(); this.contextsMetaPrivacy = new ArrayList<>();
this.uuidToContextMetaPrivacy = new LinkedHashMap<>(); this.uuidToContextMetaPrivacy = new LinkedHashMap<>();
this.contextsNoMeta = new ArrayList<>(); this.contextsBasicInfo = new ArrayList<>();
this.uuidToContextNoMeta = new LinkedHashMap<>(); this.uuidToContextBasicInfo = new LinkedHashMap<>();
ObjectMapper objectMapper = ElementMapper.getObjectMapper(); ObjectMapper objectMapper = ElementMapper.getObjectMapper();
@ -180,8 +186,8 @@ public class ServerContextCache extends ContextCache {
Context contextNoMeta = new ContextImpl(c.getName()); Context contextNoMeta = new ContextImpl(c.getName());
contextNoMeta.setMetadata(null); contextNoMeta.setMetadata(null);
contextNoMeta.setID(uuid); contextNoMeta.setID(uuid);
this.contextsNoMeta.add(contextNoMeta); this.contextsBasicInfo.add(contextNoMeta);
this.uuidToContextNoMeta.put(uuid, contextNoMeta); this.uuidToContextBasicInfo.put(uuid, contextNoMeta);
} }
@ -190,7 +196,7 @@ public class ServerContextCache extends ContextCache {
Context contextMeta = this.uuidToContext.get(uuid); Context contextMeta = this.uuidToContext.get(uuid);
Context contextMetaPrivacy = this.uuidToContextMetaPrivacy.get(uuid); Context contextMetaPrivacy = this.uuidToContextMetaPrivacy.get(uuid);
Context contextNoMeta = this.uuidToContextNoMeta.get(uuid); Context contextNoMeta = this.uuidToContextBasicInfo.get(uuid);
if(c.getParent()!=null) { if(c.getParent()!=null) {
@ -213,7 +219,7 @@ public class ServerContextCache extends ContextCache {
parentWithMetaPrivacy.addChild(isParentOfMetaPrivacy); parentWithMetaPrivacy.addChild(isParentOfMetaPrivacy);
contextMetaPrivacy.setParent(isParentOfMetaPrivacy); contextMetaPrivacy.setParent(isParentOfMetaPrivacy);
Context parentNoMeta = this.uuidToContextNoMeta.get(contextParentUUID); Context parentNoMeta = this.uuidToContextBasicInfo.get(contextParentUUID);
IsParentOf isParentOfNoMeta = new IsParentOfImpl(parentNoMeta, contextNoMeta); IsParentOf isParentOfNoMeta = new IsParentOfImpl(parentNoMeta, contextNoMeta);
isParentOfNoMeta.setMetadata(null); isParentOfNoMeta.setMetadata(null);
isParentOfNoMeta.setID(isParentOfParentUUID); isParentOfNoMeta.setID(isParentOfParentUUID);

View File

@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.ws.rs.ForbiddenException;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
@ -15,6 +17,7 @@ import org.gcube.com.fasterxml.jackson.databind.node.NullNode;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.base.reference.IdentifiableElement; import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.contexts.reference.ContextState;
import org.gcube.informationsystem.contexts.reference.entities.Context; import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf; import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.model.reference.relations.Relation; import org.gcube.informationsystem.model.reference.relations.Relation;
@ -281,6 +284,8 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
createVertex(); createVertex();
} }
this.element.setProperty(Context.STATE, ContextState.CREATED);
securityContext = new SecurityContext(uuid); securityContext = new SecurityContext(uuid);
securityContext.setParentSecurityContext(parentSecurityContext); securityContext.setParentSecurityContext(parentSecurityContext);
securityContext.create(oDatabaseDocument); securityContext.create(oDatabaseDocument);
@ -578,6 +583,14 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
} }
} }
@Override
public String createOrUpdate() throws NotFoundException, AvailableInAnotherContextException, ResourceRegistryException {
if(isUserAllowed()) {
return super.createOrUpdate();
}
throw new ForbiddenException("You are not allowed to manipulate Contexts. Allowed roles are " + allowedRoles);
}
@Override @Override
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException { public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
// Nothing to do // Nothing to do

View File

@ -15,6 +15,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.activation.UnsupportedDataTypeException; import javax.activation.UnsupportedDataTypeException;
import javax.ws.rs.ForbiddenException;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.JsonNode;
@ -25,9 +26,14 @@ import org.gcube.com.fasterxml.jackson.databind.node.JsonNodeType;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.com.fasterxml.jackson.databind.node.TextNode; import org.gcube.com.fasterxml.jackson.databind.node.TextNode;
import org.gcube.common.authorization.library.provider.CalledMethodProvider; import org.gcube.common.authorization.library.provider.CalledMethodProvider;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import org.gcube.common.authorization.utils.user.User;
import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.base.reference.Element; import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.base.reference.IdentifiableElement; import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.contexts.reference.ContextState;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.model.reference.ERElement; import org.gcube.informationsystem.model.reference.ERElement;
import org.gcube.informationsystem.model.reference.ModelElement; import org.gcube.informationsystem.model.reference.ModelElement;
import org.gcube.informationsystem.model.reference.properties.Metadata; import org.gcube.informationsystem.model.reference.properties.Metadata;
@ -153,6 +159,16 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
*/ */
protected final Map<UUID,JsonNode> affectedInstances; protected final Map<UUID,JsonNode> affectedInstances;
/**
* Roles allowed to operate on Context and
* on instances when the context is not active
*/
protected Set<String> allowedRoles;
protected final static String CONTEXT_MANAGER = "Context-Manager";
protected final static String INFRASTRUCTURE_MANAGER = "Infrastructure-Manager";
protected final static String IS_MANAGER = "IS-Manager";
protected ElementManagement(AccessType accessType) { protected ElementManagement(AccessType accessType) {
this.accessType = accessType; this.accessType = accessType;
@ -183,6 +199,11 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
this.forceIncludeMeta = false; this.forceIncludeMeta = false;
this.forceIncludeAllMeta = false; this.forceIncludeAllMeta = false;
this.allowedRoles = new HashSet<>();
this.allowedRoles.add(CONTEXT_MANAGER);
this.allowedRoles.add(INFRASTRUCTURE_MANAGER);
this.allowedRoles.add(IS_MANAGER);
} }
public boolean isForceIncludeMeta() { public boolean isForceIncludeMeta() {
@ -247,9 +268,27 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
protected SecurityContext workingContext; protected SecurityContext workingContext;
public boolean isUserAllowed() {
boolean allowed = false;
SecretManager secretManager = SecretManagerProvider.instance.get();
User user = secretManager.getUser();
Collection<String> roles = new HashSet<>(user.getRoles());
roles.retainAll(this.allowedRoles);
if(roles.size()>0) {
allowed = true;
}
return allowed;
}
protected SecurityContext getWorkingContext() throws ResourceRegistryException { protected SecurityContext getWorkingContext() throws ResourceRegistryException {
if(workingContext == null) { if(workingContext == null) {
workingContext = ContextUtility.getCurrentSecurityContext(); workingContext = ContextUtility.getCurrentSecurityContext();
Context context = ServerContextCache.getInstance().getContextByUUID(workingContext.getUUID());
if(context.getState().compareTo(ContextState.ACTIVE.getState())!=0) {
if(!isUserAllowed()) {
throw new ForbiddenException("You are not allowed to manipulate Contexts. Allowed roles are " + allowedRoles);
}
}
} }
return workingContext; return workingContext;
} }
@ -1226,9 +1265,16 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
return element; return element;
} }
public static boolean isUserAllowedToGetPrivacyMeta() { public boolean isUserAllowedToGetPrivacyMeta() {
// TODO boolean allowed = false;
return true; SecretManager secretManager = SecretManagerProvider.instance.get();
User user = secretManager.getUser();
Collection<String> roles = new HashSet<>(user.getRoles());
roles.retainAll(this.allowedRoles);
if(roles.size()>0) {
allowed = true;
}
return allowed;
} }
protected JsonNode getPropertyForJson(String key, Object object) throws ResourceRegistryException { protected JsonNode getPropertyForJson(String key, Object object) throws ResourceRegistryException {

View File

@ -81,8 +81,18 @@ public class Access extends BaseRest {
setAccountingMethod(Method.LIST, org.gcube.informationsystem.contexts.reference.entities.Context.NAME); setAccountingMethod(Method.LIST, org.gcube.informationsystem.contexts.reference.entities.Context.NAME);
ServerRequestInfo serverRequestInfo = initRequestInfo(BaseRequestInfo.DEFAULT_OFFSET, BaseRequestInfo.UNBOUNDED_LIMIT); ServerRequestInfo serverRequestInfo = initRequestInfo(BaseRequestInfo.DEFAULT_OFFSET, BaseRequestInfo.UNBOUNDED_LIMIT);
serverRequestInfo.setAllMeta(true); /*
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER); * We never provide meta information
* for context via this REST API.
* Contexts collection should be used instead.
*/
serverRequestInfo.setIncludeMeta(false);
serverRequestInfo.setAllMeta(false);
/*
* serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);
* serverRequestInfo.setAllMeta(true);
*/
serverRequestInfo.checkLimitOffset(); serverRequestInfo.checkLimitOffset();
ContextManagement contextManagement = new ContextManagement(); ContextManagement contextManagement = new ContextManagement();
@ -105,6 +115,11 @@ public class Access extends BaseRest {
setAccountingMethod(Method.READ, org.gcube.informationsystem.contexts.reference.entities.Context.NAME); setAccountingMethod(Method.READ, org.gcube.informationsystem.contexts.reference.entities.Context.NAME);
ServerRequestInfo serverRequestInfo = initRequestInfo(); ServerRequestInfo serverRequestInfo = initRequestInfo();
/*
* We have to think if never provide meta information
* for context via this REST API.
* Contexts collection should be used instead.
*/
serverRequestInfo.setAllMeta(true); serverRequestInfo.setAllMeta(true);
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER); serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);

View File

@ -48,8 +48,8 @@ public class ContextManager extends BaseRest {
setAccountingMethod(Method.LIST, Context.NAME); setAccountingMethod(Method.LIST, Context.NAME);
ServerRequestInfo serverRequestInfo = initRequestInfo(BaseRequestInfo.DEFAULT_OFFSET, BaseRequestInfo.UNBOUNDED_LIMIT); ServerRequestInfo serverRequestInfo = initRequestInfo(BaseRequestInfo.DEFAULT_OFFSET, BaseRequestInfo.UNBOUNDED_LIMIT);
serverRequestInfo.setIncludeMeta(true);
serverRequestInfo.setAllMeta(true); serverRequestInfo.setAllMeta(true);
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);
serverRequestInfo.checkLimitOffset(); serverRequestInfo.checkLimitOffset();
ContextManagement contextManagement = new ContextManagement(); ContextManagement contextManagement = new ContextManagement();
@ -74,8 +74,8 @@ public class ContextManager extends BaseRest {
setAccountingMethod(Method.READ, Context.NAME); setAccountingMethod(Method.READ, Context.NAME);
ServerRequestInfo serverRequestInfo = initRequestInfo(); ServerRequestInfo serverRequestInfo = initRequestInfo();
serverRequestInfo.setIncludeMeta(true);
serverRequestInfo.setAllMeta(true); serverRequestInfo.setAllMeta(true);
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);
ContextManagement contextManagement = new ContextManagement(); ContextManagement contextManagement = new ContextManagement();
contextManagement.setUUID(UUID.fromString(uuid)); contextManagement.setUUID(UUID.fromString(uuid));
@ -99,8 +99,8 @@ public class ContextManager extends BaseRest {
setAccountingMethod(Method.UPDATE, Context.NAME); setAccountingMethod(Method.UPDATE, Context.NAME);
ServerRequestInfo serverRequestInfo = initRequestInfo(); ServerRequestInfo serverRequestInfo = initRequestInfo();
serverRequestInfo.setIncludeMeta(true);
serverRequestInfo.setAllMeta(true); serverRequestInfo.setAllMeta(true);
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);
ContextManagement contextManagement = new ContextManagement(); ContextManagement contextManagement = new ContextManagement();
contextManagement.setUUID(UUID.fromString(uuid)); contextManagement.setUUID(UUID.fromString(uuid));

View File

@ -362,12 +362,12 @@ public class TypeManagement {
*/ */
if(!typeList.contains(type.getName())) { if(!typeList.contains(type.getName())) {
switch(propertyTypeName.getBaseType()) { switch(propertyTypeName.getBaseType()) {
// case LIST: case LIST:
// throw new UnsupportedDataTypeException(OType.EMBEDDEDLIST throw new UnsupportedDataTypeException(OType.EMBEDDEDLIST
// + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354");
// case SET: case SET:
// throw new UnsupportedDataTypeException(OType.EMBEDDEDSET throw new UnsupportedDataTypeException(OType.EMBEDDEDSET
// + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); + " support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354");
default: default:
break; break;
} }