2015-05-18 19:15:58 +02:00
package org.gcube.common.authorization.client.proxy ;
2015-11-24 19:26:37 +01:00
import static org.gcube.common.authorization.client.Constants.CONTEXT_PARAM ;
2015-05-18 19:15:58 +02:00
2016-01-22 17:28:17 +01:00
import java.io.BufferedOutputStream ;
2015-05-18 19:15:58 +02:00
import java.io.BufferedReader ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
2016-01-22 17:28:17 +01:00
import java.io.OutputStream ;
2015-05-18 19:15:58 +02:00
import java.net.HttpURLConnection ;
import java.net.URL ;
2016-01-22 17:28:17 +01:00
import java.util.ArrayList ;
2015-11-27 18:06:28 +01:00
import java.util.Collections ;
2016-09-22 10:44:15 +02:00
import java.util.HashMap ;
2015-06-04 18:49:59 +02:00
import java.util.List ;
2016-05-13 17:00:54 +02:00
import java.util.Map ;
2016-02-01 15:14:44 +01:00
2015-05-18 19:15:58 +02:00
import org.gcube.common.authorization.client.Binder ;
2016-06-29 14:54:12 +02:00
import org.gcube.common.authorization.client.Constants ;
2015-07-30 17:33:48 +02:00
import org.gcube.common.authorization.client.exceptions.ObjectNotFound ;
2015-05-18 19:15:58 +02:00
import org.gcube.common.authorization.library.AuthorizationEntry ;
2016-01-22 17:28:17 +01:00
import org.gcube.common.authorization.library.Policies ;
2016-09-07 14:11:39 +02:00
import org.gcube.common.authorization.library.QualifiersList ;
2015-11-27 18:06:28 +01:00
import org.gcube.common.authorization.library.enpoints.AuthorizationEndpoint ;
import org.gcube.common.authorization.library.enpoints.AuthorizationEndpointScanner ;
2016-09-22 10:44:15 +02:00
import org.gcube.common.authorization.library.enpoints.EndpointsContainer ;
2016-01-22 17:28:17 +01:00
import org.gcube.common.authorization.library.policies.Policy ;
2016-07-22 14:27:10 +02:00
import org.gcube.common.authorization.library.provider.ContainerInfo ;
2016-06-23 18:14:16 +02:00
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
2016-06-15 13:47:22 +02:00
import org.gcube.common.authorization.library.provider.ServiceInfo ;
2016-01-22 17:28:17 +01:00
import org.gcube.common.authorization.library.provider.UserInfo ;
2015-12-22 19:38:51 +01:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2015-05-18 19:15:58 +02:00
public class DefaultAuthorizationProxy implements AuthorizationProxy {
2015-12-22 19:38:51 +01:00
private static Logger log = LoggerFactory . getLogger ( AuthorizationProxy . class ) ;
2016-09-22 10:44:15 +02:00
private static Map < String , AuthorizationEntryCache > cache = Collections . synchronizedMap ( new HashMap < String , AuthorizationEntryCache > ( ) ) ;
2016-01-22 17:28:17 +01:00
2016-09-22 10:44:15 +02:00
private static EndpointsContainer endpoints ;
2016-06-23 18:14:16 +02:00
2015-11-24 19:26:37 +01:00
public DefaultAuthorizationProxy ( ) {
2016-09-22 10:44:15 +02:00
if ( endpoints = = null )
endpoints = AuthorizationEndpointScanner . endpoints ( ) ;
2015-11-24 19:26:37 +01:00
}
2015-05-21 16:19:37 +02:00
2016-06-23 18:14:16 +02:00
private String getInternalEnpoint ( int infrastructureHash ) {
StringBuilder endpoint = new StringBuilder ( " http:// " ) . append ( getEndpoint ( infrastructureHash ) . getHost ( ) ) . append ( " : " )
. append ( getEndpoint ( infrastructureHash ) . getPort ( ) ) . append ( " /authorization-service/gcube/service " ) ;
2015-11-27 18:06:28 +01:00
return endpoint . toString ( ) ;
}
2016-01-22 17:28:17 +01:00
2015-11-27 18:06:28 +01:00
@Override
2016-07-22 14:27:10 +02:00
public String generateServiceToken ( ServiceInfo client ) throws Exception {
2016-01-22 17:28:17 +01:00
2016-07-22 14:27:10 +02:00
String methodPath = " /token/service " ;
2016-09-22 10:44:15 +02:00
int infrastructureHash = Utils . getInfrastructureHashFromToken ( SecurityTokenProvider . instance . get ( ) , endpoints . getDefaultInfrastructure ( ) ) ;
2016-01-22 17:28:17 +01:00
2016-07-22 14:27:10 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( infrastructureHash ) ) . append ( methodPath ) ;
URL url = new URL ( callUrl . toString ( ) ) ;
HttpURLConnection connection = makeRequest ( url , " PUT " , true ) ;
connection . setDoOutput ( true ) ;
connection . setDoInput ( true ) ;
connection . setRequestProperty ( " Content-type " , " application/xml " ) ;
try ( OutputStream os = new BufferedOutputStream ( connection . getOutputStream ( ) ) ) {
Binder . getContext ( ) . createMarshaller ( ) . marshal ( client , os ) ;
}
log . debug ( " response code for " + callUrl . toString ( ) + " is " + connection . getResponseCode ( ) + " " + connection . getResponseMessage ( ) ) ;
2016-06-23 18:14:16 +02:00
2016-07-22 14:27:10 +02:00
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error contacting authorization service " ) ;
String token = " " ;
try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( ( InputStream ) connection . getContent ( ) ) ) ) {
StringBuilder result = new StringBuilder ( ) ;
String line ;
while ( ( line = reader . readLine ( ) ) ! = null )
result . append ( line ) ;
token = result . toString ( ) ;
}
2016-09-16 10:00:01 +02:00
return Utils . addInfrastructureHashToToken ( token , infrastructureHash ) ;
2016-07-22 14:27:10 +02:00
}
@Override
public String generateUserToken ( UserInfo client , String context ) throws Exception {
String methodPath = " /token/user " ;
2016-09-13 18:14:01 +02:00
int infrastructureHash = Utils . getInfrastructureHashfromContext ( context ) ;
2016-06-23 18:14:16 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( infrastructureHash ) ) . append ( methodPath ) . append ( " ? " )
2015-11-27 18:06:28 +01:00
. append ( CONTEXT_PARAM ) . append ( " = " ) . append ( context ) ;
2016-01-22 17:28:17 +01:00
2015-11-24 19:26:37 +01:00
URL url = new URL ( callUrl . toString ( ) ) ;
2016-06-29 14:54:12 +02:00
HttpURLConnection connection = makeRequest ( url , " PUT " , false ) ;
2016-01-22 17:28:17 +01:00
connection . setDoOutput ( true ) ;
2016-01-26 18:45:27 +01:00
connection . setDoInput ( true ) ;
connection . setRequestProperty ( " Content-type " , " application/xml " ) ;
2016-01-22 17:28:17 +01:00
try ( OutputStream os = new BufferedOutputStream ( connection . getOutputStream ( ) ) ) {
2016-01-26 18:45:27 +01:00
Binder . getContext ( ) . createMarshaller ( ) . marshal ( client , os ) ;
2016-01-22 17:28:17 +01:00
}
2016-01-26 18:45:27 +01:00
2016-06-15 13:47:22 +02:00
log . debug ( " response code for " + callUrl . toString ( ) + " is " + connection . getResponseCode ( ) + " " + connection . getResponseMessage ( ) ) ;
2016-01-26 18:45:27 +01:00
2015-11-24 19:26:37 +01:00
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error contacting authorization service " ) ;
2016-06-29 14:54:12 +02:00
String token = " " ;
2016-01-22 17:28:17 +01:00
try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( ( InputStream ) connection . getContent ( ) ) ) ) {
2015-11-24 19:26:37 +01:00
StringBuilder result = new StringBuilder ( ) ;
String line ;
while ( ( line = reader . readLine ( ) ) ! = null )
result . append ( line ) ;
2016-06-29 14:54:12 +02:00
token = result . toString ( ) ;
2015-05-18 19:15:58 +02:00
}
2015-12-22 19:38:51 +01:00
2016-09-16 10:00:01 +02:00
return Utils . addInfrastructureHashToToken ( token , infrastructureHash ) ;
2015-05-18 19:15:58 +02:00
}
2016-07-14 17:47:45 +02:00
2016-06-15 13:47:22 +02:00
2016-06-29 14:54:12 +02:00
@Override
public String generateApiKey ( String apiQualifier ) throws Exception {
2016-07-14 17:47:45 +02:00
String methodPath = String . format ( " /apikey?qualifier=%s " , apiQualifier ) ;
2016-06-29 14:54:12 +02:00
2016-09-22 10:44:15 +02:00
int infrastructureHash = Utils . getInfrastructureHashFromToken ( SecurityTokenProvider . instance . get ( ) , endpoints . getDefaultInfrastructure ( ) ) ;
2016-06-29 14:54:12 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( infrastructureHash ) ) . append ( methodPath ) ;
URL url = new URL ( callUrl . toString ( ) ) ;
HttpURLConnection connection = makeRequest ( url , " PUT " , true ) ;
connection . setDoInput ( true ) ;
connection . setRequestProperty ( " Content-type " , " application/xml " ) ;
log . debug ( " response code for " + callUrl . toString ( ) + " is " + connection . getResponseCode ( ) + " " + connection . getResponseMessage ( ) ) ;
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error contacting authorization service " ) ;
String token = " " ;
try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( ( InputStream ) connection . getContent ( ) ) ) ) {
StringBuilder result = new StringBuilder ( ) ;
String line ;
while ( ( line = reader . readLine ( ) ) ! = null )
result . append ( line ) ;
token = result . toString ( ) ;
}
2016-09-16 10:00:01 +02:00
return Utils . addInfrastructureHashToToken ( token , infrastructureHash ) ;
2016-06-29 14:54:12 +02:00
}
2016-09-07 14:11:39 +02:00
@Override
/ * *
* return a map with key qualifier and value token
* /
public Map < String , String > retrieveApiKeys ( ) throws Exception {
String methodPath = " /apikey/ " ;
2016-09-22 10:44:15 +02:00
int infrastructureHash = Utils . getInfrastructureHashFromToken ( SecurityTokenProvider . instance . get ( ) , endpoints . getDefaultInfrastructure ( ) ) ;
2016-09-07 14:11:39 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( infrastructureHash ) ) . append ( methodPath ) ;
2016-09-08 17:42:02 +02:00
2016-09-07 14:11:39 +02:00
URL url = new URL ( callUrl . toString ( ) ) ;
HttpURLConnection connection = makeRequest ( url , " GET " , true ) ;
connection . setDoInput ( true ) ;
connection . setDoOutput ( true ) ;
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error retrieving keys (error code is " + connection . getResponseCode ( ) + " ) " ) ;
if ( connection . getContentLengthLong ( ) < = 0 ) return Collections . emptyMap ( ) ;
try ( InputStream stream = ( InputStream ) connection . getContent ( ) ; ) {
QualifiersList entries = ( QualifiersList ) Binder . getContext ( ) . createUnmarshaller ( ) . unmarshal ( stream ) ;
return entries . getQualifiers ( ) ;
}
}
2016-06-29 14:54:12 +02:00
2016-09-13 18:14:01 +02:00
2016-06-23 18:14:16 +02:00
2016-06-15 13:47:22 +02:00
@Override
2016-07-22 14:27:10 +02:00
public String requestActivation ( ContainerInfo container , String context ) throws Exception {
2016-06-15 13:47:22 +02:00
2016-07-22 14:27:10 +02:00
String methodPath = " /token/node " ;
2016-06-15 13:47:22 +02:00
2016-09-16 10:00:01 +02:00
int infrastructureHash = Utils . getInfrastructureHashfromContext ( context ) ;
2016-07-22 14:27:10 +02:00
StringBuilder callUrl =
2016-09-16 10:00:01 +02:00
new StringBuilder ( getInternalEnpoint ( infrastructureHash ) ) . append ( methodPath ) . append ( " ? " )
2016-06-15 13:47:22 +02:00
. append ( CONTEXT_PARAM ) . append ( " = " ) . append ( context ) ;
URL url = new URL ( callUrl . toString ( ) ) ;
2016-07-22 14:27:10 +02:00
HttpURLConnection connection = makeRequest ( url , " PUT " , false ) ;
2016-06-15 13:47:22 +02:00
connection . setDoOutput ( true ) ;
connection . setDoInput ( true ) ;
connection . setRequestProperty ( " Content-type " , " application/xml " ) ;
try ( OutputStream os = new BufferedOutputStream ( connection . getOutputStream ( ) ) ) {
Binder . getContext ( ) . createMarshaller ( ) . marshal ( container , os ) ;
}
log . debug ( " response code is " + connection . getResponseCode ( ) ) ;
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error contacting authorization service " ) ;
2016-07-22 14:27:10 +02:00
String token = " " ;
2016-06-15 13:47:22 +02:00
try ( BufferedReader reader = new BufferedReader ( new InputStreamReader ( ( InputStream ) connection . getContent ( ) ) ) ) {
StringBuilder result = new StringBuilder ( ) ;
String line ;
while ( ( line = reader . readLine ( ) ) ! = null )
result . append ( line ) ;
2016-07-22 14:27:10 +02:00
token = result . toString ( ) ;
2016-06-15 13:47:22 +02:00
}
2016-09-16 10:00:01 +02:00
return Utils . addInfrastructureHashToToken ( token , infrastructureHash ) ;
2016-06-15 13:47:22 +02:00
}
2015-05-29 18:32:43 +02:00
@Override
2016-01-22 17:28:17 +01:00
public AuthorizationEntry get ( String token ) throws ObjectNotFound , Exception {
2016-09-22 10:44:15 +02:00
String realToken = Utils . getRealToken ( token ) ;
int infrastructureHashFromToken = Utils . getInfrastructureHashFromToken ( token , endpoints . getDefaultInfrastructure ( ) ) ;
AuthorizationEndpoint endpoint = getEndpoint ( infrastructureHashFromToken ) ;
if ( cache . containsKey ( realToken ) & & cache . get ( realToken ) . isValid ( endpoint . getClientCacheValidity ( ) ) ) {
2016-09-22 19:07:14 +02:00
log . trace ( " valid entry found in cache for token {}, returning it " , String . format ( " %s******** " , realToken . substring ( 0 , realToken . length ( ) - 8 ) ) ) ;
2016-09-22 10:44:15 +02:00
return cache . get ( realToken ) . getEntry ( ) ;
} else
2016-09-22 19:07:14 +02:00
log . trace ( " invalid entry found in cache for token {}, contacting auth service " , String . format ( " %s******** " , realToken . substring ( 0 , realToken . length ( ) - 8 ) ) ) ;
2016-02-01 15:14:44 +01:00
2016-07-14 17:47:45 +02:00
final String methodPath = " /token/ " ;
2015-11-24 19:26:37 +01:00
2016-09-22 10:44:15 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( infrastructureHashFromToken ) )
. append ( methodPath ) . append ( realToken ) ;
2015-12-22 19:38:51 +01:00
2015-11-24 19:26:37 +01:00
URL url = new URL ( callUrl . toString ( ) ) ;
2016-06-29 14:54:12 +02:00
HttpURLConnection connection = makeRequest ( url , " GET " , false ) ;
2016-01-22 17:28:17 +01:00
connection . setDoInput ( true ) ;
2015-11-24 19:26:37 +01:00
if ( connection . getResponseCode ( ) = = 404 ) throw new ObjectNotFound ( " token " + token + " not found " ) ;
2016-07-14 17:47:45 +02:00
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error contacting authorization service (error code is " + connection . getResponseCode ( ) + " ) " ) ;
2015-11-24 19:26:37 +01:00
if ( connection . getContentLengthLong ( ) < = 0 ) return null ;
try ( InputStream stream = ( InputStream ) connection . getContent ( ) ; ) {
AuthorizationEntry entry = ( AuthorizationEntry ) Binder . getContext ( ) . createUnmarshaller ( ) . unmarshal ( stream ) ;
2016-09-22 10:44:15 +02:00
if ( entry ! = null ) cache . put ( realToken , new AuthorizationEntryCache ( entry ) ) ;
2015-11-24 19:26:37 +01:00
return entry ;
2015-05-29 18:32:43 +02:00
}
}
2016-09-22 10:44:15 +02:00
2016-01-22 17:28:17 +01:00
2015-05-29 18:32:43 +02:00
@Override
2016-01-22 17:28:17 +01:00
public void addPolicies ( List < Policy > policies ) throws Exception {
final String methodPath = " /policyManager " ;
2015-11-24 19:26:37 +01:00
2016-09-22 10:44:15 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( Utils . getInfrastructureHashFromToken ( SecurityTokenProvider . instance . get ( ) , endpoints . getDefaultInfrastructure ( ) ) ) ) . append ( methodPath ) ;
2016-01-22 17:28:17 +01:00
URL url = new URL ( callUrl . toString ( ) ) ;
2016-06-29 14:54:12 +02:00
HttpURLConnection connection = makeRequest ( url , " POST " , true ) ;
2016-01-22 17:28:17 +01:00
connection . setDoOutput ( true ) ;
2016-01-26 18:45:27 +01:00
connection . setRequestProperty ( " Content-type " , " application/xml " ) ;
2016-01-22 17:28:17 +01:00
try ( OutputStream os = new BufferedOutputStream ( connection . getOutputStream ( ) ) ) {
2016-01-26 18:45:27 +01:00
Binder . getContext ( ) . createMarshaller ( ) . marshal ( new Policies ( policies ) , os ) ;
2015-05-29 18:32:43 +02:00
}
2016-01-22 17:28:17 +01:00
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error adding policies " ) ;
2015-05-29 18:32:43 +02:00
}
2015-05-18 19:15:58 +02:00
2015-06-04 18:49:59 +02:00
@Override
2016-01-22 17:28:17 +01:00
public void removePolicies ( long . . . ids ) throws Exception {
final String methodPath = " /policyManager/ " ;
2016-09-22 10:44:15 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( Utils . getInfrastructureHashFromToken ( SecurityTokenProvider . instance . get ( ) , endpoints . getDefaultInfrastructure ( ) ) ) ) . append ( methodPath ) ;
2016-01-22 17:28:17 +01:00
List < Long > errorIds = new ArrayList < Long > ( ) ;
for ( long id : ids ) {
URL url = new URL ( callUrl . toString ( ) + id ) ;
2016-06-29 14:54:12 +02:00
HttpURLConnection connection = makeRequest ( url , " DELETE " , true ) ;
2016-01-22 17:28:17 +01:00
if ( connection . getResponseCode ( ) ! = 200 ) errorIds . add ( id ) ;
}
if ( ! errorIds . isEmpty ( ) )
throw new Exception ( " error removing policies with ids: " + errorIds ) ;
2015-11-24 19:26:37 +01:00
}
2015-06-04 18:49:59 +02:00
2015-11-24 19:26:37 +01:00
@Override
2016-01-22 17:28:17 +01:00
public List < Policy > getPolicies ( String context ) throws Exception {
final String methodPath = " /policyManager/ " ;
2016-08-30 11:29:19 +02:00
2016-09-13 18:14:01 +02:00
StringBuilder callUrl = new StringBuilder ( getInternalEnpoint ( Utils . getInfrastructureHashfromContext ( context ) ) ) . append ( methodPath ) . append ( " ? " ) . append ( CONTEXT_PARAM ) . append ( " = " ) . append ( context ) ;
2016-01-22 17:28:17 +01:00
URL url = new URL ( callUrl . toString ( ) ) ;
2016-06-29 14:54:12 +02:00
HttpURLConnection connection = makeRequest ( url , " GET " , true ) ;
2016-01-26 18:45:27 +01:00
connection . setDoInput ( true ) ;
2016-01-22 17:28:17 +01:00
if ( connection . getResponseCode ( ) ! = 200 ) throw new Exception ( " error retrieving policies " ) ;
2016-01-26 18:45:27 +01:00
if ( connection . getContentLengthLong ( ) < = 0 ) return Collections . emptyList ( ) ;
2015-06-04 18:49:59 +02:00
2016-01-26 18:45:27 +01:00
try ( InputStreamReader stream = new InputStreamReader ( ( InputStream ) connection . getContent ( ) ) ) {
2016-01-22 17:28:17 +01:00
Policies policies = ( Policies ) Binder . getContext ( ) . createUnmarshaller ( ) . unmarshal ( stream ) ;
return policies . getPolicies ( ) ;
2015-06-04 18:49:59 +02:00
}
}
2016-01-22 17:28:17 +01:00
2016-06-29 14:54:12 +02:00
private HttpURLConnection makeRequest ( URL url , String method , boolean includeTokenInHeader ) throws Exception {
2015-06-04 18:49:59 +02:00
HttpURLConnection connection = ( HttpURLConnection ) url . openConnection ( ) ;
2016-08-30 11:29:19 +02:00
if ( includeTokenInHeader ) {
if ( SecurityTokenProvider . instance . get ( ) = = null ) throw new RuntimeException ( " null token passed " ) ;
2016-09-16 10:00:01 +02:00
connection . setRequestProperty ( Constants . TOKEN_HEADER_ENTRY , Utils . getRealToken ( SecurityTokenProvider . instance . get ( ) ) ) ;
2016-08-30 11:29:19 +02:00
}
2015-06-04 18:49:59 +02:00
connection . setRequestMethod ( method ) ;
return connection ;
}
2015-11-27 18:06:28 +01:00
@Override
2016-06-23 18:14:16 +02:00
public AuthorizationEndpoint getEndpoint ( int infrastructureHash ) {
2016-09-22 10:44:15 +02:00
if ( ! endpoints . getEndpoints ( ) . containsKey ( infrastructureHash ) )
2016-06-23 18:14:16 +02:00
throw new RuntimeException ( " Authorization Endpoint not found for the required infrastructure " ) ;
2016-09-22 10:44:15 +02:00
return endpoints . getEndpoints ( ) . get ( infrastructureHash ) ;
2015-11-27 18:06:28 +01:00
}
@Override
2016-09-22 10:44:15 +02:00
public void setEndpoint ( EndpointsContainer newEndpoints ) {
endpoints = newEndpoints ;
2015-11-27 18:06:28 +01:00
}
2016-08-30 11:29:19 +02:00
2016-01-22 17:28:17 +01:00
2015-05-18 19:15:58 +02:00
}