Implementing strategy for add/remove to/from context no follow

This commit is contained in:
Luca Frosini 2021-02-02 16:50:48 +01:00
parent 6082e3a0d6
commit b18ebe7427
4 changed files with 82 additions and 21 deletions

View File

@ -28,6 +28,7 @@ import com.orientechnologies.orient.core.db.ODatabaseSession;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument; import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.record.OIdentifiable; import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordLazySet; import com.orientechnologies.orient.core.db.record.ORecordLazySet;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.metadata.security.ORestrictedOperation; import com.orientechnologies.orient.core.metadata.security.ORestrictedOperation;
import com.orientechnologies.orient.core.metadata.security.ORole; import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.OSecurity; import com.orientechnologies.orient.core.metadata.security.OSecurity;
@ -322,6 +323,22 @@ public class SecurityContext {
oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName); oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName);
} }
public boolean isElementInContext(final OElement element) throws ResourceRegistryException {
ORID orid = element.getIdentity();
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument contextODatabaseDocument = getDatabaseDocument(PermissionMode.READER);
contextODatabaseDocument.activateOnCurrentThread();
ORecord oRecord = contextODatabaseDocument.getRecord(orid);
logger.trace("{}", oRecord);
if(current!=null) {
current.activateOnCurrentThread();
}
return true;
}
public void addElement(OElement element, ODatabaseDocument oDatabaseDocument) { public void addElement(OElement element, ODatabaseDocument oDatabaseDocument) {
ODocument oDocument = element.getRecord(); ODocument oDocument = element.getRecord();
OSecurity oSecurity = getOSecurity(oDatabaseDocument); OSecurity oSecurity = getOSecurity(oDatabaseDocument);

View File

@ -42,6 +42,7 @@ import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityCo
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode; import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment;
import org.gcube.informationsystem.resourceregistry.instances.base.properties.PropertyElementManagement; import org.gcube.informationsystem.resourceregistry.instances.base.properties.PropertyElementManagement;
import org.gcube.informationsystem.resourceregistry.instances.model.OperationValidator;
import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient; import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient;
import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility; import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility;
import org.gcube.informationsystem.resourceregistry.utils.Utility; import org.gcube.informationsystem.resourceregistry.utils.Utility;
@ -772,6 +773,11 @@ public abstract class ElementManagement<El extends OElement> {
public Map<UUID,JsonNode> addToContext(UUID contextUUID) public Map<UUID,JsonNode> addToContext(UUID contextUUID)
throws NotFoundException, ContextException, ResourceRegistryException { throws NotFoundException, ContextException, ResourceRegistryException {
return addToContext(contextUUID, null);
}
public Map<UUID,JsonNode> addToContext(UUID contextUUID, OperationValidator operationValidator)
throws NotFoundException, ContextException, ResourceRegistryException {
logger.info("Going to add {} with UUID {} to Context with UUID {}", accessType.getName(), uuid, contextUUID); logger.info("Going to add {} with UUID {} to Context with UUID {}", accessType.getName(), uuid, contextUUID);
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
try { try {
@ -782,7 +788,16 @@ public abstract class ElementManagement<El extends OElement> {
Map<UUID,JsonNode> affectedInstances = internalAddToContext(targetSecurityContext); Map<UUID,JsonNode> affectedInstances = internalAddToContext(targetSecurityContext);
oDatabaseDocument.commit(); if(honourPropagationConstraintsInContextSharing) {
oDatabaseDocument.commit();
}else {
if(operationValidator==null) {
throw new ResourceRegistryException("A removeFromContext operation which must not honour PropagationConstraints have to provide an " + OperationValidator.class.getSimpleName());
}
if(operationValidator.isValidOperation(affectedInstances)) {
oDatabaseDocument.commit();
}
}
logger.info("{} with UUID {} successfully added to Context with UUID {}", elementType, uuid, contextUUID); logger.info("{} with UUID {} successfully added to Context with UUID {}", elementType, uuid, contextUUID);
return affectedInstances; return affectedInstances;
@ -811,6 +826,11 @@ public abstract class ElementManagement<El extends OElement> {
public Map<UUID,JsonNode> removeFromContext(UUID contextUUID) public Map<UUID,JsonNode> removeFromContext(UUID contextUUID)
throws NotFoundException, ContextException, ResourceRegistryException { throws NotFoundException, ContextException, ResourceRegistryException {
return removeFromContext(contextUUID, null);
}
public Map<UUID,JsonNode> removeFromContext(UUID contextUUID, OperationValidator operationValidator)
throws NotFoundException, ContextException, ResourceRegistryException {
logger.debug("Going to remove {} with UUID {} from Context with UUID {}", elementType, uuid, contextUUID); logger.debug("Going to remove {} with UUID {} from Context with UUID {}", elementType, uuid, contextUUID);
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
try { try {
@ -821,7 +841,16 @@ public abstract class ElementManagement<El extends OElement> {
Map<UUID,JsonNode> affectedInstances = internalRemoveFromContext(targetSecurityContext); Map<UUID,JsonNode> affectedInstances = internalRemoveFromContext(targetSecurityContext);
oDatabaseDocument.commit(); if(honourPropagationConstraintsInContextSharing) {
oDatabaseDocument.commit();
}else {
if(operationValidator==null) {
throw new ResourceRegistryException("A removeFromContext operation which must not honour PropagationConstraints have to provide an " + OperationValidator.class.getSimpleName());
}
if(operationValidator.isValidOperation(affectedInstances)) {
oDatabaseDocument.commit();
}
}
logger.info("{} with UUID {} successfully removed from Context with UUID {}", elementType, uuid, contextUUID); logger.info("{} with UUID {} successfully removed from Context with UUID {}", elementType, uuid, contextUUID);
return affectedInstances; return affectedInstances;
@ -1219,4 +1248,12 @@ public abstract class ElementManagement<El extends OElement> {
} }
} }
public boolean isAvailableOnContext(OElement element, SecurityContext securityContext) {
try {
return securityContext.isElementInContext(element);
} catch (ResourceRegistryException e) {
return false;
}
}
} }

View File

@ -227,13 +227,15 @@ public abstract class EntityManagement<E extends EntityElement> extends EntityEl
Map<UUID,JsonNode> affectedInstances = new HashMap<>(); Map<UUID,JsonNode> affectedInstances = new HashMap<>();
Iterable<OEdge> edges = getElement().getEdges(ODirection.OUT); if(honourPropagationConstraintsInContextSharing) {
Iterable<OEdge> edges = getElement().getEdges(ODirection.OUT);
for(OEdge edge : edges) {
RelationManagement<?> relationManagement = getRelationManagement(edge); for(OEdge edge : edges) {
relationManagement.setDryRunContextSharing(dryRunContextSharing); RelationManagement<?> relationManagement = getRelationManagement(edge);
relationManagement.setHonourPropagationConstraintsInContextSharing(honourPropagationConstraintsInContextSharing); relationManagement.setDryRunContextSharing(dryRunContextSharing);
affectedInstances.putAll(relationManagement.internalRemoveFromContext(targetSecurityContext)); relationManagement.setHonourPropagationConstraintsInContextSharing(honourPropagationConstraintsInContextSharing);
affectedInstances.putAll(relationManagement.internalRemoveFromContext(targetSecurityContext));
}
} }
if(!dryRunContextSharing) { if(!dryRunContextSharing) {

View File

@ -105,25 +105,30 @@ public class SharingManager {
CalledMethodProvider.instance.set(calledMethod.toString()); CalledMethodProvider.instance.set(calledMethod.toString());
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
Map<UUID,JsonNode> affectedInstances = new HashMap<>();
ArrayNode arrayNode = (ArrayNode) objectMapper.readTree(body); ArrayNode arrayNode = (ArrayNode) objectMapper.readTree(body);
for(JsonNode node : arrayNode) {
Map<UUID,JsonNode> expectedInstances = new HashMap<>();
ElementManagement<?> elementManagement = null;
boolean first = true;
for(JsonNode node : arrayNode) {
String type = node.get(Element.CLASS_PROPERTY).asText(); String type = node.get(Element.CLASS_PROPERTY).asText();
String instanceId = node.get(IdentifiableElement.HEADER_PROPERTY).get(Header.UUID_PROPERTY).asText(); String instanceId = node.get(IdentifiableElement.HEADER_PROPERTY).get(Header.UUID_PROPERTY).asText();
UUID uuid = UUID.fromString(instanceId);
ElementManagement<?> elementManagement = ElementManagementUtility.getERManagement(type); expectedInstances.put(uuid, node);
elementManagement.setUUID(UUID.fromString(instanceId)); if(first) {
elementManagement.setDryRunContextSharing(dryRun); elementManagement = ElementManagementUtility.getERManagement(type);
elementManagement.setUUID(UUID.fromString(instanceId));
if(operation == SharingOperation.ADD) { first = false;
affectedInstances.putAll(elementManagement.addToContext(UUID.fromString(contextId)));
}else {
affectedInstances.putAll(elementManagement.removeFromContext(UUID.fromString(contextId)));
} }
} }
elementManagement.setHonourPropagationConstraintsInContextSharing(false);
elementManagement.setDryRunContextSharing(dryRun);
UUID contextUUID = UUID.fromString(contextId);
Map<UUID,JsonNode> affectedInstances = elementManagement.addToContext(contextUUID);
return serializeAffectedInstaces(objectMapper, affectedInstances); return serializeAffectedInstaces(objectMapper, affectedInstances);
}catch (ResourceRegistryException e) { }catch (ResourceRegistryException e) {
throw e; throw e;