storagehub/src/main/java/org/gcube/data/access/storagehub/services/delegates/ACLManagerDelegate.java

108 lines
4.0 KiB
Java

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<ACL> get(Item item, Session session) throws RepositoryException, BackendGenericError {
List<ACL> 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<AccessType> 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);
}
}