2016-02-01 15:14:44 +01:00
package org.gcube.common.authorization.client.helper ;
import static org.gcube.common.authorization.client.Constants.authorizationService ;
import java.lang.reflect.Method ;
import java.util.Arrays ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import javassist.util.proxy.MethodHandler ;
import javassist.util.proxy.ProxyFactory ;
import javassist.util.proxy.ProxyObject ;
import org.gcube.common.authorization.client.exceptions.UnauthorizedAccessException ;
import org.gcube.common.authorization.library.AuthorizationEntry ;
import org.gcube.common.authorization.library.PolicyUtils ;
import org.gcube.common.authorization.library.annotations.AuthorizationControl ;
2016-02-05 17:23:25 +01:00
import org.gcube.common.authorization.library.policies.Action ;
2016-02-01 15:14:44 +01:00
import org.gcube.common.authorization.library.policies.Policy ;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
import org.gcube.common.authorization.library.provider.ServiceIdentifier ;
/ * *
* enables authorization control on classes using proxies
*
* when a user in not allowed to call a method annotated with { @link AuthorizationControl }
* an { @link UnauthorizedAccessException } is thrown
*
* @author lucio lelii
*
* /
public class Authorization {
private static Map < Class < ? > , Class < ? > > proxyClassMap = new HashMap < Class < ? > , Class < ? > > ( ) ;
private static ProxyFactory proxyfactory = new ProxyFactory ( ) ;
private static Class < ? > getProxied ( Class < ? > proxyClass ) {
if ( proxyClassMap . containsKey ( proxyClass ) )
return proxyClassMap . get ( proxyClass ) ;
proxyfactory . setSuperclass ( proxyClass ) ;
Class < ? > proxied = proxyfactory . createClass ( ) ;
proxyClassMap . put ( proxyClass , proxied ) ;
return proxied ;
}
public static < T extends Authorizable > T getAuthorizedInstance ( Class < T > proxyClass ) {
Class < ? > proxied = getProxied ( proxyClass ) ;
Object obj ;
try {
obj = proxied . newInstance ( ) ;
MethodHandler handler = new MethodHandler ( ) {
public Object invoke ( Object self , Method thisMethod , Method proceed ,
Object [ ] args ) throws Throwable {
if ( thisMethod . isAnnotationPresent ( AuthorizationControl . class ) & & ! thisMethod . getName ( ) . equals ( " getServiceName " )
& & ! thisMethod . getName ( ) . equals ( " getServiceClass " ) ) {
if ( SecurityTokenProvider . instance . get ( ) = = null )
throw new RuntimeException ( " the Security token is not set " ) ;
Authorizable obj = ( Authorizable ) self ;
2016-02-05 17:23:25 +01:00
Action [ ] modes = null ;
2016-02-01 15:14:44 +01:00
if ( thisMethod . isAnnotationPresent ( AuthorizationControl . class ) )
modes = thisMethod . getAnnotation ( AuthorizationControl . class ) . check ( ) ;
checkAuthorization ( obj . getServiceClass ( ) , obj . getServiceName ( ) , modes ) ;
}
return proceed . invoke ( self , args ) ;
}
} ;
( ( ProxyObject ) obj ) . setHandler ( handler ) ;
return proxyClass . cast ( obj ) ;
} catch ( InstantiationException | IllegalAccessException e ) {
throw new RuntimeException ( e ) ;
}
}
2016-02-05 17:23:25 +01:00
public static void checkAuthorization ( String serviceClass , String serviceName , Action . . . modes ) throws Exception {
2016-02-01 15:14:44 +01:00
if ( modes = = null | | modes . length = = 0 ) return ;
if ( SecurityTokenProvider . instance . get ( ) = = null )
throw new UnauthorizedAccessException ( " the Security token is not set " ) ;
2016-02-05 17:23:25 +01:00
List < Action > modesList = Arrays . asList ( modes ) ;
2016-02-01 15:14:44 +01:00
AuthorizationEntry entry = authorizationService ( ) . get ( SecurityTokenProvider . instance . get ( ) ) ;
if ( entry . getPolicies ( ) ! = null ) {
//DO we need a library identifier ??
ServiceIdentifier serviceIdentifier = new ServiceIdentifier ( serviceClass , serviceName , " * " ) ;
for ( Policy policy : entry . getPolicies ( ) )
if ( PolicyUtils . isPolicyValidForClient ( policy . getServiceAccess ( ) , serviceIdentifier ) )
2016-02-05 17:23:25 +01:00
if ( modesList . contains ( policy . getMode ( ) ) | | policy . getMode ( ) = = Action . ALL )
2016-02-01 15:14:44 +01:00
throw new UnauthorizedAccessException ( " the invoked method is protected by the Authorization system, cannot be invoked by " + entry . getClientInfo ( ) . getId ( ) ) ;
}
}
}