package org.gcube.data.access.storagehub.services.delegates; import java.security.Principal; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.AccessControlEntry; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.gcube.common.storagehub.model.acls.ACL; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.gcube.data.access.storagehub.services.interfaces.ACLManagerInterface; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton public class ACLManagerDelegate implements ACLManagerInterface { @Inject Node2ItemConverter node2Item; private static final Logger log = LoggerFactory.getLogger(ACLManagerDelegate.class); @Override public List get(Item item, Session session) throws RepositoryException, BackendGenericError { List acls = new ArrayList<>(); if (!item.isShared()) return acls; Node toRetrieve = (Node) item.getRelatedNode(); if (!(item instanceof SharedFolder)) toRetrieve = retrieveSharedFolderParent(toRetrieve, session); JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, toRetrieve.getPath()); for (AccessControlEntry aclEntry : accessControlList.getAccessControlEntries()) { ACL acl = new ACL(); acl.setPricipal(aclEntry.getPrincipal().getName()); List types = new ArrayList<>(); for (Privilege priv : aclEntry.getPrivileges()) try { types.add(AccessType.fromValue(priv.getName())); }catch (Exception e) { log.warn(priv.getName()+" cannot be mapped to AccessTypes",e); } acl.setAccessTypes(types); acls.add(acl); } return acls; } private Node retrieveSharedFolderParent(Node node, Session session) throws BackendGenericError, RepositoryException{ if (node2Item.checkNodeType(node, SharedFolder.class)) return node; else return retrieveSharedFolderParent(node.getParent(), session); } @Override public void update(String targetUser, SharedFolder folder, AccessType accessType, Session session) throws RepositoryException, StorageHubException { AccessControlManager acm = session.getAccessControlManager(); JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, folder.getPath()); Principal principal = AccessControlUtils.getPrincipal(session, targetUser); _remove(acls, principal); Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(accessType.getValue()) }; acls.addAccessControlEntry(principal, userPrivileges); acm.setPolicy(folder.getPath(), acls); session.save(); } @Override public void delete(String targetUser, SharedFolder folder, Session session) throws RepositoryException { AccessControlManager acm = session.getAccessControlManager(); JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, folder.getPath()); Principal principal = AccessControlUtils.getPrincipal(session, targetUser); _remove(acls, principal); acm.setPolicy(folder.getPath(), acls); } private void _remove(JackrabbitAccessControlList acls, Principal principal) throws RepositoryException { AccessControlEntry aceToDelete = null; for (AccessControlEntry ace : acls.getAccessControlEntries()) if (ace.getPrincipal().equals(principal)) { aceToDelete = ace; break; } if (aceToDelete!= null) acls.removeAccessControlEntry(aceToDelete); } }