2018-05-17 12:51:56 +02:00
package org.gcube.data.access.storagehub ;
2019-04-15 15:57:12 +02:00
import org.apache.jackrabbit.api.security.user.Group ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
import javax.inject.Inject ;
2018-05-17 12:51:56 +02:00
import javax.inject.Singleton ;
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 ;
2018-05-28 12:01:01 +02:00
import javax.jcr.security.AccessControlEntry ;
import javax.jcr.security.Privilege ;
2018-05-17 12:51:56 +02:00
2019-04-12 16:35:33 +02:00
import org.apache.jackrabbit.api.JackrabbitSession ;
2018-05-28 12:01:01 +02:00
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList ;
2019-04-12 16:35:33 +02:00
import org.apache.jackrabbit.api.security.user.Authorizable ;
2018-05-28 12:01:01 +02:00
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils ;
2018-05-17 12:51:56 +02:00
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
2018-10-25 16:33:23 +02:00
import org.gcube.common.storagehub.model.Excludes ;
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 ;
2018-05-17 12:51:56 +02:00
import org.gcube.common.storagehub.model.items.Item ;
import org.gcube.common.storagehub.model.items.SharedFolder ;
2018-10-25 16:33:23 +02:00
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter ;
2019-09-30 09:41:48 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import lombok.extern.java.Log ;
import lombok.extern.log4j.Log4j ;
2018-05-17 12:51:56 +02:00
@Singleton
public class AuthorizationChecker {
2019-09-30 09:41:48 +02:00
private static Logger log = LoggerFactory . getLogger ( AuthorizationChecker . class ) ;
2018-10-25 16:33:23 +02:00
@Inject
Node2ItemConverter node2Item ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
public void checkReadAuthorizationControl ( Session session , String id ) throws UserNotAuthorizedException , BackendGenericError , RepositoryException {
2018-05-17 12:51:56 +02:00
Node node = session . getNodeByIdentifier ( id ) ;
2018-10-25 16:33:23 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
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
2018-10-25 16:33:23 +02:00
if ( item = = null ) throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to read node with id " + id + " : it's not a valid StorageHub node " ) ;
2019-04-12 16:35:33 +02:00
2019-09-30 09:41:48 +02:00
2018-05-17 12:51:56 +02:00
if ( item . isShared ( ) ) {
2018-10-25 16:33:23 +02:00
SharedFolder parentShared = node2Item . getItem ( retrieveSharedFolderParent ( node , session ) , Excludes . EXCLUDE_ACCOUNTING ) ;
2019-09-30 09:41:48 +02:00
if ( parentShared . getUsers ( ) . getMap ( ) . keySet ( ) . contains ( login ) ) return ;
2018-12-28 17:58:08 +01:00
//CHECKING ACL FOR VREFOLDER AND SHARED FOLDER
JackrabbitAccessControlList accessControlList = AccessControlUtils . getAccessControlList ( session , parentShared . getPath ( ) ) ;
AccessControlEntry [ ] entries = accessControlList . getAccessControlEntries ( ) ;
2019-09-30 09:41:48 +02:00
Authorizable userAuthorizable = ( ( JackrabbitSession ) session ) . getUserManager ( ) . getAuthorizable ( login ) ;
2019-04-12 16:35:33 +02:00
for ( AccessControlEntry entry : entries ) {
2019-09-30 09:41:48 +02:00
log . debug ( " checking access right for {} with compared with {} " , login , entry . getPrincipal ( ) ) ;
2019-04-12 17:41:21 +02:00
Authorizable authorizable = ( ( JackrabbitSession ) session ) . getUserManager ( ) . getAuthorizable ( entry . getPrincipal ( ) ) ;
2019-09-19 16:31:24 +02:00
//TODO; check why sometimes the next line gets a nullpointer
2019-04-12 16:35:33 +02:00
if ( ! authorizable . isGroup ( ) & & entry . getPrincipal ( ) . getName ( ) . equals ( login ) ) return ;
2019-09-30 09:41:48 +02:00
if ( authorizable . isGroup ( ) & & ( ( Group ) authorizable ) . isMember ( userAuthorizable ) ) return ;
2019-04-12 16:35:33 +02:00
}
2018-12-28 17:58:08 +01:00
throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to read node with id " + id ) ;
2019-04-12 16:35:33 +02:00
2018-11-20 14:08:45 +01:00
} else if ( item . getOwner ( ) = = null | | ! item . getOwner ( ) . equals ( login ) )
2018-10-25 16:33:23 +02:00
throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to read node with id " + id ) ;
2018-05-17 12:51:56 +02:00
}
2018-05-28 12:01:01 +02:00
2018-10-25 16:33:23 +02:00
private Node retrieveSharedFolderParent ( Node node , Session session ) throws BackendGenericError , RepositoryException {
if ( node2Item . checkNodeType ( node , SharedFolder . class ) ) return node ;
2018-05-17 12:51:56 +02:00
else
2018-10-25 16:33:23 +02:00
return retrieveSharedFolderParent ( node . getParent ( ) , session ) ;
2018-05-28 12:01:01 +02:00
}
2018-10-25 16:33:23 +02:00
public void checkWriteAuthorizationControl ( Session session , String id , boolean isNewItem ) throws UserNotAuthorizedException , BackendGenericError , RepositoryException {
2018-06-20 16:59:41 +02:00
//in case of newItem the id is the parent otherwise the old node to replace
2018-05-28 12:01:01 +02:00
Node node = session . getNodeByIdentifier ( id ) ;
2018-10-25 16:33:23 +02:00
Item item = node2Item . getItem ( node , Excludes . ALL ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
if ( item = = null ) throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to write into node with id " + id + " : it's not a valid StorageHub node " ) ;
2019-04-12 16:35:33 +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 ( ) ) )
2018-10-25 16:33:23 +02:00
throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to write into node with id " + id + " : it's a protected folder " ) ;
2019-04-12 16:35:33 +02:00
2018-05-28 12:01:01 +02:00
if ( item . isShared ( ) ) {
2018-10-25 16:33:23 +02:00
Node parentSharedNode = retrieveSharedFolderParent ( node , session ) ;
JackrabbitAccessControlList accessControlList = AccessControlUtils . getAccessControlList ( session , parentSharedNode . getPath ( ) ) ;
2018-05-28 12:01:01 +02:00
AccessControlEntry [ ] entries = accessControlList . getAccessControlEntries ( ) ;
2019-04-15 15:57:12 +02:00
Authorizable UserAuthorizable = ( ( JackrabbitSession ) session ) . getUserManager ( ) . getAuthorizable ( login ) ;
2019-04-12 16:35:33 +02:00
//put it in a different method
2018-05-28 12:01:01 +02:00
for ( AccessControlEntry entry : entries ) {
2019-04-15 15:57:12 +02:00
Authorizable authorizable = ( ( JackrabbitSession ) session ) . getUserManager ( ) . getAuthorizable ( entry . getPrincipal ( ) ) ;
if ( ( ! authorizable . isGroup ( ) & & entry . getPrincipal ( ) . getName ( ) . equals ( login ) ) | | ( authorizable . isGroup ( ) & & ( ( Group ) authorizable ) . isMember ( UserAuthorizable ) ) ) {
2018-05-28 12:01:01 +02:00
for ( Privilege privilege : entry . getPrivileges ( ) ) {
2018-07-02 17:58:50 +02:00
AccessType access = AccessType . fromValue ( privilege . getName ( ) ) ;
2018-06-20 16:59:41 +02:00
if ( isNewItem & & access ! = AccessType . READ_ONLY )
2018-05-28 12:01:01 +02:00
return ;
2018-06-20 16:59:41 +02:00
else
if ( ! isNewItem & &
2019-04-12 16:35:33 +02:00
( access = = AccessType . ADMINISTRATOR | | access = = AccessType . WRITE_ALL | | ( access = = AccessType . WRITE_OWNER & & item . getOwner ( ) . equals ( login ) ) ) )
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
2018-10-25 16:33:23 +02:00
if ( item . getOwner ( ) . equals ( login ) )
2018-06-20 16:59:41 +02:00
return ;
2018-10-25 16:33:23 +02:00
throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " to write into node with id " + id ) ;
}
2019-04-12 16:35:33 +02:00
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 ) ;
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
2018-10-25 16:33:23 +02:00
public void checkAdministratorControl ( Session session , SharedFolder item ) throws UserNotAuthorizedException , BackendGenericError , RepositoryException {
2018-12-17 14:55:43 +01:00
//TODO: riguardare questo pezzo di codice
2018-10-25 16:33:23 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2019-04-12 16:35:33 +02:00
2018-11-30 17:49:35 +01:00
if ( item = = null ) throw new UserNotAuthorizedException ( " Insufficent Provileges for user " + login + " : it's not a valid StorageHub node " ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
Node node = session . getNodeByIdentifier ( item . getId ( ) ) ;
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
if ( item . isShared ( ) ) {
Node parentSharedNode = retrieveSharedFolderParent ( node , session ) ;
JackrabbitAccessControlList accessControlList = AccessControlUtils . getAccessControlList ( session , parentSharedNode . getPath ( ) ) ;
AccessControlEntry [ ] entries = accessControlList . getAccessControlEntries ( ) ;
2019-04-12 16:35:33 +02:00
//put it in a different method
2018-10-25 16:33:23 +02:00
SharedFolder parentShared = node2Item . getItem ( parentSharedNode , Excludes . EXCLUDE_ACCOUNTING ) ;
for ( AccessControlEntry entry : entries ) {
if ( entry . getPrincipal ( ) . getName ( ) . equals ( login ) | | ( parentShared . isVreFolder ( ) & & entry . getPrincipal ( ) . getName ( ) . equals ( parentShared . getTitle ( ) ) ) ) {
for ( Privilege privilege : entry . getPrivileges ( ) ) {
AccessType access = AccessType . fromValue ( privilege . getName ( ) ) ;
if ( access = = AccessType . ADMINISTRATOR )
2019-04-12 16:35:33 +02:00
return ;
2018-10-25 16:33:23 +02:00
}
throw new UserNotAuthorizedException ( " The user " + login + " is not an administrator of node with id " + item . getId ( ) ) ;
}
}
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
}
2019-04-12 16:35:33 +02:00
2018-10-25 16:33:23 +02:00
throw new UserNotAuthorizedException ( " The user " + login + " is not an administrator of node with id " + item . getId ( ) ) ;
2019-04-12 16:35:33 +02:00
2018-05-17 12:51:56 +02:00
}
2018-10-25 16:33:23 +02:00
2019-04-12 16:35:33 +02:00
2018-06-20 16:59:41 +02:00
/ *
2018-06-05 15:33:36 +02:00
private String retrieveOwner ( Node node ) {
Node nodeOwner ;
//get Owner
try {
return node . getProperty ( NodeProperty . PORTAL_LOGIN . toString ( ) ) . getString ( ) ;
} catch ( Exception e ) {
try {
nodeOwner = node . getNode ( NodeProperty . OWNER . toString ( ) ) ;
return nodeOwner . getProperty ( NodeProperty . PORTAL_LOGIN . toString ( ) ) . getString ( ) ;
// this.userId = nodeOwner.getProperty(USER_ID).getString();
// this.portalLogin = nodeOwner.getProperty(PORTAL_LOGIN).getString();
// node.getSession().save();
} catch ( Exception e1 ) {
throw new RuntimeException ( e1 ) ;
}
2018-05-28 12:01:01 +02:00
2018-06-05 15:33:36 +02:00
}
}
2018-06-20 16:59:41 +02:00
* /
2018-05-17 12:51:56 +02:00
}