Reorganized environments

This commit is contained in:
Luca Frosini 2024-10-23 12:33:36 +02:00
parent dafc4e5639
commit d9cc910fa9
14 changed files with 505 additions and 380 deletions

View File

@ -194,7 +194,7 @@ public class ContextUtility {
if(parentVertex != null) {
UUID parentUUID = UUIDUtility.getUUID(parentVertex);
securityContext.setParentSecurityContext(getEnvironmentByUUID(parentUUID, parentVertex));
securityContext.setParentEnvironment(getEnvironmentByUUID(parentUUID, parentVertex));
}
} catch(NoSuchElementException e) {

View File

@ -279,7 +279,7 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
@Override
protected OVertex reallyCreate() throws AlreadyPresentException, ResourceRegistryException {
InstanceEnvironment newInstanceEnvironment = null;
SystemEnvironment parentInstanceEnvironment = null;
InstanceEnvironment parentInstanceEnvironment = null;
try {
JsonNode isParentOfJsonNode = jsonNode.get(Context.PARENT_PROPERTY);
@ -336,7 +336,7 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
newInstanceEnvironment = new InstanceEnvironment(uuid);
newInstanceEnvironment.setParentSecurityContext(parentInstanceEnvironment);
newInstanceEnvironment.setParentEnvironment(parentInstanceEnvironment);
newInstanceEnvironment.create(oDatabaseDocument);
ContextUtility.getInstance().addSecurityContext(newInstanceEnvironment);
@ -460,7 +460,7 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
checkContext(newParentContextManagement);
}
SystemEnvironment newParentSecurityContext = null;
InstanceEnvironment newParentInstanceEnvironment = null;
// Removing the old parent relationship if any
Iterable<OEdge> edges = getElement().getEdges(ODirection.IN, IsParentOf.NAME);
@ -484,12 +484,12 @@ public class ContextManagement extends EntityElementManagement<Context, EntityTy
isParentOfManagement.setSourceEntityManagement(newParentContextManagement);
isParentOfManagement.setTargetEntityManagement(this);
isParentOfManagement.internalCreate();
newParentSecurityContext = ContextUtility.getInstance()
newParentInstanceEnvironment = ContextUtility.getInstance()
.getEnvironmentByUUID(newParentContextManagement.uuid);
}
SystemEnvironment thisSecurityContext = ContextUtility.getInstance().getEnvironmentByUUID(uuid);
thisSecurityContext.changeParentSecurityContext(newParentSecurityContext, oDatabaseDocument);
InstanceEnvironment thisInstanceEnvironment = ContextUtility.getInstance().getEnvironmentByUUID(uuid);
thisInstanceEnvironment.changeParentEnvironment(newParentInstanceEnvironment, oDatabaseDocument);
}
@Override

View File

