2016-11-25 15:42:29 +01:00
package org.gcube.smartgears.handlers.application.request ;
2022-02-07 09:44:31 +01:00
import static org.gcube.common.authorization.client.Constants.authorizationService ;
2016-11-25 15:42:29 +01:00
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 ;
2022-02-07 09:44:31 +01:00
import java.util.List ;
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 ;
2022-02-07 09:44:31 +01:00
import org.gcube.common.authorization.library.PolicyUtils ;
import org.gcube.common.authorization.library.policies.Policy ;
2022-03-04 17:21:10 +01:00
import org.gcube.common.authorization.library.policies.PolicyType ;
import org.gcube.common.authorization.library.policies.ServiceAccess ;
import org.gcube.common.authorization.library.policies.User2ServicePolicy ;
import org.gcube.common.authorization.library.policies.UserEntity ;
2022-02-07 09:44:31 +01:00
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
2016-11-25 15:42:29 +01:00
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
2022-02-07 09:44:31 +01:00
import org.gcube.common.authorization.library.provider.ServiceIdentifier ;
import org.gcube.common.authorization.library.utils.Caller ;
2016-11-25 15:42:29 +01:00
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 ;
2022-02-07 09:44:31 +01:00
import org.gcube.smartgears.configuration.Mode ;
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 ;
2022-02-07 09:44:31 +01:00
import org.gcube.smartgears.utils.Utils ;
2016-11-25 15:42:29 +01:00
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 ;
2022-02-07 09:44:31 +01:00
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 ;
}
2022-02-07 09:44:31 +01:00
2016-11-25 15:42:29 +01:00
@Override
public void handleRequest ( RequestEvent call ) {
log . trace ( " executing request validator ON REQUEST " ) ;
context = call . context ( ) ;
validateAgainstLifecycle ( call ) ;
2022-02-07 09:44:31 +01:00
2017-07-28 12:09:32 +02:00
rejectUnauthorizedCalls ( call ) ;
2022-02-07 09:44:31 +01:00
if ( context . container ( ) . configuration ( ) . mode ( ) ! = Mode . offline ) {
validateScopeCall ( ) ;
validatePolicy ( ScopeProvider . instance . get ( ) , call ) ;
}
2016-11-25 15:42:29 +01:00
}
2022-02-07 09:44:31 +01: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
}
2022-03-04 17:28:40 +01:00
2016-11-25 15:42:29 +01:00
}
2017-07-28 12:09:32 +02:00
private void validateScopeCall ( ) {
2022-02-07 09:44:31 +01:00
2017-07-28 12:09:32 +02:00
String scope = ScopeProvider . instance . get ( ) ;
2022-02-07 09:44:31 +01:00
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 " ) ;
}
2022-02-07 09:44:31 +01:00
2017-03-21 14:42:21 +01:00
ScopeBean bean = new ScopeBean ( scope ) ;
2022-02-07 09:44:31 +01:00
2017-03-21 14:42:21 +01:00
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 ) {
2022-02-07 09:44:31 +01:00
2017-07-28 12:09:32 +02:00
String token = SecurityTokenProvider . instance . get ( ) ;
String scope = ScopeProvider . instance . get ( ) ;
2022-02-07 09:44:31 +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
RequestError . request_not_authorized_error . fire ( context . name ( ) + " : authorization required " ) ;
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
}
2022-02-07 09:44:31 +01:00
private void validatePolicy ( String scope , RequestEvent call ) {
log . info ( " accessing policy validator in scope {} " , scope ) ;
2016-11-25 15:42:29 +01:00
ServiceIdentifier serviceIdentifier = Utils . getServiceInfo ( call . context ( ) ) . getServiceIdentifier ( ) ;
2022-03-04 17:21:10 +01:00
String callerId = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2022-03-04 17:28:40 +01:00
List < Policy > policies = null ;
2022-02-07 09:44:31 +01:00
try {
2022-03-04 17:28:40 +01:00
authorizationService ( ) . getPolicies ( scope ) ;
2022-02-07 09:44:31 +01:00
} catch ( Exception e ) {
2022-03-04 17:28:40 +01:00
invalid_request_error . fire ( " error contating authorization " ) ;
}
for ( Policy policy : policies ) {
log . debug ( " policy: {} " , policy . getPolicyAsString ( ) ) ;
if ( PolicyUtils . isPolicyValidForClient ( policy . getServiceAccess ( ) , serviceIdentifier ) | | isPolicyValidForService ( policy . getServiceAccess ( ) , serviceIdentifier ) ) {
boolean toReject = false ;
UserEntity entity = ( ( ( User2ServicePolicy ) policy ) . getEntity ( ) ) ;
if ( entity . getIdentifier ( ) ! = null )
toReject = entity . getIdentifier ( ) . trim ( ) . equals ( callerId ) ;
else if ( entity . getExcludes ( ) . isEmpty ( ) )
toReject = true ;
else toReject = ! entity . getExcludes ( ) . contains ( callerId ) ;
if ( toReject ) {
log . error ( " rejecting call to {} : {} is not allowed to contact the service " , context . name ( ) , callerId ) ;
RequestError . request_not_authorized_error . fire ( " rejecting call to " + context . name ( ) + " : " + callerId + " is not allowed to contact the service: " + serviceIdentifier . getServiceName ( ) ) ;
}
}
2022-02-07 09:44:31 +01:00
}
2022-03-04 17:28:40 +01:00
2022-02-07 09:44:31 +01:00
}
2022-03-04 17:28:40 +01:00
2022-03-04 17:21:10 +01:00
//TO resolve an error on Auth Portlet
private boolean isPolicyValidForService ( ServiceAccess serviceAccess , ServiceIdentifier serviceId ) {
String policyAsString = serviceAccess . getAsString ( ) ;
2022-03-04 17:28:40 +01:00
2022-03-04 17:21:10 +01:00
return policyAsString . equals ( " ALL " ) | | policyAsString . equals ( serviceId . getServiceClass ( ) + " :ALL:ALL " ) | |
policyAsString . equals ( serviceId . getServiceClass ( ) + " : " + serviceId . getServiceName ( ) + " :ALL " ) | |
policyAsString . equals ( serviceId . getFullIdentifier ( ) ) ;
}
2016-11-25 15:42:29 +01:00
}