@ -1,9 +1,11 @@
package org.gcube.data.analysis.rconnector ;
import java.io.File ;
import java.io.IOException ;
import java.net.URI ;
import java.net.URLEncoder ;
import java.nio.file.Files ;
import java.nio.file.Paths ;
import java.text.SimpleDateFormat ;
import java.util.Calendar ;
import java.util.Locale ;
@ -20,11 +22,12 @@ import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response ;
import javax.xml.bind.DatatypeConverter ;
import lombok.extern.slf4j.Slf4j ;
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.data.access.storagehub.fs.StorageHubFS ;
import lombok.extern.slf4j.Slf4j ;
@Path ( "connect/" )
@Slf4j
@ -35,85 +38,89 @@ public class Resource {
@Inject
InfoRetriever infoRetriever ;
@Context ServletContext context ;
@Path ( "/{trId}" )
@GET
public Response connect ( @PathParam ( "trId" ) Long tabularResourceId ) {
log . info ( "connect called with user {} and trID {} in scope {}" , AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) , tabularResourceId , ScopeProvider . instance . get ( ) ) ;
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
String usersHome = context . getInitParameter ( "usersHome" ) ;
String filename = context . getInitParameter ( "filename" ) ;
String scriptToExecute = context . getInitParameter ( "addUserScript" ) ;
if ( ScopeProvider . instance . get ( ) = = null | | AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) = = null | | tabularResourceId = = null ) return Response . serverError ( ) . build ( ) ;
if ( ScopeProvider . instance . get ( ) = = null | | login = = null | | tabularResourceId = = null ) return Response . serverError ( ) . build ( ) ;
Info info ;
try {
info = infoRetriever . retrieve ( AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) , tabularResourceId ) ;
info = infoRetriever . retrieve ( login , tabularResourceId ) ;
log . debug ( "retrieved info: " + info ) ;
} catch ( Exception e ) {
log . error ( "error connecting to r" , e ) ;
return Response . serverError ( ) . build ( ) ;
}
if ( ! writer . write ( info , AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
return createResponse ( AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) ) ;
if ( ! writer . write ( info , login , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
return createResponse ( login ) ;
}
@GET
public Response connect ( ) {
log . info ( "connect called with user {} in scope {}" , AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) , ScopeProvider . instance . get ( ) ) ;
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
String usersHome = context . getInitParameter ( "usersHome" ) ;
String filename = context . getInitParameter ( "filename" ) ;
String scriptToExecute = context . getInitParameter ( "addUserScript" ) ;
if ( AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) = = null ) return Response . serverError ( ) . build ( ) ;
if ( login = = null ) return Response . serverError ( ) . build ( ) ;
Info info = new Info ( ) ;
info . setUsername ( AuthorizationProvider. instance . get ( ) . getClient ( ) . getId ( ) ) ;
info . setUsername ( login ) ;
info . setToken ( SecurityTokenProvider . instance . get ( ) ) ;
if ( ! writer . write ( info , AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
if ( ! writer . write ( info , login , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
return createResponse ( AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ) ;
}
private Response createResponse ( String userName ) {
try {
String keyFilePath = context . getInitParameter ( "storedKeyPath" ) ;
String rStudioServerAddress = context . getInitParameter ( "rStudioAddress" ) ;
log . debug ( "key file path: " + keyFilePath ) ;
log . debug ( "rstudio server address: " + rStudioServerAddress ) ;
Calendar now = Calendar . getInstance ( ) ;
now . add ( Calendar . YEAR , 10 ) ;
now . add ( Calendar . DAY_OF_YEAR , - 1 ) ;
SimpleDateFormat sdf = new SimpleDateFormat ( "EEE, dd MMM yyyy HH:mm:ss z" , Locale . ENGLISH ) ;
String format = sdf . format ( now . getTime ( ) ) ;
File keyFile = new File ( keyFilePath ) ;
if ( ! keyFile . exists ( ) )
return Response . serverError ( ) . build ( ) ;
byte [ ] keyByte = Files . readAllBytes ( keyFile . toPath ( ) ) ;
SecretKeySpec keySpec = new SecretKeySpec ( keyByte ,
"HmacSHA256" ) ;
"HmacSHA256" ) ;
Mac mac = Mac . getInstance ( "HmacSHA256" ) ;
mac . init ( keySpec ) ;
byte [ ] result = mac . doFinal ( ( userName + format ) . getBytes ( ) ) ;
String encoded = URLEncoder . encode ( DatatypeConverter . printBase64Binary ( result ) ) ;
String cookieValue = userName + "|" + URLEncoder . encode ( format ) . replaceAll ( "\\+" , "%20" ) + "|" + encoded ;
NewCookie cookie = new NewCookie ( "user-id" ,
cookieValue ,
"/" , rStudioServerAddress , "" , - 1 , false , true ) ;
return Response . seeOther ( new URI ( "http://" + rStudioServerAddress ) )
. cookie ( cookie ) . build ( ) ;
} catch ( Exception e ) {
log . error ( "error creating response" , e ) ;
return Response . serverError ( ) . build ( ) ; }
}
}