diff --git a/.gitignore b/.gitignore index 271e5e1..e7a3ebc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ target .project /.DS_Store /bin/ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/.settings/.gitignore b/.settings/.gitignore index 1de83a6..817d634 100644 --- a/.settings/.gitignore +++ b/.settings/.gitignore @@ -1,3 +1,4 @@ /org.eclipse.core.resources.prefs /org.eclipse.jdt.core.prefs /org.eclipse.m2e.core.prefs +/org.eclipse.jdt.apt.core.prefs diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/contexts/entities/ContextManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/contexts/entities/ContextManagement.java index d72c1bf..88fb42d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/contexts/entities/ContextManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/contexts/entities/ContextManagement.java @@ -5,9 +5,12 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; +import javax.ws.rs.BadRequestException; import javax.ws.rs.ForbiddenException; +import javax.ws.rs.NotAuthorizedException; import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; import org.gcube.com.fasterxml.jackson.databind.JsonNode; @@ -245,8 +248,37 @@ public class ContextManagement extends EntityElementManagement allowedRoles = SecurityContext.getAllowedRoles(); + if(!SecurityContext.isUserAllowed(allowedRoles)) { + throw new NotAuthorizedException("Only user with one of the following role " + allowedRoles + " can create a child Context."); + } + }else { + Set allowedRoles = SecurityContext.getAllOperationsAllowedRoles(); + if(!SecurityContext.isUserAllowed(allowedRoles)) { + throw new NotAuthorizedException("Only user with one of the following role " + allowedRoles + " can create a child Context requesting the operation from a Context which is not the parent."); + } + } + + checkContext(parentContextManagement); if (uuid == null) { uuid = UUIDManager.getInstance().generateValidUUID(); @@ -279,6 +325,7 @@ public class ContextManagement extends EntityElementManagement iterable = getElement().getEdges(ODirection.OUT); @@ -591,7 +638,7 @@ public class ContextManagement extends EntityElementManagement allowedRoles; - - public final static String CONTEXT_MANAGER = "Context-Manager"; + protected static Set allOperationAllowedRoles; + //protected static Set allowedRoles; + public final static String INFRASTRUCTURE_MANAGER = "Infrastructure-Manager"; public final static String IS_MANAGER = "IS-Manager"; + public final static String CONTEXT_MANAGER = "Context-Manager"; + + static { + allOperationAllowedRoles = new HashSet<>(); + allOperationAllowedRoles.add(INFRASTRUCTURE_MANAGER); + allOperationAllowedRoles.add(IS_MANAGER); + +// allowedRoles = new HashSet<>(); +// allowedRoles.add(CONTEXT_MANAGER); + } + + public static Set getAllOperationsAllowedRoles() { + return new HashSet<>(allOperationAllowedRoles); + } + +// public static Set getAllowedRoles() { +// return new HashSet<>(allowedRoles); +// } + protected SecurityContext(UUID context, boolean hierarchical) throws ResourceRegistryException { this.context = context; this.poolMap = new HashMap<>(); - this.allowedRoles = new HashSet<>(); - this.allowedRoles.add(INFRASTRUCTURE_MANAGER); - this.allowedRoles.add(IS_MANAGER); + + boolean hierarchicalAllowed = SecurityContext.isUserAllowed(allOperationAllowedRoles); + /* - * Only Infrastructure-Manager and IS-Manager - * are entitled to use hierarchical mode. - * I decide not complains for that instead - * assume the hierarchical was not requested + * 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 && !isUserAllowed()) { + 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 fllowing roles "); - sb.append(allowedRoles.toString()); + 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 && isUserAllowed(); + this.hierarchical = hierarchical && hierarchicalAllowed; this.children = new HashSet<>(); @@ -135,10 +153,6 @@ public class SecurityContext { this(context, true); } - public Set getAllowedRoles() { - return allowedRoles; - } - protected boolean isHierarchicalMode() { return hierarchical || RequestUtility.getRequestInfo().get().isHierarchicalMode(); } @@ -477,33 +491,67 @@ public class SecurityContext { } + private static boolean isUserAllowed(Set allowedRoles) { + boolean allowed = false; + SecretManager secretManager = SecretManagerProvider.instance.get(); + User user = secretManager.getUser(); + Collection roles = new HashSet<>(user.getRoles()); + roles.retainAll(allowedRoles); + if(roles.size()>0) { + allowed = true; + } + return allowed; + } + + public boolean isUserAllowed() { boolean allowed = false; SecretManager secretManager = SecretManagerProvider.instance.get(); User user = secretManager.getUser(); Collection roles = new HashSet<>(user.getRoles()); - roles.retainAll(this.allowedRoles); + roles.retainAll(allowedRoles); if(roles.size()>0) { allowed = true; } - - - /* - * The Context-Manager is allowed to operate in a context - * only if he is the Context-Manager of the context - */ - - // TODO in subclass - - /* - * The Context-Manager is allowed to delete a context - * only if he is the Context-Manager of the parent context - * (so the request must arrive from the parent context). - */ - return allowed; } + public boolean isUserAllowed(Operation operation) { + switch (operation) { + case CREATE: + break; + + case READ: + break; + + case EXISTS: + break; + + case UPDATE: + break; + + case DELETE: + break; + + case ADD_TO_CONTEXT: + break; + + case REMOVE_FROM_CONTEXT: + break; + + case QUERY: + break; + + case GET_METADATA: + return isUserAllowed(allOperationAllowedRoles); + + default: + break; + } + + return true; + } + public void create() throws ResourceRegistryException { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); ODatabaseDocument adminDatabaseDocument = null; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java index 6609fa0..a049dfb 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java @@ -262,7 +262,7 @@ public abstract class ElementManagement { Context context = ServerContextCache.getInstance().getContextByUUID(workingContext.getUUID()); if(context.getState().compareTo(ContextState.ACTIVE.getState())!=0) { if(!workingContext.isUserAllowed()) { - throw new ForbiddenException("You are not allowed to operate in non " + ContextState.ACTIVE.getState() + " Contexts. Allowed roles are " + workingContext.getAllowedRoles()); + throw new ForbiddenException("You are not allowed to operate in non " + ContextState.ACTIVE.getState() + " Contexts. Allowed roles are " + SecurityContext.getAllOperationsAllowedRoles()); } } } @@ -734,17 +734,20 @@ public abstract class ElementManagement { throws NotFoundException, AvailableInAnotherContextException, ResourceRegistryException { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { - oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.WRITER); + SecurityContext securityContext = getWorkingContext(); + oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.WRITER); oDatabaseDocument.begin(); boolean update = false; setAsEntryPoint(); + setOperation(Operation.UPDATE); try { getElement(); - setOperation(Operation.UPDATE); + securityContext.isUserAllowed(operation); update = true; internalUpdate(); } catch(NotFoundException e) { setOperation(Operation.CREATE); + securityContext.isUserAllowed(operation); String calledMethod = CalledMethodProvider.instance.get(); calledMethod = calledMethod.replace("update", "create"); CalledMethodProvider.instance.set(calledMethod); @@ -788,7 +791,9 @@ public abstract class ElementManagement { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { - oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.WRITER); + SecurityContext securityContext = getWorkingContext(); + securityContext.isUserAllowed(Operation.CREATE); + oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.WRITER); oDatabaseDocument.begin(); setAsEntryPoint(); @@ -827,10 +832,12 @@ public abstract class ElementManagement { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { - oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.READER); + SecurityContext securityContext = getWorkingContext(); + setOperation(Operation.READ); + securityContext.isUserAllowed(operation); + oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.READER); setAsEntryPoint(); - setOperation(Operation.READ); getElement(); @@ -853,10 +860,11 @@ public abstract class ElementManagement { } public String update() throws NotFoundException, AvailableInAnotherContextException, ResourceRegistryException { - ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { - oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.WRITER); + SecurityContext securityContext = getWorkingContext(); + securityContext.isUserAllowed(Operation.UPDATE); + oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.WRITER); oDatabaseDocument.begin(); setAsEntryPoint(); @@ -898,7 +906,10 @@ public abstract class ElementManagement { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { // oDatabaseDocument = ContextUtility.getAdminSecurityContext().getDatabaseDocument(PermissionMode.WRITER); - oDatabaseDocument = getWorkingContext().getDatabaseDocument(PermissionMode.WRITER); + SecurityContext securityContext = getWorkingContext(); + setOperation(Operation.DELETE); + securityContext.isUserAllowed(operation); + oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.WRITER); oDatabaseDocument.begin(); setAsEntryPoint(); @@ -939,10 +950,11 @@ public abstract class ElementManagement { ODatabaseDocument instanceDB = this.oDatabaseDocument; try { AdminSecurityContext adminSecurityContext = ContextUtility.getAdminSecurityContext(); + setOperation(Operation.GET_METADATA); + adminSecurityContext.isUserAllowed(operation); oDatabaseDocument = adminSecurityContext.getDatabaseDocument(PermissionMode.READER); setAsEntryPoint(); - setOperation(Operation.GET_METADATA); Set contexts = SecurityContext.getContexts(getElement()); return contexts; @@ -1249,7 +1261,7 @@ public abstract class ElementManagement { if(roles.contains(SecurityContext.CONTEXT_MANAGER)) { return true; } - roles.retainAll(workingContext.getAllowedRoles()); + roles.retainAll(SecurityContext.getAllOperationsAllowedRoles()); if(roles.size()>0) { allowed = true; }