@ -36,14 +36,9 @@ public class AdminEnvironment extends SystemEnvironment {
}
private AdminEnvironment() throws ResourceRegistryException {
super(ADMIN_SECURITY_CONTEXT_UUID, false);
super(ADMIN_SECURITY_CONTEXT_UUID);
}
// @Override
// protected boolean isHierarchicalMode() {
// return false;
// }
@Override
public void create() {
throw new RuntimeException("Cannot use this method for Admin Context");

View File

@ -34,13 +34,9 @@ public class ContextEnvironment extends SystemEnvironment {
}
private ContextEnvironment() throws ResourceRegistryException {
super(CONTEXT_SECURITY_CONTEXT_UUID, false);
super(CONTEXT_SECURITY_CONTEXT_UUID);
}
@Override
protected boolean isHierarchicalMode() {
return false;
}
@Override
protected ORole addExtraRules(ORole role, PermissionMode permissionMode) {

View File

@ -0,0 +1,434 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.environments;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment;
import org.gcube.informationsystem.resourceregistry.requests.RequestUtility;
import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo;
import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility;
import org.gcube.informationsystem.utils.UUIDManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.orientechnologies.orient.core.db.ODatabasePool;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordLazySet;
import com.orientechnologies.orient.core.metadata.security.ORestrictedOperation;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.metadata.security.OSecurityRole.ALLOW_MODES;
import com.orientechnologies.orient.core.metadata.security.OUser;
import com.orientechnologies.orient.core.record.OElement;
import com.orientechnologies.orient.core.record.impl.ODocument;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public abstract class HierarchicEnvironment extends SystemEnvironment {
private static Logger logger = LoggerFactory.getLogger(HierarchicEnvironment.class);
/*
* H stand for Hierarchical
*/
public static final String H = "H";
protected final boolean hierarchical;
protected final Map<PermissionMode,ODatabasePool> hierarchicPoolMap;
protected HierarchicEnvironment parentEnvironment;
protected Set<HierarchicEnvironment> children;
public HierarchicEnvironment(UUID uuid) throws ResourceRegistryException {
super(uuid);
this.hierarchicPoolMap = new HashMap<>();
boolean hierarchicalAllowed = isUserAllowed(SystemEnvironment.getAllOperationsAllowedRoles());
/*
* Only the Infrastructure Manager and IS Manager are entitled to use hierarchical mode.
* I decided not to complain if the user does not have such roles and assumed the hierarchical mode was not requested.
*/
if(!hierarchicalAllowed) {
StringBuffer sb = new StringBuffer();
sb.append("The user ");
sb.append(ContextUtility.getCurrentUserUsername());
sb.append(" requested hierarchical mode but he/she does not have one of the following roles ");
sb.append(allOperationAllowedRoles.toString());
sb.append(". Instead of complaining, the request will be elaborated not in hierarchical mode.");
logger.warn(sb.toString());
}
this.hierarchical = hierarchicalAllowed;
this.children = new HashSet<>();
}
protected boolean isHierarchicalMode() {
return hierarchical || RequestUtility.getRequestInfo().get().isHierarchicalMode();
}
public void setParentEnvironment(HierarchicEnvironment parentEnvironment) {
if(this.parentEnvironment!=null) {
this.parentEnvironment.getChildren().remove(this);
}
this.parentEnvironment = parentEnvironment;
if(parentEnvironment!=null) {
this.parentEnvironment.addChild(this);
}
}
public HierarchicEnvironment getParentEnvironment() {
return parentEnvironment;
}
private void addChild(HierarchicEnvironment child) {
this.children.add(child);
}
public Set<HierarchicEnvironment> getChildren(){
return this.children;
}
/**
* @return a set containing all children and recursively
* all children.
*/
private Set<HierarchicEnvironment> getAllChildren(){
Set<HierarchicEnvironment> allChildren = new HashSet<>();
allChildren.add(this);
for(HierarchicEnvironment securityContext : getChildren()) {
allChildren.addAll(securityContext.getAllChildren());
}
return allChildren;
}
/**
* @return
*/
private Set<HierarchicEnvironment> getAllParents(){
Set<HierarchicEnvironment> allParents = new HashSet<>();
HierarchicEnvironment parent = getParentEnvironment();
while(parent!=null) {
allParents.add(parent);
parent = parent.getParentEnvironment();
}
return allParents;
}
/**
* Use to change the parent not to set the first time
*
* @param newParentSecurityContext
* @param orientGraph
* @throws ResourceRegistryException
*/
public void changeParentEnvironment(HierarchicEnvironment newParentSecurityContext, ODatabaseDocument orientGraph) throws ResourceRegistryException {
if(!hierarchical) {
StringBuilder errorMessage = new StringBuilder();
errorMessage.append("Cannot change parent ");
errorMessage.append(HierarchicEnvironment.class.getSimpleName());
errorMessage.append(" to non hierarchic ");
errorMessage.append(HierarchicEnvironment.class.getSimpleName());
errorMessage.append(". ");
errorMessage.append(OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
final String error = errorMessage.toString();
logger.error(error);
throw new RuntimeException(error);
}
OSecurity oSecurity = getOSecurity(orientGraph);
Set<HierarchicEnvironment> allChildren = getAllChildren();
Set<HierarchicEnvironment> oldParents = getAllParents();
Set<HierarchicEnvironment> newParents = new HashSet<>();
if(newParentSecurityContext!=null) {
newParents = newParentSecurityContext.getAllParents();
}
/*
* From old parents I remove the new parents so that oldParents
* contains only the parents where I have to remove all
* HReaderRole-UUID e HWriterRole-UUID of allChildren by using
* removeHierarchicRoleFromParent() function
*
*/
oldParents.removeAll(newParents);
removeChildrenHRolesFromParents(oSecurity, oldParents, allChildren);
setParentEnvironment(newParentSecurityContext);
if(newParentSecurityContext!=null){
for(PermissionMode permissionMode : PermissionMode.values()) {
List<ORole> roles = new ArrayList<>();
for(HierarchicEnvironment child : allChildren) {
String roleName = child.getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, true);
ORole role = oSecurity.getRole(roleName);
roles.add(role);
}
newParentSecurityContext.addHierarchicalRoleToParent(oSecurity, permissionMode, roles.toArray(new ORole[allChildren.size()]));
}
}
}
@Override
protected synchronized ODatabasePool getPool(PermissionMode permissionMode, boolean recreate) {
ODatabasePool pool = null;
Boolean h = hierarchical || RequestUtility.getRequestInfo().get().isHierarchicalMode();
Map<PermissionMode,ODatabasePool> pools = h ? hierarchicPoolMap : poolMap;
if(recreate) {
pool = pools.get(permissionMode);
if(pool!=null) {
pool.close();
pools.remove(permissionMode);
}
}
pool = pools.get(permissionMode);
if(pool == null) {
String username = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, h);
String password = DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode);
pool = new ODatabasePool(DatabaseEnvironment.DB_URI, username, password);
pools.put(permissionMode, pool);
}
return pool;
}
public static String getRoleOrUserName(PermissionMode permissionMode, SecurityType securityType) {
return getRoleOrUserName(permissionMode, securityType, false);
}
public static String getRoleOrUserName(PermissionMode permissionMode, SecurityType securityType,
boolean hierarchic) {
StringBuilder stringBuilder = new StringBuilder();
if(hierarchic) {
stringBuilder.append(H);
}
stringBuilder.append(permissionMode);
stringBuilder.append(securityType);
return stringBuilder.toString();
}
public String getSecurityRoleOrUserName(PermissionMode permissionMode, SecurityType securityType,
boolean hierarchic) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(getRoleOrUserName(permissionMode, securityType, hierarchic));
stringBuilder.append("_");
stringBuilder.append(environmentUUID.toString());
return stringBuilder.toString();
}
private OSecurity getOSecurity(ODatabaseDocument oDatabaseDocument) {
return oDatabaseDocument.getMetadata().getSecurity();
}
public static Set<String> getContexts(OElement element) {
Set<String> contexts = new HashSet<>();
ORecordLazySet oRecordLazySet = element.getProperty(OSecurity.ALLOW_ALL_FIELD);
for (OIdentifiable oIdentifiable : oRecordLazySet) {
ODocument oDocument = (ODocument) oIdentifiable;
String name = oDocument.getProperty("name");
if (name.startsWith(getRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE))
|| name.startsWith(getRoleOrUserName(PermissionMode.READER, SecurityType.ROLE))) {
String[] list = name.split("_");
if (list.length == 2) {
String contextUUID = list[1];
if (!UUIDManager.getInstance().isReservedUUID(contextUUID)) {
contexts.add(contextUUID);
}
}
}
}
return contexts;
}
protected void allow(OSecurity oSecurity, ODocument oDocument, boolean hierarchic) {
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE, hierarchic);
oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_ALL, writerRoleName);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE, hierarchic);
oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName);
}
@Override
public void addElement(OElement element, ODatabaseDocument oDatabaseDocument) {
ODocument oDocument = element.getRecord();
OSecurity oSecurity = getOSecurity(oDatabaseDocument);
allow(oSecurity, oDocument, false);
if(hierarchical) {
allow(oSecurity, oDocument, true);
}
oDocument.save();
element.save();
}
protected void deny(OSecurity oSecurity, ODocument oDocument, boolean hierarchical) {
// The element could be created in such a context so the writerUser for the
// context is allowed by default because it was the creator
String writerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER, hierarchical);
oSecurity.denyUser(oDocument, ORestrictedOperation.ALLOW_ALL, writerUserName);
String readerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER, hierarchical);
oSecurity.denyUser(oDocument, ORestrictedOperation.ALLOW_READ, readerUserName);
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE, hierarchical);
oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_ALL, writerRoleName);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE, hierarchical);
oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName);
}
@Override
public void removeElement(OElement element, ODatabaseDocument oDatabaseDocument) {
ODocument oDocument = element.getRecord();
OSecurity oSecurity = getOSecurity(oDatabaseDocument);
deny(oSecurity, oDocument, false);
if(hierarchical) {
deny(oSecurity, oDocument, true);
}
oDocument.save();
element.save();
}
@Override
protected boolean allowed(final ORole role, final ODocument oDocument) {
ServerRequestInfo sri = RequestUtility.getRequestInfo().get();
Boolean hm = sri.isHierarchicalMode();
sri.setHierarchicalMode(false);
try {
return super.allowed(role, oDocument);
}finally {
sri.setHierarchicalMode(hm);
}
}
protected void addHierarchicalRoleToParent(OSecurity oSecurity, PermissionMode permissionMode, ORole... roles) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
for(ORole role : roles) {
user.addRole(role);
}
user.save();
if(getParentEnvironment() != null) {
getParentEnvironment().addHierarchicalRoleToParent(oSecurity, permissionMode, roles);
}
}
protected void createRolesAndUsers(OSecurity oSecurity) {
boolean[] booleanArray;
if(hierarchical) {
booleanArray = new boolean[] {false, true};
} else {
booleanArray = new boolean[] {false};
}
for(boolean hierarchical : booleanArray) {
for(PermissionMode permissionMode : PermissionMode.values()) {
ORole superRole = getSuperRole(oSecurity, permissionMode);
String roleName = getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, hierarchical);
ORole role = oSecurity.createRole(roleName, superRole, ALLOW_MODES.DENY_ALL_BUT);
addExtraRules(role, permissionMode);
role.save();
logger.trace("{} created", role);
if(hierarchical && getParentEnvironment() != null) {
getParentEnvironment().addHierarchicalRoleToParent(oSecurity, permissionMode, role);
}
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, hierarchical);
OUser user = oSecurity.createUser(userName, DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode),
role);
user.save();
logger.trace("{} created", user);
}
}
}
protected void removeChildrenHRolesFromParents(OSecurity oSecurity) {
Set<HierarchicEnvironment> parents = getAllParents();
Set<HierarchicEnvironment> allChildren = getAllChildren();
removeChildrenHRolesFromParents(oSecurity, parents, allChildren);
}
protected void removeChildrenHRolesFromParents(OSecurity oSecurity, Set<HierarchicEnvironment> parents, Set<HierarchicEnvironment> children) {
for(HierarchicEnvironment parent : parents) {
parent.removeChildrenHRolesFromMyHUsers(oSecurity, children);
}
}
protected void removeChildrenHRolesFromMyHUsers(OSecurity oSecurity, Set<HierarchicEnvironment> children) {
for(PermissionMode permissionMode : PermissionMode.values()) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
for(HierarchicEnvironment child : children) {
String roleName = child.getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, true);
logger.debug("Going to remove {} from {}", roleName, userName);
boolean removed = user.removeRole(roleName);
logger.trace("{} {} removed from {}", roleName, removed ? "successfully" : "NOT", userName);
}
user.save();
}
}
protected void removeHierarchicRoleFromMyHUser(OSecurity oSecurity, PermissionMode permissionMode, String roleName) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
logger.debug("Going to remove {} from {}", roleName, userName);
boolean removed = user.removeRole(roleName);
logger.trace("{} {} removed from {}", roleName, removed ? "successfully" : "NOT", userName);
user.save();
}
protected void deleteRolesAndUsers(OSecurity oSecurity) {
boolean[] booleanArray;
if(hierarchical) {
booleanArray = new boolean[] {false, true};
} else {
booleanArray = new boolean[] {false};
}
for(boolean hierarchic : booleanArray) {
if(hierarchic) {
removeChildrenHRolesFromParents(oSecurity);
}
for(PermissionMode permissionMode : PermissionMode.values()) {
for(SecurityType securityType : SecurityType.values()) {
String name = getSecurityRoleOrUserName(permissionMode, securityType, hierarchic);
drop(oSecurity, name, securityType);
}
}
}
}
}

