2016-11-25 15:42:29 +01:00
package org.gcube.smartgears.handlers.application.request ;
import static org.gcube.smartgears.handlers.application.request.RequestError.application_failed_error ;
import static org.gcube.smartgears.handlers.application.request.RequestError.application_unavailable_error ;
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error ;
import java.io.IOException ;
2017-01-30 15:05:08 +01:00
import javax.xml.bind.annotation.XmlAttribute ;
2016-11-25 15:42:29 +01:00
import javax.xml.bind.annotation.XmlRootElement ;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
import org.gcube.common.scope.api.ScopeProvider ;
2017-03-21 14:42:21 +01:00
import org.gcube.common.scope.impl.ScopeBean ;
import org.gcube.common.scope.impl.ScopeBean.Type ;
2016-11-25 15:42:29 +01:00
import org.gcube.smartgears.Constants ;
2017-03-21 14:42:21 +01:00
import org.gcube.smartgears.configuration.container.ContainerConfiguration ;
2016-11-25 15:42:29 +01:00
import org.gcube.smartgears.context.application.ApplicationContext ;
import org.gcube.smartgears.handlers.application.RequestEvent ;
import org.gcube.smartgears.handlers.application.RequestHandler ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
@XmlRootElement ( name = Constants . request_validation )
public class RequestValidator extends RequestHandler {
2017-01-30 15:05:08 +01:00
@XmlAttribute ( required = false , name = " oauth " )
2017-07-28 12:09:32 +02:00
@Deprecated
2017-01-30 15:05:08 +01:00
boolean oauthCompatibility = false ;
2016-11-25 15:42:29 +01:00
private static Logger log = LoggerFactory . getLogger ( RequestValidator . class ) ;
private ApplicationContext context ;
@Override
public String getName ( ) {
return Constants . request_validation ;
}
@Override
public void handleRequest ( RequestEvent call ) {
log . trace ( " executing request validator ON REQUEST " ) ;
context = call . context ( ) ;
validateAgainstLifecycle ( call ) ;
2017-01-30 15:05:08 +01:00
2017-07-28 12:09:32 +02:00
rejectUnauthorizedCalls ( call ) ;
validateScopeCall ( ) ;
2020-11-18 18:50:49 +01:00
/ * if ( SecurityTokenProvider . instance . get ( ) ! = null )
validatePolicy ( SecurityTokenProvider . instance . get ( ) , call ) ; * /
2016-11-25 15:42:29 +01:00
}
2017-07-28 12:09:32 +02:00
2016-11-25 15:42:29 +01:00
private void validateAgainstLifecycle ( RequestEvent call ) {
switch ( context . lifecycle ( ) . state ( ) ) {
case stopped :
application_unavailable_error . fire ( ) ; break ;
case failed :
application_failed_error . fire ( ) ; break ;
default :
//nothing to do, but avoids warnings
}
}
2017-07-28 12:09:32 +02:00
private void validateScopeCall ( ) {
String scope = ScopeProvider . instance . get ( ) ;
2016-11-25 15:42:29 +01:00
if ( scope = = null ) {
log . warn ( " rejecting unscoped call to {} " , context . name ( ) ) ;
invalid_request_error . fire ( " call is unscoped " ) ;
}
2017-03-21 14:42:21 +01:00
ScopeBean bean = new ScopeBean ( scope ) ;
ContainerConfiguration conf = context . container ( ) . configuration ( ) ;
if ( ! conf . allowedContexts ( ) . contains ( scope ) & &
! ( conf . authorizeChildrenContext ( ) & & bean . is ( Type . VRE ) & & conf . allowedContexts ( ) . contains ( bean . enclosingScope ( ) . toString ( ) ) ) ) {
2016-11-25 15:42:29 +01:00
log . warn ( " rejecting call to {} in invalid context {}, allowed context are {} " , context . name ( ) , scope , context . container ( ) . configuration ( ) . allowedContexts ( ) ) ;
invalid_request_error . fire ( context . name ( ) + " cannot be called in scope " + scope ) ;
}
}
2017-07-28 12:09:32 +02:00
private void rejectUnauthorizedCalls ( RequestEvent call ) {
2017-01-30 15:05:08 +01:00
2017-07-28 12:09:32 +02:00
String token = SecurityTokenProvider . instance . get ( ) ;
String scope = ScopeProvider . instance . get ( ) ;
2017-01-30 15:05:08 +01:00
2016-11-25 15:42:29 +01:00
if ( token = = null & & scope = = null ) {
log . warn ( " rejecting call to {}, authorization required " , context . name ( ) , token ) ;
2021-02-22 10:09:11 +01:00
//if (call.context().container().configuration().authenticationEnpoint()==null){
RequestError . request_not_authorized_error . fire ( context . name ( ) + " : authorization required " ) ;
/ * } else {
2016-11-25 15:42:29 +01:00
log . info ( " authorization enpoint found on configuration, redirecting the call " ) ;
String recallLocation = String . format ( " http://%s:%d%s " , call . context ( ) . container ( ) . configuration ( ) . hostname ( ) , call . context ( ) . container ( ) . configuration ( ) . port ( ) , call . uri ( ) ) ;
//call.response().setHeader("Allowed-Contexts", call.context().container().configuration().allowedContexts().toString());
try {
call . response ( ) . sendRedirect ( context . container ( ) . configuration ( ) . authenticationEnpoint ( ) + " ?Recall-Location= " + recallLocation ) ;
} catch ( IOException e ) {
log . error ( " errror redirecting call " , e ) ;
}
2021-02-22 10:09:11 +01:00
} * /
2016-11-25 15:42:29 +01:00
}
}
@Override
public String toString ( ) {
2016-11-30 17:27:21 +01:00
return getName ( ) ;
2016-11-25 15:42:29 +01:00
}
2020-11-18 18:50:49 +01:00
/ *
2017-07-28 12:09:32 +02:00
private void validatePolicy ( String token , RequestEvent call ) {
log . info ( " accessing policy validator with token {} " , token ) ;
2016-11-25 15:42:29 +01:00
AuthorizationEntry authEntry = null ;
try {
authEntry = authorizationService ( ) . get ( token ) ;
} catch ( ObjectNotFound onf ) {
log . warn ( " rejecting call to {}, invalid token {} " , context . name ( ) , token ) ;
invalid_request_error . fire ( context . name ( ) + " invalid token : " + token ) ;
} catch ( Exception e ) {
log . error ( " error contacting authorization service " , e ) ;
internal_server_error . fire ( " error contacting authorization service " ) ;
}
ServiceIdentifier serviceIdentifier = Utils . getServiceInfo ( call . context ( ) ) . getServiceIdentifier ( ) ;
for ( Policy policy : authEntry . getPolicies ( ) )
if ( PolicyUtils . isPolicyValidForClient ( policy . getServiceAccess ( ) , serviceIdentifier ) ) {
log . error ( " rejecting call to {} : {} is not allowed to contact the service " , context . name ( ) , authEntry . getClientInfo ( ) . getId ( ) ) ;
invalid_request_error . fire ( " rejecting call to " + context . name ( ) + " : " + authEntry . getClientInfo ( ) . getId ( ) + " is not allowed to contact the service " ) ;
}
2020-11-18 18:50:49 +01:00
} * /
2016-11-30 17:27:21 +01:00
2016-11-25 15:42:29 +01:00
}