2016-10-18 23:31:04 +02:00
package org.gcube.data_catalogue.grsf_publish_ws.filters ;
import static org.gcube.common.authorization.client.Constants.authorizationService ;
import java.io.IOException ;
import javax.ws.rs.container.ContainerRequestContext ;
import javax.ws.rs.container.ContainerRequestFilter ;
2016-10-19 14:34:19 +02:00
import javax.ws.rs.core.MediaType ;
2016-10-18 23:31:04 +02:00
import javax.ws.rs.core.MultivaluedMap ;
import javax.ws.rs.core.Response ;
import javax.ws.rs.ext.Provider ;
2016-10-19 14:26:26 +02:00
import org.gcube.accounting.datamodel.UsageRecord.OperationResult ;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord ;
import org.gcube.accounting.persistence.AccountingPersistence ;
import org.gcube.accounting.persistence.AccountingPersistenceFactory ;
2016-10-18 23:31:04 +02:00
import org.gcube.common.authorization.library.AuthorizationEntry ;
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
import org.gcube.common.authorization.library.utils.Caller ;
2016-10-19 09:57:31 +02:00
import org.gcube.common.portal.PortalContext ;
2016-10-18 23:31:04 +02:00
import org.gcube.common.scope.api.ScopeProvider ;
2016-10-19 14:34:19 +02:00
import org.gcube.data_catalogue.grsf_publish_ws.json.output.ResponseBean ;
2016-10-18 23:31:04 +02:00
import org.slf4j.LoggerFactory ;
/ * *
* Requests filter : is invoked before any request reaches a service method
* @author Costantino Perciante at ISTI - CNR
* /
@Provider
2016-10-19 14:26:26 +02:00
public class RequestsAuthAccountingFilter implements ContainerRequestFilter {
2016-10-18 23:31:04 +02:00
2016-10-19 14:26:26 +02:00
private static final org . slf4j . Logger logger = LoggerFactory . getLogger ( RequestsAuthAccountingFilter . class ) ;
2016-10-18 23:31:04 +02:00
private static final String AUTH_TOKEN = " gcube-token " ;
2016-10-19 14:26:26 +02:00
private final static AccountingPersistence accountingPersistence = AccountingPersistenceFactory . getPersistence ( ) ;
2016-10-18 23:31:04 +02:00
@Override
public void filter ( ContainerRequestContext requestContext )
throws IOException {
logger . info ( " Intercepted request, checking if it contains authorization token " ) ;
// check if the request contains gcube-token
String tokenInHeader = null , tokenAsQueryParameter = null ;
MultivaluedMap < String , String > headers = requestContext . getHeaders ( ) ;
if ( headers ! = null & & headers . containsKey ( AUTH_TOKEN ) )
tokenInHeader = headers . get ( AUTH_TOKEN ) . get ( 0 ) ;
MultivaluedMap < String , String > queryParameters = requestContext . getUriInfo ( ) . getQueryParameters ( ) ;
if ( queryParameters ! = null & & queryParameters . containsKey ( AUTH_TOKEN ) )
tokenAsQueryParameter = queryParameters . get ( AUTH_TOKEN ) . get ( 0 ) ;
if ( tokenInHeader ! = null ) {
logger . info ( " Token in " + tokenInHeader . substring ( 0 , 5 ) + " ******************** " ) ;
AuthorizationEntry ae = validateToken ( tokenInHeader ) ;
if ( ae ! = null ) {
logger . debug ( " Setting scope " + ae . getContext ( ) ) ;
AuthorizationProvider . instance . set ( new Caller ( ae . getClientInfo ( ) , ae . getQualifier ( ) ) ) ;
ScopeProvider . instance . set ( ae . getContext ( ) ) ;
logger . info ( " Authorization entry set in thread local " ) ;
return ;
} else
2016-10-19 14:34:19 +02:00
requestContext . abortWith ( Response . status ( Response . Status . UNAUTHORIZED ) . type ( MediaType . APPLICATION_JSON ) . entity ( new ResponseBean ( false , " Invalid or missing gcube-token " , null ) ) . build ( ) ) ;
2016-10-18 23:31:04 +02:00
} else if ( tokenAsQueryParameter ! = null ) {
logger . info ( " Token is " + tokenAsQueryParameter . substring ( 0 , 5 ) + " ******************** " ) ;
AuthorizationEntry ae = validateToken ( tokenAsQueryParameter ) ;
if ( ae ! = null ) {
logger . debug ( " Setting scope " + ae . getContext ( ) ) ;
AuthorizationProvider . instance . set ( new Caller ( ae . getClientInfo ( ) , ae . getQualifier ( ) ) ) ;
ScopeProvider . instance . set ( ae . getContext ( ) ) ;
logger . info ( " Authorization entry set in thread local " ) ;
return ;
} else
2016-10-19 14:34:19 +02:00
requestContext . abortWith ( Response . status ( Response . Status . UNAUTHORIZED ) . type ( MediaType . APPLICATION_JSON ) . entity ( new ResponseBean ( false , " Invalid or missing gcube-token " , null ) ) . build ( ) ) ;
2016-10-18 23:31:04 +02:00
}
else
2016-10-19 14:34:19 +02:00
requestContext . abortWith ( Response . status ( Response . Status . UNAUTHORIZED ) . type ( MediaType . APPLICATION_JSON ) . entity ( new ResponseBean ( false , " Invalid or missing gcube-token " , null ) ) . build ( ) ) ;
2016-10-18 23:31:04 +02:00
}
/ * *
* Validate token .
* @param token
* @return null if validation fails
* /
private static AuthorizationEntry validateToken ( String token ) {
2016-10-19 14:26:26 +02:00
2016-10-18 23:31:04 +02:00
AuthorizationEntry res = null ;
2016-10-19 14:26:26 +02:00
2016-10-18 23:31:04 +02:00
try {
2016-10-19 14:26:26 +02:00
2016-10-19 09:57:31 +02:00
// set the root scope
ScopeProvider . instance . set ( " / " + PortalContext . getConfiguration ( ) . getInfrastructureName ( ) ) ;
2016-10-18 23:31:04 +02:00
logger . debug ( " Validating token " + token ) ;
res = authorizationService ( ) . get ( token ) ;
logger . debug ( " Token seems valid for scope " + res . getContext ( ) + " and user " + res . getClientInfo ( ) . getId ( ) ) ;
} catch ( Exception e ) {
logger . error ( " The token is not valid. This request will be rejected!!! ( " + token + " ) " , e ) ;
2016-10-19 09:57:31 +02:00
} finally {
ScopeProvider . instance . reset ( ) ;
2016-10-18 23:31:04 +02:00
}
return res ;
}
2016-10-19 14:26:26 +02:00
/ * *
* Accounts service requests
* /
private static void accountRequest ( String username ) {
// Create a new Service Usage Record
ServiceUsageRecord usageRecord = new ServiceUsageRecord ( ) ;
try {
// TODO
usageRecord . setResourceProperty ( ServiceUsageRecord . CONSUMER_ID , username ) ;
usageRecord . setOperationResult ( OperationResult . SUCCESS ) ;
usageRecord . setCallerHost ( " node13.d4science.org " ) ;
usageRecord . setHost ( " node22.d4science.org " ) ;
usageRecord . setServiceClass ( " VREManagement " ) ;
usageRecord . setServiceName ( " SmartExecutor " ) ;
usageRecord . setCalledMethod ( " launch " ) ;
usageRecord . setResourceProperty ( ServiceUsageRecord . DURATION , " 300 " ) ;
accountingPersistence . account ( usageRecord ) ;
} catch ( Exception e ) {
logger . error ( " Unable to account this service usage record " , e ) ;
}
2016-10-19 14:34:19 +02:00
2016-10-19 14:26:26 +02:00
}
2016-10-18 23:31:04 +02:00
}