View File

@ -3,18 +3,14 @@ package org.gcube.informationsystem.resourceregistry.environments;
import java.util.UUID;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class InstanceEnvironment extends SystemEnvironment {
private static Logger logger = LoggerFactory.getLogger(InstanceEnvironment.class);
public class InstanceEnvironment extends HierarchicEnvironment {
public InstanceEnvironment(UUID uuid) throws ResourceRegistryException {
super(uuid, true);
super(uuid);
}
}

View File

@ -34,12 +34,7 @@ public class QueryTemplateEnvironment extends SystemEnvironment {
}
private QueryTemplateEnvironment() throws ResourceRegistryException {
super(QUERY_TEMPLATES_SECURITY_CONTEXT_UUID, false);
}
@Override
protected boolean isHierarchicalMode() {
return false;
super(QUERY_TEMPLATES_SECURITY_CONTEXT_UUID);
}
@Override

View File

@ -37,12 +37,7 @@ public class ShadowContextEnvironment extends SystemEnvironment {
}
private ShadowContextEnvironment() throws ResourceRegistryException {
super(SHADOW_CONTEXT_SECURITY_CONTEXT_UUID, false);
}
@Override
protected boolean isHierarchicalMode() {
return false;
super(SHADOW_CONTEXT_SECURITY_CONTEXT_UUID);
}
@Override

View File

@ -3,11 +3,9 @@
*/
package org.gcube.informationsystem.resourceregistry.environments;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -15,23 +13,16 @@ import java.util.UUID;
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.contexts.reference.entities.Context;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment;
import org.gcube.informationsystem.resourceregistry.instances.model.Operation;
import org.gcube.informationsystem.resourceregistry.requests.RequestUtility;
import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo;
import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility;
import org.gcube.informationsystem.utils.UUIDManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.orientechnologies.orient.core.db.ODatabasePool;
import com.orientechnologies.orient.core.db.ODatabaseSession;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
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.ORole;
@ -52,13 +43,6 @@ public abstract class SystemEnvironment {
protected static final String DEFAULT_WRITER_ROLE = "writer";
protected static final String DEFAULT_READER_ROLE = "reader";
/*
* H stand for Hierarchical
*/
public static final String H = "H";
protected final boolean hierarchical;
public enum SecurityType {
ROLE("Role"), USER("User");
@ -89,11 +73,7 @@ public abstract class SystemEnvironment {
protected final UUID environmentUUID;
protected final Map<Boolean,Map<PermissionMode,ODatabasePool>> poolMap;
protected SystemEnvironment parentSecurityContext;
protected Set<SystemEnvironment> children;
protected final Map<PermissionMode,ODatabasePool> poolMap;
/**
* Roles allowed to operate on the security context
@ -120,179 +100,37 @@ public abstract class SystemEnvironment {
return new HashSet<>(allowedRoles);
}
protected SystemEnvironment(UUID context, boolean hierarchical) throws ResourceRegistryException {
protected SystemEnvironment(UUID context) throws ResourceRegistryException {
this.environmentUUID = context;
this.poolMap = new HashMap<>();
this.allowedRoles = new HashSet<>(SystemEnvironment.allOperationAllowedRoles);
this.allowedRoles.add(CONTEXT_MANAGER);
boolean hierarchicalAllowed = SystemEnvironment.isUserAllowed(allOperationAllowedRoles);
/*
* Only the Infrastructure Manager and IS Manager are entitled to use hierarchical mode.
* I decided not to complain if the user does not have such roles and assumed the hierarchical mode was not requested.
*/
if(hierarchical && !hierarchicalAllowed) {
StringBuffer sb = new StringBuffer();
sb.append("The user ");
sb.append(ContextUtility.getCurrentUserUsername());
sb.append(" requested hierarchical mode but he/she does not have one of the following roles ");
sb.append(allOperationAllowedRoles.toString());
sb.append(". Instead of complaining, the request will be elaborated not in hierarchical mode.");
logger.warn(sb.toString());
}
this.hierarchical = hierarchical && hierarchicalAllowed;
this.children = new HashSet<>();
}
protected boolean isHierarchicalMode() {
return hierarchical || RequestUtility.getRequestInfo().get().isHierarchicalMode();
}
public void setParentSecurityContext(SystemEnvironment parentSecurityContext) {
if(this.parentSecurityContext!=null) {
this.parentSecurityContext.getChildren().remove(this);
}
this.parentSecurityContext = parentSecurityContext;
if(parentSecurityContext!=null) {
this.parentSecurityContext.addChild(this);
}
}
public SystemEnvironment getParentSecurityContext() {
return parentSecurityContext;
}
private void addChild(SystemEnvironment child) {
this.children.add(child);
}
public Set<SystemEnvironment> getChildren(){
return this.children;
}
protected ODatabaseDocument getAdminDatabaseDocument() throws ResourceRegistryException {
return AdminEnvironment.getInstance().getDatabaseDocument(PermissionMode.WRITER);
}
/**
* @return a set containing all children and recursively
* all children.
*/
private Set<SystemEnvironment> getAllChildren(){
Set<SystemEnvironment> allChildren = new HashSet<>();
allChildren.add(this);
for(SystemEnvironment securityContext : getChildren()) {
allChildren.addAll(securityContext.getAllChildren());
}
return allChildren;
}
/**
* @return
*/
private Set<SystemEnvironment> getAllParents(){
Set<SystemEnvironment> allParents = new HashSet<>();
SystemEnvironment parent = getParentSecurityContext();
while(parent!=null) {
allParents.add(parent);
parent = parent.getParentSecurityContext();
}
return allParents;
}
/**
* Use to change the parent not to set the first time
*
* @param newParentSecurityContext
* @param orientGraph
* @throws ResourceRegistryException
*/
public void changeParentSecurityContext(SystemEnvironment newParentSecurityContext, ODatabaseDocument orientGraph) throws ResourceRegistryException {
if(!hierarchical) {
StringBuilder errorMessage = new StringBuilder();
errorMessage.append("Cannot change parent ");
errorMessage.append(SystemEnvironment.class.getSimpleName());
errorMessage.append(" to non hierarchic ");
errorMessage.append(SystemEnvironment.class.getSimpleName());
errorMessage.append(". ");
errorMessage.append(OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
final String error = errorMessage.toString();
logger.error(error);
throw new RuntimeException(error);
}
OSecurity oSecurity = getOSecurity(orientGraph);
Set<SystemEnvironment> allChildren = getAllChildren();
Set<SystemEnvironment> oldParents = getAllParents();
Set<SystemEnvironment> newParents = new HashSet<>();
if(newParentSecurityContext!=null) {
newParents = newParentSecurityContext.getAllParents();
}
/*
* From old parents I remove the new parents so that oldParents
* contains only the parents where I have to remove all
* HReaderRole-UUID e HWriterRole-UUID of allChildren by using
* removeHierarchicRoleFromParent() function
*
*/
oldParents.removeAll(newParents);
removeChildrenHRolesFromParents(oSecurity, oldParents, allChildren);
setParentSecurityContext(newParentSecurityContext);
if(newParentSecurityContext!=null){
for(PermissionMode permissionMode : PermissionMode.values()) {
List<ORole> roles = new ArrayList<>();
for(SystemEnvironment child : allChildren) {
String roleName = child.getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, true);
ORole role = oSecurity.getRole(roleName);
roles.add(role);
}
newParentSecurityContext.addHierarchicalRoleToParent(oSecurity, permissionMode, roles.toArray(new ORole[allChildren.size()]));
}
}
}
private synchronized ODatabasePool getPool(PermissionMode permissionMode, boolean recreate) {
protected synchronized ODatabasePool getPool(PermissionMode permissionMode, boolean recreate) {
ODatabasePool pool = null;
Boolean h = hierarchical || RequestUtility.getRequestInfo().get().isHierarchicalMode();
Map<PermissionMode,ODatabasePool> pools = poolMap.get(h);
if(pools == null) {
pools = new HashMap<>();
poolMap.put(h, pools);
} else {
if(recreate) {
pool = pools.get(permissionMode);
pool = poolMap.get(permissionMode);
if(pool!=null) {
pool.close();
pools.remove(permissionMode);
}
poolMap.remove(permissionMode);
}
}
pool = pools.get(permissionMode);
pool = poolMap.get(permissionMode);
if(pool == null) {
String username = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, h);
String username = getSecurityRoleOrUserName(permissionMode, SecurityType.USER);
String password = DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode);
pool = new ODatabasePool(DatabaseEnvironment.DB_URI, username, password);
pools.put(permissionMode, pool);
poolMap.put(permissionMode, pool);
}
return pool;
@ -303,24 +141,15 @@ public abstract class SystemEnvironment {
}
public static String getRoleOrUserName(PermissionMode permissionMode, SecurityType securityType) {
return getRoleOrUserName(permissionMode, securityType, false);
}
public static String getRoleOrUserName(PermissionMode permissionMode, SecurityType securityType,
boolean hierarchic) {
StringBuilder stringBuilder = new StringBuilder();
if(hierarchic) {
stringBuilder.append(H);
}
stringBuilder.append(permissionMode);
stringBuilder.append(securityType);
return stringBuilder.toString();
}
public String getSecurityRoleOrUserName(PermissionMode permissionMode, SecurityType securityType,
boolean hierarchic) {
public String getSecurityRoleOrUserName(PermissionMode permissionMode, SecurityType securityType) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(getRoleOrUserName(permissionMode, securityType, hierarchic));
stringBuilder.append(getRoleOrUserName(permissionMode, securityType));
stringBuilder.append("_");
stringBuilder.append(environmentUUID.toString());
return stringBuilder.toString();
@ -330,32 +159,11 @@ public abstract class SystemEnvironment {
return oDatabaseDocument.getMetadata().getSecurity();
}
public static Set<String> getContexts(OElement element) {
Set<String> contexts = new HashSet<>();
ORecordLazySet oRecordLazySet = element.getProperty(OSecurity.ALLOW_ALL_FIELD);
for (OIdentifiable oIdentifiable : oRecordLazySet) {
ODocument oDocument = (ODocument) oIdentifiable;
String name = oDocument.getProperty("name");
if (name.startsWith(getRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE))
|| name.startsWith(getRoleOrUserName(PermissionMode.READER, SecurityType.ROLE))) {
String[] list = name.split("_");
if (list.length == 2) {
String contextUUID = list[1];
if (!UUIDManager.getInstance().isReservedUUID(contextUUID)) {
contexts.add(contextUUID);
}
}
}
}
return contexts;
}
public void addElement(OElement element) throws ResourceRegistryException {
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument adminDatabaseDocument = null;
try {
adminDatabaseDocument = getAdminDatabaseDocument();
adminDatabaseDocument = AdminEnvironment.getInstance().getDatabaseDocument(PermissionMode.WRITER);
addElement(element, adminDatabaseDocument);
}finally {
if(adminDatabaseDocument!=null) {
@ -368,10 +176,10 @@ public abstract class SystemEnvironment {
}
}
protected void allow(OSecurity oSecurity, ODocument oDocument, boolean hierarchic) {
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE, hierarchic);
protected void allow(OSecurity oSecurity, ODocument oDocument) {
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE);
oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_ALL, writerRoleName);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE, hierarchic);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE);
oSecurity.allowRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName);
}
@ -404,10 +212,7 @@ public abstract class SystemEnvironment {
public void addElement(OElement element, ODatabaseDocument oDatabaseDocument) {
ODocument oDocument = element.getRecord();
OSecurity oSecurity = getOSecurity(oDatabaseDocument);
allow(oSecurity, oDocument, false);
if(hierarchical) {
allow(oSecurity, oDocument, true);
}
allow(oSecurity, oDocument);
oDocument.save();
element.save();
}
@ -416,7 +221,7 @@ public abstract class SystemEnvironment {
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument adminDatabaseDocument = null;
try {
adminDatabaseDocument = getAdminDatabaseDocument();
adminDatabaseDocument = AdminEnvironment.getInstance().getDatabaseDocument(PermissionMode.WRITER);
removeElement(element, adminDatabaseDocument);
}finally {
if(adminDatabaseDocument!=null) {
@ -429,17 +234,17 @@ public abstract class SystemEnvironment {
}
}
protected void deny(OSecurity oSecurity, ODocument oDocument, boolean hierarchical) {
protected void deny(OSecurity oSecurity, ODocument oDocument) {
// The element could be created in such a context so the writerUser for the
// context is allowed by default because it was the creator
String writerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER, hierarchical);
String writerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER);
oSecurity.denyUser(oDocument, ORestrictedOperation.ALLOW_ALL, writerUserName);
String readerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER, hierarchical);
String readerUserName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.USER);
oSecurity.denyUser(oDocument, ORestrictedOperation.ALLOW_READ, readerUserName);
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE, hierarchical);
String writerRoleName = getSecurityRoleOrUserName(PermissionMode.WRITER, SecurityType.ROLE);
oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_ALL, writerRoleName);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE, hierarchical);
String readerRoleName = getSecurityRoleOrUserName(PermissionMode.READER, SecurityType.ROLE);
oSecurity.denyRole(oDocument, ORestrictedOperation.ALLOW_READ, readerRoleName);
}
@ -447,19 +252,12 @@ public abstract class SystemEnvironment {
public void removeElement(OElement element, ODatabaseDocument oDatabaseDocument) {
ODocument oDocument = element.getRecord();
OSecurity oSecurity = getOSecurity(oDatabaseDocument);
deny(oSecurity, oDocument, false);
if(hierarchical) {
deny(oSecurity, oDocument, true);
}
deny(oSecurity, oDocument);
oDocument.save();
element.save();
}
protected boolean allowed(final ORole role, final ODocument oDocument) {
ServerRequestInfo sri = RequestUtility.getRequestInfo().get();
Boolean hm = sri.isHierarchicalMode();
sri.setHierarchicalMode(false);
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument oDatabaseDocument = null;
try {
@ -473,7 +271,6 @@ public abstract class SystemEnvironment {
} catch(Exception e) {
return false;
} finally {
sri.setHierarchicalMode(hm);
if(oDatabaseDocument!=null) {
oDatabaseDocument.close();
@ -551,7 +348,7 @@ public abstract class SystemEnvironment {
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument adminDatabaseDocument = null;
try {
adminDatabaseDocument = getAdminDatabaseDocument();
adminDatabaseDocument = AdminEnvironment.getInstance().getDatabaseDocument(PermissionMode.WRITER);
create(adminDatabaseDocument);
@ -576,48 +373,22 @@ public abstract class SystemEnvironment {
return oSecurity.getRole(superRoleName);
}
protected void addHierarchicalRoleToParent(OSecurity oSecurity, PermissionMode permissionMode, ORole... roles) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
for(ORole role : roles) {
user.addRole(role);
}
user.save();
if(getParentSecurityContext() != null) {
getParentSecurityContext().addHierarchicalRoleToParent(oSecurity, permissionMode, roles);
}
}
protected void createRolesAndUsers(OSecurity oSecurity) {
boolean[] booleanArray;
if(hierarchical) {
booleanArray = new boolean[] {false, true};
} else {
booleanArray = new boolean[] {false};
}
for(boolean hierarchical : booleanArray) {
for(PermissionMode permissionMode : PermissionMode.values()) {
ORole superRole = getSuperRole(oSecurity, permissionMode);
String roleName = getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, hierarchical);
String roleName = getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE);
ORole role = oSecurity.createRole(roleName, superRole, ALLOW_MODES.DENY_ALL_BUT);
addExtraRules(role, permissionMode);
role.save();
logger.trace("{} created", role);
if(hierarchical && getParentSecurityContext() != null) {
getParentSecurityContext().addHierarchicalRoleToParent(oSecurity, permissionMode, role);
}
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, hierarchical);
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER);
OUser user = oSecurity.createUser(userName, DatabaseEnvironment.DEFAULT_PASSWORDS.get(permissionMode),
role);
user.save();
logger.trace("{} created", user);
}
}
}
@ -627,7 +398,7 @@ public abstract class SystemEnvironment {
logger.trace("Security Context (roles and users) with UUID {} successfully created", environmentUUID.toString());
}
private void drop(OSecurity oSecurity, String name, SecurityType securityType) {
protected void drop(OSecurity oSecurity, String name, SecurityType securityType) {
boolean dropped = false;
switch(securityType) {
case ROLE:
@ -652,7 +423,7 @@ public abstract class SystemEnvironment {
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
ODatabaseDocument adminDatabaseDocument = null;
try {
adminDatabaseDocument = getAdminDatabaseDocument();
adminDatabaseDocument = AdminEnvironment.getInstance().getDatabaseDocument(PermissionMode.WRITER);
delete(adminDatabaseDocument);
@ -669,61 +440,14 @@ public abstract class SystemEnvironment {
}
protected void removeChildrenHRolesFromParents(OSecurity oSecurity) {
Set<SystemEnvironment> parents = getAllParents();
Set<SystemEnvironment> allChildren = getAllChildren();
removeChildrenHRolesFromParents(oSecurity, parents, allChildren);
}
protected void removeChildrenHRolesFromParents(OSecurity oSecurity, Set<SystemEnvironment> parents, Set<SystemEnvironment> children) {
for(SystemEnvironment parent : parents) {
parent.removeChildrenHRolesFromMyHUsers(oSecurity, children);
}
}
protected void removeChildrenHRolesFromMyHUsers(OSecurity oSecurity, Set<SystemEnvironment> children) {
for(PermissionMode permissionMode : PermissionMode.values()) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
for(SystemEnvironment child : children) {
String roleName = child.getSecurityRoleOrUserName(permissionMode, SecurityType.ROLE, true);
logger.debug("Going to remove {} from {}", roleName, userName);
boolean removed = user.removeRole(roleName);
logger.trace("{} {} removed from {}", roleName, removed ? "successfully" : "NOT", userName);
}
user.save();
}
}
protected void removeHierarchicRoleFromMyHUser(OSecurity oSecurity, PermissionMode permissionMode, String roleName) {
String userName = getSecurityRoleOrUserName(permissionMode, SecurityType.USER, true);
OUser user = oSecurity.getUser(userName);
logger.debug("Going to remove {} from {}", roleName, userName);
boolean removed = user.removeRole(roleName);
logger.trace("{} {} removed from {}", roleName, removed ? "successfully" : "NOT", userName);
user.save();
}
protected void deleteRolesAndUsers(OSecurity oSecurity) {
boolean[] booleanArray;
if(hierarchical) {
booleanArray = new boolean[] {false, true};
} else {
booleanArray = new boolean[] {false};
}
for(boolean hierarchic : booleanArray) {
if(hierarchic) {
removeChildrenHRolesFromParents(oSecurity);
}
for(PermissionMode permissionMode : PermissionMode.values()) {
for(SecurityType securityType : SecurityType.values()) {
String name = getSecurityRoleOrUserName(permissionMode, securityType, hierarchic);
String name = getSecurityRoleOrUserName(permissionMode, securityType);
drop(oSecurity, name, securityType);
}
}
}
}
public void delete(ODatabaseDocument orientGraph) {
OSecurity oSecurity = getOSecurity(orientGraph);
@ -759,6 +483,7 @@ public abstract class SystemEnvironment {
@Override
public String toString() {
return String.format("%s %s", Context.NAME, getUUID().toString());
return String.format("%s %s", this.getClass().getSimpleName(), getUUID().toString());
}
}

View File

@ -34,12 +34,7 @@ public class TypeEnvironment extends SystemEnvironment {
}
private TypeEnvironment() throws ResourceRegistryException {
super(SCHEMA_SECURITY_CONTEXT_UUID, false);
}
@Override
protected boolean isHierarchicalMode() {
return false;
super(SCHEMA_SECURITY_CONTEXT_UUID);
}
@Override

View File

@ -48,6 +48,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaV
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
import org.gcube.informationsystem.resourceregistry.contexts.ServerContextCache;
import org.gcube.informationsystem.resourceregistry.environments.AdminEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.InstanceEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.SystemEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.SystemEnvironment.PermissionMode;
import org.gcube.informationsystem.resourceregistry.instances.base.properties.PropertyElementManagement;
@ -957,7 +958,7 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
setAsEntryPoint();
Set<String> contexts = SystemEnvironment.getContexts(getElement());
Set<String> contexts = InstanceEnvironment.getContexts(getElement());
return contexts;
} catch(ResourceRegistryException e) {
logger.error("Unable to get contexts for {} with UUID {}", typeName, uuid, e);

View File

@ -20,7 +20,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.Cont
import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextManagement;
import org.gcube.informationsystem.resourceregistry.environments.ContextEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.InstanceEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.SystemEnvironment;
import org.gcube.informationsystem.resourceregistry.environments.SystemEnvironment.PermissionMode;
import org.gcube.informationsystem.resourceregistry.environments.SystemEnvironment.SecurityType;
import org.gcube.informationsystem.resourceregistry.utils.MetadataUtility;
@ -112,20 +111,20 @@ public class ContextManagementTest extends ContextTest {
}
if(hierarchic) {
SystemEnvironment parent = null;
InstanceEnvironment parent = null;
if(deleted) {
if(oldParentUUID != null) {
parent = ContextUtility.getInstance().getEnvironmentByUUID(oldParentUUID);
}
}
parent = instanceEnvironment.getParentSecurityContext();
parent = (InstanceEnvironment) instanceEnvironment.getParentEnvironment();
while(parent != null) {
String parentUser = parent.getSecurityRoleOrUserName(permissionMode, SecurityType.USER,
hierarchic);
OUser parentOUser = oSecurity.getUser(parentUser);
Assert.assertTrue(parentOUser != null);
Assert.assertEquals(parentOUser.hasRole(oRole.getName(), false), !deleted);
parent = parent.getParentSecurityContext();
parent = (InstanceEnvironment) parent.getParentEnvironment();
}
}
@ -168,11 +167,11 @@ public class ContextManagementTest extends ContextTest {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setUUID(uuid);
SystemEnvironment securityContext = ContextUtility.getInstance().getEnvironmentByUUID(uuid);
InstanceEnvironment instanceEnvironment = ContextUtility.getInstance().getEnvironmentByUUID(uuid);
UUID oldParentUUID = null;
if(securityContext.getParentSecurityContext() != null) {
oldParentUUID = securityContext.getParentSecurityContext().getUUID();
if(instanceEnvironment.getParentEnvironment() != null) {
oldParentUUID = instanceEnvironment.getParentEnvironment().getUUID();
}
contextManagement.delete();

View File

@ -7,8 +7,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.BadRequestException;
import org.gcube.com.fasterxml.jackson.databind.JavaType;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;

View File

@ -14,26 +14,22 @@ import org.gcube.informationsystem.model.reference.entities.Entity;
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
import org.gcube.informationsystem.model.reference.properties.Encrypted;
import org.gcube.informationsystem.model.reference.properties.Event;
import org.gcube.informationsystem.model.reference.properties.Metadata;
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint;
import org.gcube.informationsystem.model.reference.properties.Property;
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
import org.gcube.informationsystem.model.reference.relations.IsRelatedTo;
import org.gcube.informationsystem.model.reference.relations.Relation;
import org.gcube.informationsystem.queries.templates.reference.properties.TemplateVariable;
import org.gcube.informationsystem.resourceregistry.ContextTest;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException;
import org.gcube.informationsystem.types.TypeMapper;
import org.gcube.informationsystem.types.reference.Type;
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
import org.gcube.informationsystem.types.reference.relations.RelationType;
import org.gcube.informationsystem.utils.Version;
import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.ContactFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.EventFacet;
import org.gcube.resourcemanagement.model.reference.entities.resources.Actor;
import org.gcube.resourcemanagement.model.reference.entities.resources.EService;
import org.gcube.resourcemanagement.model.reference.entities.resources.RunningPlugin;