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

View File

@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.ForbiddenException;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
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.informationsystem.base.reference.AccessType;
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.relations.IsParentOf;
import org.gcube.informationsystem.model.reference.relations.Relation;
@ -281,6 +284,8 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
createVertex();
}
this.element.setProperty(Context.STATE, ContextState.CREATED);
securityContext = new SecurityContext(uuid);
securityContext.setParentSecurityContext(parentSecurityContext);
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
public void sanityCheck() throws SchemaViolationException, ResourceRegistryException {
// Nothing to do

View File

@ -15,6 +15,7 @@ import java.util.Set;
import java.util.UUID;
import javax.activation.UnsupportedDataTypeException;
import javax.ws.rs.ForbiddenException;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
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.TextNode;
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.Element;
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.ModelElement;
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;
/**
* 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) {
this.accessType = accessType;
@ -183,6 +199,11 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
this.forceIncludeMeta = 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() {
@ -247,9 +268,27 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
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 {
if(workingContext == null) {
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;
}
@ -1226,9 +1265,16 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
return element;
}
public static boolean isUserAllowedToGetPrivacyMeta() {
// TODO
return true;
public boolean isUserAllowedToGetPrivacyMeta() {
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 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);
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();
ContextManagement contextManagement = new ContextManagement();
@ -105,6 +115,11 @@ public class Access extends BaseRest {
setAccountingMethod(Method.READ, org.gcube.informationsystem.contexts.reference.entities.Context.NAME);
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.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);

View File

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

View File

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