storagehub/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java

212 lines
8.4 KiB
Java
Raw Normal View History

package org.gcube.data.access.storagehub;
2021-04-07 12:38:18 +02:00
import java.util.List;
import javax.inject.Inject;
2021-04-07 12:38:18 +02:00
import javax.inject.Singleton;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
2021-04-07 12:38:18 +02:00
import org.apache.jackrabbit.api.security.user.UserManager;
import org.gcube.common.storagehub.model.Excludes;
2021-04-07 12:38:18 +02:00
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.InvalidCallParameters;
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException;
import org.gcube.common.storagehub.model.items.FolderItem;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.common.storagehub.model.items.SharedFolder;
import org.gcube.common.storagehub.model.items.TrashItem;
2020-04-08 21:11:43 +02:00
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
2021-04-07 12:38:18 +02:00
import org.gcube.data.access.storagehub.services.interfaces.ACLManagerInterface;
2019-09-30 09:41:48 +02:00
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
* the caller must be authorized, so i'm not passing the login also if it works on behalf of an user
*
*
*/
2021-04-07 12:38:18 +02:00
@Singleton
public class AuthorizationChecker {
2019-09-30 09:41:48 +02:00
private static Logger log = LoggerFactory.getLogger(AuthorizationChecker.class);
@Inject
Node2ItemConverter node2Item;
@Inject
PathUtil pathUtil;
2021-04-07 12:38:18 +02:00
@Inject
ACLManagerInterface aclManager;
2021-04-07 12:38:18 +02:00
public void checkReadAuthorizationControl(Session session, String userToCheck, String id) throws UserNotAuthorizedException , BackendGenericError, RepositoryException{
Node node = session.getNodeByIdentifier(id);
Item item = node2Item.getItem(node, Excludes.ALL);
if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to read node with id "+id+": it's not a valid StorageHub node");
//checking if the item is in the owner trash folder
2021-04-07 12:38:18 +02:00
if(item instanceof TrashItem && item.getParentPath().equals(pathUtil.getTrashPath(userToCheck, session).toPath()))
return;
if (!item.isShared() && item.getOwner()!=null && item.getOwner().equals(userToCheck)) return;
if (hasParentPublicFolder(session, item)) return;
2021-09-10 10:59:07 +02:00
//TODO: remove when messages will be passed to a new system
String parentPath = item.getParentPath();
if (parentPath.endsWith("hl:attachments") && (parentPath.contains("/OutBox/") || parentPath.contains("/InBox/"))) {
return ;
}
if (item.isShared()) {
2021-04-07 12:38:18 +02:00
//SharedFolder parentShared = node2Item.getItem(retrieveSharedFolderParent(node, session), Excludes.EXCLUDE_ACCOUNTING);
//if (parentShared.getUsers().getMap().keySet().contains(userToCheck)) return;
//CHECKING ACL FOR VREFOLDER AND SHARED FOLDER
2021-04-07 12:38:18 +02:00
List<ACL> acls = aclManager.get(item, session);
UserManager userManager = ((JackrabbitSession) session).getUserManager();
Authorizable userAuthorizable = userManager.getAuthorizable(userToCheck);
for (ACL entry: acls) {
log.debug("checking access right for {} with compared with {}",userToCheck, entry.getPricipal());
Authorizable authorizable = userManager.getAuthorizable(entry.getPricipal());
if (authorizable==null) {
2021-04-07 12:38:18 +02:00
log.warn("{} doesn't have a correspondant auhtorizable object, check it ", entry.getPricipal());
continue;
}
try {
2021-04-07 12:38:18 +02:00
if (!authorizable.isGroup() && entry.getPricipal().equals(userToCheck)) return;
if (authorizable.isGroup() && ((Group) authorizable).isMember(userAuthorizable)) return;
}catch (Throwable e) {
log.warn("someting went wrong checking authorizations",e);
}
}
}
2021-09-10 10:59:07 +02:00
throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to read node with id "+id);
}
private boolean hasParentPublicFolder(Session session, Item item) {
2021-09-10 10:59:07 +02:00
if(item==null || item.getParentPath()==null) return false;
if (item.getParentPath().replaceAll("/Home/[^/]*/"+Constants.WORKSPACE_ROOT_FOLDER_NAME,"").isEmpty() || item.getParentPath().replaceAll(Constants.SHARED_FOLDER_PATH, "").isEmpty()) {
if (item instanceof FolderItem)
return ((FolderItem) item).isPublicItem();
else return false;
} else {
if (item instanceof FolderItem)
try {
return ((FolderItem) item).isPublicItem() || hasParentPublicFolder(session, node2Item.getItem(item.getParentId(), session, Excludes.ALL));
}catch (Throwable e) {
log.warn("error checking public parents",e);
return false;
}
else
try {
return hasParentPublicFolder(session, node2Item.getItem(item.getParentId(), session, Excludes.ALL));
}catch (Throwable e) {
log.warn("error checking public parents",e);
return false;
}
}
}
2021-04-07 12:38:18 +02:00
//newItem means that a new item will be created and id is the destination directory
2021-04-07 12:38:18 +02:00
public void checkWriteAuthorizationControl(Session session, String userToCheck, Item item, Node node, boolean isNewItem) throws UserNotAuthorizedException, BackendGenericError, RepositoryException {
2020-04-08 21:11:43 +02:00
if (item==null) throw new UserNotAuthorizedException("Not valid StorageHub node");
if (Constants.WRITE_PROTECTED_FOLDER.contains(item.getName()) || Constants.WRITE_PROTECTED_FOLDER.contains(item.getTitle()))
throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to write into node with id "+item.getId()+": it's a protected folder");
if (item.isShared()) {
2021-04-07 12:38:18 +02:00
//CHECKING ACL FOR VREFOLDER AND SHARED FOLDER
List<ACL> acls = aclManager.get(item, session);
UserManager userManager = ((JackrabbitSession) session).getUserManager();
Authorizable UserAuthorizable = userManager.getAuthorizable(userToCheck);
//put it in a different method
2021-04-07 12:38:18 +02:00
for (ACL entry: acls) {
Authorizable authorizable = userManager.getAuthorizable(entry.getPricipal());
if ((!authorizable.isGroup() && entry.getPricipal().equals(userToCheck)) || (authorizable.isGroup() && ((Group) authorizable).isMember(UserAuthorizable))){
for (AccessType privilege : entry.getAccessTypes()){
if (isNewItem && privilege!=AccessType.READ_ONLY)
return;
else
if (!isNewItem &&
2021-04-07 12:38:18 +02:00
(privilege==AccessType.ADMINISTRATOR || privilege==AccessType.WRITE_ALL || (privilege==AccessType.WRITE_OWNER && item.getOwner().equals(userToCheck))))
return;
}
}
}
} else
if(item.getOwner().equals(userToCheck))
return;
throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to write into node with id "+item.getId());
2020-04-08 21:11:43 +02:00
}
//newItem means that a new item will be created and id is the destination directory
2021-04-07 12:38:18 +02:00
public void checkWriteAuthorizationControl(Session session, String userToCheck , String id, boolean isNewItem) throws UserNotAuthorizedException, BackendGenericError, RepositoryException {
2020-04-08 21:11:43 +02:00
//in case of newItem the id is the parent otherwise the old node to replace
Node node = session.getNodeByIdentifier(id);
Item item = node2Item.getItem(node, Excludes.ALL);
2021-04-07 12:38:18 +02:00
checkWriteAuthorizationControl(session, userToCheck, item, node, isNewItem);
}
2021-04-07 12:38:18 +02:00
/**
*
* checks if item with {id} can be moved
*
*/
public void checkMoveOpsForProtectedFolders(Session session, String id) throws InvalidCallParameters, BackendGenericError, RepositoryException {
Node node = session.getNodeByIdentifier(id);
Item item = node2Item.getItem(node, Excludes.ALL);
if (Constants.PROTECTED_FOLDER.contains(item.getName()) || Constants.PROTECTED_FOLDER.contains(item.getTitle()))
throw new InvalidCallParameters("protected folder cannot be moved or deleted");
}
2021-04-07 12:38:18 +02:00
/**
*
* checks if {userToCheck} is an admin for {item}
*
*/
public void checkAdministratorControl(Session session, String userToCheck, SharedFolder item) throws UserNotAuthorizedException, BackendGenericError, RepositoryException {
if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+": it's not a valid StorageHub node");
if (item.isShared()) {
2021-04-07 12:38:18 +02:00
List<ACL> acls = aclManager.get(item, session);
for (ACL entry: acls) {
if (entry.getPricipal().equals(userToCheck)) {
for (AccessType privilege : entry.getAccessTypes()){
if (privilege==AccessType.ADMINISTRATOR)
return;
}
}
}
2021-04-07 12:38:18 +02:00
}
throw new UserNotAuthorizedException("The user "+userToCheck+" is not an administrator of node with id "+item.getId());
}
}