2018-05-17 12:51:56 +02:00
package org.gcube.data.access.storagehub ;
2021-04-07 12:38:18 +02:00
import java.util.List ;
2018-10-25 16:33:23 +02:00
import javax.inject.Inject ;
2021-04-07 12:38:18 +02:00
import javax.inject.Singleton ;
2018-05-17 12:51:56 +02:00
import javax.jcr.Node ;
2018-10-25 16:33:23 +02:00
import javax.jcr.RepositoryException ;
2018-05-17 12:51:56 +02:00
import javax.jcr.Session ;
2019-04-12 16:35:33 +02:00
import org.apache.jackrabbit.api.JackrabbitSession ;
import org.apache.jackrabbit.api.security.user.Authorizable ;
2020-03-17 13:40:41 +01:00
import org.apache.jackrabbit.api.security.user.Group ;
2021-04-07 12:38:18 +02:00
import org.apache.jackrabbit.api.security.user.UserManager ;
2018-10-25 16:33:23 +02:00
import org.gcube.common.storagehub.model.Excludes ;
2021-04-07 12:38:18 +02:00
import org.gcube.common.storagehub.model.acls.ACL ;
2018-05-28 12:01:01 +02:00
import org.gcube.common.storagehub.model.acls.AccessType ;
2018-10-25 16:33:23 +02:00
import org.gcube.common.storagehub.model.exceptions.BackendGenericError ;
2018-11-30 17:49:35 +01:00
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters ;
2018-10-25 16:33:23 +02:00
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException ;
2020-04-09 09:44:40 +02:00
import org.gcube.common.storagehub.model.items.FolderItem ;
2018-05-17 12:51:56 +02:00
import org.gcube.common.storagehub.model.items.Item ;
import org.gcube.common.storagehub.model.items.SharedFolder ;
2020-04-15 17:36:11 +02:00
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 ;
2021-03-31 14:49:47 +02:00
/ * *
*
*
* 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
2018-05-17 12:51:56 +02:00
public class AuthorizationChecker {
2020-04-05 11:37:15 +02:00
2019-09-30 09:41:48 +02:00
private static Logger log = LoggerFactory . getLogger ( AuthorizationChecker . class ) ;
2020-04-05 11:37:15 +02:00
2018-10-25 16:33:23 +02:00
@Inject
Node2ItemConverter node2Item ;
2021-03-12 10:24:45 +01:00
2021-03-31 14:49:47 +02:00
@Inject
PathUtil pathUtil ;
2021-04-07 12:38:18 +02:00
@Inject
ACLManagerInterface aclManager ;
2021-03-12 10:24:45 +01:00
2021-04-07 12:38:18 +02:00
public void checkReadAuthorizationControl ( Session session , String userToCheck , String id ) throws UserNotAuthorizedException , BackendGenericError , RepositoryException {
2021-03-31 14:49:47 +02:00
2021-03-12 10:24:45 +01:00
Node node = session . getNodeByIdentifier ( id ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
Item item = node2Item . getItem ( node , Excludes . ALL ) ;
2018-05-17 12:51:56 +02:00
2021-03-31 14:49:47 +02:00
if ( item = = null ) throw new UserNotAuthorizedException ( " Insufficent Privileges for user " + userToCheck + " to read node with id " + id + " : it's not a valid StorageHub node " ) ;
2019-04-12 16:35:33 +02:00
2020-04-15 17:36:11 +02:00
//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 ( ) ) )
2020-04-15 17:36:11 +02:00
return ;
2021-03-31 14:49:47 +02:00
if ( ! item . isShared ( ) & & item . getOwner ( ) ! = null & & item . getOwner ( ) . equals ( userToCheck ) ) return ;
2020-04-09 09:44:40 +02:00
if ( hasParentPublicFolder ( session , item ) ) return ;
2020-04-15 17:36:11 +02:00
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 ;
}
2018-05-17 12:51:56 +02:00
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;
2018-12-28 17:58:08 +01:00
//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 ( ) ) ;
2020-04-09 09:44:40 +02:00
2020-04-05 11:37:15 +02:00
if ( authorizable = = null ) {
2021-04-07 12:38:18 +02:00
log . warn ( " {} doesn't have a correspondant auhtorizable object, check it " , entry . getPricipal ( ) ) ;
2020-04-05 11:37:15 +02:00
continue ;
}
2020-04-09 09:44:40 +02:00
2020-04-05 11:37:15 +02:00
try {
2021-04-07 12:38:18 +02:00
if ( ! authorizable . isGroup ( ) & & entry . getPricipal ( ) . equals ( userToCheck ) ) return ;
2020-04-05 11:37:15 +02:00
if ( authorizable . isGroup ( ) & & ( ( Group ) authorizable ) . isMember ( userAuthorizable ) ) return ;
} catch ( Throwable e ) {
log . warn ( " someting went wrong checking authorizations " , e ) ;
}
2019-04-12 16:35:33 +02:00
}
2020-04-09 09:44:40 +02:00
}
2021-09-10 10:59:07 +02:00
2021-03-31 14:49:47 +02:00
throw new UserNotAuthorizedException ( " Insufficent Privileges for user " + userToCheck + " to read node with id " + id ) ;
2020-04-09 09:44:40 +02:00
}
2021-03-12 10:24:45 +01:00
2020-04-09 09:44:40 +02:00
private boolean hasParentPublicFolder ( Session session , Item item ) {
2021-09-10 10:59:07 +02:00
if ( item = = null | | item . getParentPath ( ) = = null ) return false ;
2020-04-09 09:44:40 +02:00
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 ;
}
}
2018-05-17 12:51:56 +02:00
}
2018-05-28 12:01:01 +02:00
2021-04-07 12:38:18 +02:00
2020-04-09 09:44:40 +02:00
2020-04-15 17:36:11 +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 " ) ;
2020-04-15 17:36:11 +02:00
2018-11-30 17:49:35 +01:00
if ( Constants . WRITE_PROTECTED_FOLDER . contains ( item . getName ( ) ) | | Constants . WRITE_PROTECTED_FOLDER . contains ( item . getTitle ( ) ) )
2021-03-31 14:49:47 +02:00
throw new UserNotAuthorizedException ( " Insufficent Privileges for user " + userToCheck + " to write into node with id " + item . getId ( ) + " : it's a protected folder " ) ;
2020-04-15 17:36:11 +02:00
2018-05-28 12:01:01 +02:00
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 ) ;
2019-04-12 16:35:33 +02:00
//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 )
2018-05-28 12:01:01 +02:00
return ;
2018-06-20 16:59:41 +02:00
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 ) ) ) )
2018-06-20 16:59:41 +02:00
return ;
2019-04-12 16:35:33 +02:00
2018-05-28 12:01:01 +02:00
}
2019-04-12 16:35:33 +02:00
2018-05-28 12:01:01 +02:00
}
}
} else
2021-03-31 14:49:47 +02:00
if ( item . getOwner ( ) . equals ( userToCheck ) )
2018-06-20 16:59:41 +02:00
return ;
2021-03-31 14:49:47 +02:00
throw new UserNotAuthorizedException ( " Insufficent Privileges for user " + userToCheck + " to write into node with id " + item . getId ( ) ) ;
2020-04-08 21:11:43 +02:00
}
2020-04-09 09:44:40 +02:00
2020-04-15 17:36:11 +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 ) ;
2018-10-25 16:33:23 +02:00
}
2019-04-12 16:35:33 +02:00
2021-04-07 12:38:18 +02:00
/ * *
*
* checks if item with { id } can be moved
*
* /
2018-11-30 17:49:35 +01:00
public void checkMoveOpsForProtectedFolders ( Session session , String id ) throws InvalidCallParameters , BackendGenericError , RepositoryException {
Node node = session . getNodeByIdentifier ( id ) ;
Item item = node2Item . getItem ( node , Excludes . ALL ) ;
2020-04-15 17:36:11 +02:00
2018-11-30 17:49:35 +01:00
if ( Constants . PROTECTED_FOLDER . contains ( item . getName ( ) ) | | Constants . PROTECTED_FOLDER . contains ( item . getTitle ( ) ) )
throw new InvalidCallParameters ( " protected folder cannot be moved or deleted " ) ;
}
2019-04-12 16:35:33 +02:00
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 {
2021-03-31 14:49:47 +02:00
if ( item = = null ) throw new UserNotAuthorizedException ( " Insufficent Privileges for user " + userToCheck + " : it's not a valid StorageHub node " ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
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 )
2019-04-12 16:35:33 +02:00
return ;
2018-10-25 16:33:23 +02:00
}
}
}
2021-04-07 12:38:18 +02:00
}
2021-03-31 14:49:47 +02:00
throw new UserNotAuthorizedException ( " The user " + userToCheck + " is not an administrator of node with id " + item . getId ( ) ) ;
2018-05-17 12:51:56 +02:00
}
2018-10-25 16:33:23 +02:00
2018-05-17 12:51:56 +02:00
}