@ -1,5 +1,6 @@
package org.gcube.data.access.storagehub.services ;
import java.security.Principal ;
import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
@ -8,6 +9,8 @@ import javax.inject.Inject;
import javax.jcr.Node ;
import javax.jcr.NodeIterator ;
import javax.jcr.PathNotFoundException ;
import javax.jcr.RepositoryException ;
import javax.jcr.security.AccessControlEntry ;
import javax.jcr.security.AccessControlManager ;
import javax.jcr.security.Privilege ;
import javax.servlet.ServletContext ;
@ -22,6 +25,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces ;
import javax.ws.rs.core.Context ;
import javax.ws.rs.core.MediaType ;
import javax.ws.rs.core.Response ;
import org.apache.jackrabbit.api.JackrabbitSession ;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList ;
@ -35,17 +39,23 @@ import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse ;
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.common.storagehub.model.Excludes ;
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.InvalidItemException ;
import org.gcube.common.storagehub.model.exceptions.StorageHubException ;
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException ;
import org.gcube.common.storagehub.model.types.NodeProperty ;
import org.gcube.common.storagehub.model.types.PrimaryNodeType ;
import org.gcube.data.access.storagehub.AuthorizationChecker ;
import org.gcube.data.access.storagehub.Constants ;
import org.gcube.data.access.storagehub.Utils ;
import org.gcube.data.access.storagehub.exception.MyAuthException ;
import org.gcube.data.access.storagehub.handlers.CredentialHandler ;
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter ;
import org.gcube.data.access.storagehub.handlers.VRE ;
import org.gcube.data.access.storagehub.handlers.VREManager ;
import org.gcube.smartgears.utils.InnerMethodName ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
@ -57,19 +67,28 @@ public class GroupManager {
private static final String VREMANAGER_ROLE = "VRE-Manager" ;
private static final String INFRASTRUCTURE_MANAGER_ROLE = "Infrastructure-Manager" ;
private static final Logger log = LoggerFactory . getLogger ( GroupManager . class ) ;
@Inject
RepositoryInitializer repository ;
@Inject
VREManager vreManager ;
@Inject
Node2ItemConverter node2Item ;
@Inject
AuthorizationChecker authChecker ;
@GET
@Path ( "" )
@Produces ( MediaType . APPLICATION_JSON )
public List < String > getGroups ( ) {
InnerMethodName . instance . set ( "getGroups" ) ;
JackrabbitSession session = null ;
List < String > groups = new ArrayList < > ( ) ;
try {
@ -103,18 +122,18 @@ public class GroupManager {
@Consumes ( MediaType . APPLICATION_FORM_URLENCODED )
@AuthorizationControl ( allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public String createGroup ( @FormParam ( "group" ) String group , @FormParam ( "accessType" ) AccessType accessType ) {
InnerMethodName . instance . set ( "createGroup" ) ;
JackrabbitSession session = null ;
String groupId = null ;
try {
if ( ! isValidGroupForContext ( groupId ) )
throw new UserNotAuthorizedException ( "only VREManager can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = session . getUserManager ( ) ;
Group createdGroup = usrManager . createGroup ( group ) ;
@ -138,15 +157,15 @@ public class GroupManager {
@Path ( "{group}" )
@AuthorizationControl ( allowedRoles = { INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public String deleteGroup ( @PathParam ( "group" ) String group ) {
InnerMethodName . instance . set ( "deleteGroup" ) ;
JackrabbitSession session = null ;
try {
if ( ! isValidGroupForContext ( group ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = session . getUserManager ( ) ;
@ -170,35 +189,166 @@ public class GroupManager {
return group ;
}
public boolean isAdmin ( ) { return AuthorizationProvider . instance . get ( ) . getClient ( ) . getRoles ( ) . contains ( INFRASTRUCTURE_MANAGER_ROLE ) ; }
public boolean isInfraManager ( ) { return AuthorizationProvider . instance . get ( ) . getClient ( ) . getRoles ( ) . contains ( INFRASTRUCTURE_MANAGER_ROLE ) ; }
@PUT
@Path ( "{id}/admins" )
@Consumes ( MediaType . APPLICATION_FORM_URLENCODED )
@AuthorizationControl ( allowedRoles = { VREMANAGER_ROLE , INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public void addAdmin ( @PathParam ( "id" ) String groupId , @FormParam ( "userId" ) String userId ) {
InnerMethodName . instance . set ( "addAddmin" ) ;
JackrabbitSession session = null ;
try {
if ( ! isInfraManager ( ) & & ! isValidGroupForContext ( groupId ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
VRE vreFolder = Utils . getVreFolderItemByGroupNameAndUser ( session , groupId , userId , node2Item , vreManager , Excludes . ALL ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = ( ( JackrabbitSession ) session ) . getUserManager ( ) ;
Group group = ( Group ) usrManager . getAuthorizable ( groupId ) ;
User authUser = ( User ) usrManager . getAuthorizable ( userId ) ;
if ( ! group . isMember ( authUser ) )
throw new InvalidCallParameters ( "user " + userId + " is not in the group " + groupId ) ;
Node node = session . getNodeByIdentifier ( vreFolder . getVreFolder ( ) . getId ( ) ) ;
AccessControlManager acm = session . getAccessControlManager ( ) ;
JackrabbitAccessControlList acls = AccessControlUtils . getAccessControlList ( acm , node . getPath ( ) ) ;
Privilege [ ] userPrivileges = new Privilege [ ] { acm . privilegeFromName ( AccessType . ADMINISTRATOR . getValue ( ) ) } ;
Principal principal = AccessControlUtils . getPrincipal ( session , userId ) ;
acls . addAccessControlEntry ( principal , userPrivileges ) ;
acm . setPolicy ( node . getPath ( ) , acls ) ;
session . save ( ) ;
} catch ( StorageHubException she ) {
log . error ( she . getErrorMessage ( ) , she ) ;
GXOutboundErrorResponse . throwException ( she , Response . Status . fromStatusCode ( she . getStatus ( ) ) ) ;
} catch ( RepositoryException re ) {
log . error ( "adding admin to VREFolder" , re ) ;
GXOutboundErrorResponse . throwException ( new BackendGenericError ( "jcr error adding admin to VREFolder" , re ) ) ;
} finally {
if ( session ! = null )
session . logout ( ) ;
}
}
@DELETE
@Path ( "{id}/admins/{userId}" )
@Consumes ( MediaType . APPLICATION_FORM_URLENCODED )
@AuthorizationControl ( allowedRoles = { VREMANAGER_ROLE , INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public void removeAdmin ( @PathParam ( "id" ) String groupId , @PathParam ( "userId" ) String userId ) {
InnerMethodName . instance . set ( "removeAdmin" ) ;
JackrabbitSession session = null ;
try {
if ( ! isValidGroupForContext ( groupId ) & & ! isInfraManager ( ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
VRE vreFolder = Utils . getVreFolderItemByGroupNameAndUser ( session , groupId , userId , node2Item , vreManager , Excludes . ALL ) ;
Node node = session . getNodeByIdentifier ( vreFolder . getVreFolder ( ) . getId ( ) ) ;
AccessControlManager acm = session . getAccessControlManager ( ) ;
JackrabbitAccessControlList acls = AccessControlUtils . getAccessControlList ( acm , node . getPath ( ) ) ;
AccessControlEntry toRemove = null ;
for ( AccessControlEntry acl : acls . getAccessControlEntries ( ) )
if ( acl . getPrincipal ( ) . getName ( ) . equals ( userId ) ) {
toRemove = acl ;
break ;
}
acls . removeAccessControlEntry ( toRemove ) ;
acm . setPolicy ( node . getPath ( ) , acls ) ;
session . save ( ) ;
} catch ( StorageHubException she ) {
log . error ( she . getErrorMessage ( ) , she ) ;
GXOutboundErrorResponse . throwException ( she , Response . Status . fromStatusCode ( she . getStatus ( ) ) ) ;
} catch ( RepositoryException re ) {
log . error ( "removing admin to VREFolder" , re ) ;
GXOutboundErrorResponse . throwException ( new BackendGenericError ( "jcr error removing admin to VREFolder" , re ) ) ;
} finally {
if ( session ! = null )
session . logout ( ) ;
}
}
@GET
@Path ( "{groupId}/admins" )
@Produces ( MediaType . APPLICATION_JSON )
public List < String > getAdmins ( @PathParam ( "groupId" ) String groupId ) {
InnerMethodName . instance . set ( "getAdmins" ) ;
JackrabbitSession session = null ;
List < String > users = new ArrayList < > ( ) ;
try {
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
VRE vreFolder = Utils . getVreFolderItemByGroupNameAndUser ( session , groupId , AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) , node2Item , vreManager , Excludes . ALL ) ;
AccessControlManager acm = session . getAccessControlManager ( ) ;
//authChecker.checkAdministratorControl(session, (VreFolder)vreFolder.getVreFolder());
Node node = session . getNodeByIdentifier ( vreFolder . getVreFolder ( ) . getId ( ) ) ;
JackrabbitAccessControlList acls = AccessControlUtils . getAccessControlList ( acm , node . getPath ( ) ) ;
for ( AccessControlEntry acl : acls . getAccessControlEntries ( ) )
for ( Privilege pr : acl . getPrivileges ( ) ) {
if ( pr . getName ( ) . equals ( AccessType . ADMINISTRATOR . getValue ( ) ) ) {
users . add ( acl . getPrincipal ( ) . getName ( ) ) ;
}
}
} catch ( Exception e ) {
log . error ( "jcr error getting admins of group {}" , groupId , e ) ;
GXOutboundErrorResponse . throwException ( new BackendGenericError ( e ) ) ;
} finally {
if ( session ! = null )
session . logout ( ) ;
}
return users ;
}
@PUT
@Path ( "{id}" )
@Path ( "{id} /users ")
@Consumes ( MediaType . APPLICATION_FORM_URLENCODED )
@AuthorizationControl ( allowedRoles = { VREMANAGER_ROLE , INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public boolean addUserToGroup ( @PathParam ( "id" ) String groupId , @FormParam ( "userId" ) String userId ) {
InnerMethodName . instance . set ( "addUserToGroup" ) ;
JackrabbitSession session = null ;
boolean success = false ;
try {
if ( ! isValidGroupForContext ( groupId ) & & ! isAdmin ( ) )
if ( ! isValidGroupForContext ( groupId ) & & ! is InfraManager ( ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = session . getUserManager ( ) ;
Group group = ( Group ) usrManager . getAuthorizable ( groupId ) ;
User user = ( User ) usrManager . getAuthorizable ( userId ) ;
if ( group . isMember ( user ) )
throw new InvalidCallParameters ( "user " + userId + " is already member of group " + groupId ) ;
success = group . addMember ( user ) ;
String folderName = group . getPrincipal ( ) . getName ( ) ;
@ -224,26 +374,26 @@ public class GroupManager {
@Path ( "{groupId}/users/{userId}" )
@AuthorizationControl ( allowedRoles = { VREMANAGER_ROLE , INFRASTRUCTURE_MANAGER_ROLE } , exception = MyAuthException . class )
public boolean removeUserFromGroup ( @PathParam ( "groupId" ) String groupId , @PathParam ( "userId" ) String userId ) {
InnerMethodName . instance . set ( "removeUserFromGroup" ) ;
JackrabbitSession session = null ;
boolean success = false ;
try {
if ( ! isValidGroupForContext ( groupId ) & & ! is Admin ( ) )
if ( ! isValidGroupForContext ( groupId ) & & ! is InfraManager ( ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = session . getUserManager ( ) ;
Group group = ( Group ) usrManager . getAuthorizable ( groupId ) ;
User user = ( User ) usrManager . getAuthorizable ( userId ) ;
if ( ! group . isMember ( user ) )
throw new InvalidCallParameters ( "user " + userId + " is not member of group " + groupId ) ;
//delete folder on user
String folderName = group . getPrincipal ( ) . getName ( ) ;
Node folder = getVreFolderNode ( session , folderName ) ;
@ -276,16 +426,16 @@ public class GroupManager {
@Produces ( MediaType . APPLICATION_JSON )
@AuthorizationControl ( allowedRoles = { VREMANAGER_ROLE } , exception = MyAuthException . class )
public List < String > getUsersOfGroup ( @PathParam ( "groupId" ) String groupId ) {
InnerMethodName . instance . set ( "getUsersOfGroup" ) ;
JackrabbitSession session = null ;
List < String > users = new ArrayList < > ( ) ;
try {
if ( ! isValidGroupForContext ( groupId ) )
throw new UserNotAuthorizedException ( "only VREManager of the selected VRE can execute this operation" ) ;
session = ( JackrabbitSession ) repository . getRepository ( ) . login ( CredentialHandler . getAdminCredentials ( context ) ) ;
org . apache . jackrabbit . api . security . user . UserManager usrManager = session . getUserManager ( ) ;
@ -336,17 +486,17 @@ public class GroupManager {
acm . setPolicy ( folder . getPath ( ) , acls ) ;
}
private Node getVreFolderNode ( JackrabbitSession session , String name ) throws InvalidItemException , Exception {
Node sharedRootNode = session . getNode ( Constants . SHARED_FOLDER_PATH ) ;
Node vreFolder = null ;
try {
vreFolder = sharedRootNode . getNode ( name ) ;
} catch ( PathNotFoundException e ) {
log . debug ( "is an old HL VRE" ) ;
}
NodeIterator nodes = sharedRootNode . getNodes ( ) ;
while ( nodes . hasNext ( ) ) {
Node node = nodes . nextNode ( ) ;
@ -365,5 +515,5 @@ public class GroupManager {
String expectedGroupId = currentContext . replace ( "/" , "-" ) . substring ( 1 ) ;
return group . equals ( expectedGroupId ) ;
}
}