2016-10-03 12:43:47 +02:00
package org.gcube.data.analysis.rconnector ;
import java.io.File ;
2019-04-08 17:09:18 +02:00
import java.io.IOException ;
2016-10-03 12:43:47 +02:00
import java.net.URI ;
import java.net.URLEncoder ;
import java.nio.file.Files ;
2019-04-08 17:09:18 +02:00
import java.nio.file.Paths ;
2016-10-03 12:43:47 +02:00
import java.text.SimpleDateFormat ;
import java.util.Calendar ;
import java.util.Locale ;
import javax.crypto.Mac ;
import javax.crypto.spec.SecretKeySpec ;
import javax.inject.Inject ;
import javax.servlet.ServletContext ;
import javax.ws.rs.GET ;
import javax.ws.rs.Path ;
import javax.ws.rs.PathParam ;
import javax.ws.rs.core.Context ;
import javax.ws.rs.core.NewCookie ;
import javax.ws.rs.core.Response ;
import javax.xml.bind.DatatypeConverter ;
import org.gcube.common.authorization.library.provider.AuthorizationProvider ;
2016-11-25 15:56:12 +01:00
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
2016-10-03 12:43:47 +02:00
import org.gcube.common.scope.api.ScopeProvider ;
2019-04-08 17:09:18 +02:00
import org.gcube.data.access.storagehub.fs.StorageHubFS ;
import lombok.extern.slf4j.Slf4j ;
2016-10-03 12:43:47 +02:00
@Path ( " connect/ " )
@Slf4j
public class Resource {
@Inject
ConfigFileWriter writer ;
@Inject
InfoRetriever infoRetriever ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
@Context ServletContext context ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
@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 ( ) ) ;
2019-04-08 17:09:18 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2016-10-03 12:43:47 +02:00
String usersHome = context . getInitParameter ( " usersHome " ) ;
String filename = context . getInitParameter ( " filename " ) ;
String scriptToExecute = context . getInitParameter ( " addUserScript " ) ;
2019-04-08 17:09:18 +02:00
if ( ScopeProvider . instance . get ( ) = = null | | login = = null | | tabularResourceId = = null ) return Response . serverError ( ) . build ( ) ;
2016-10-03 12:43:47 +02:00
Info info ;
try {
2019-04-08 17:09:18 +02:00
info = infoRetriever . retrieve ( login , tabularResourceId ) ;
2016-10-03 12:43:47 +02:00
log . debug ( " retrieved info: " + info ) ;
} catch ( Exception e ) {
log . error ( " error connecting to r " , e ) ;
return Response . serverError ( ) . build ( ) ;
}
2019-04-08 17:09:18 +02:00
if ( ! writer . write ( info , login , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
return createResponse ( login ) ;
2016-10-03 12:43:47 +02:00
}
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
@GET
public Response connect ( ) {
log . info ( " connect called with user {} in scope {} " , AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) , ScopeProvider . instance . get ( ) ) ;
2019-04-08 17:09:18 +02:00
String login = AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ;
2016-10-03 12:43:47 +02:00
String usersHome = context . getInitParameter ( " usersHome " ) ;
String filename = context . getInitParameter ( " filename " ) ;
String scriptToExecute = context . getInitParameter ( " addUserScript " ) ;
2019-04-08 17:09:18 +02:00
if ( login = = null ) return Response . serverError ( ) . build ( ) ;
2016-10-03 12:43:47 +02:00
Info info = new Info ( ) ;
2019-04-08 17:09:18 +02:00
info . setUsername ( login ) ;
2016-11-25 15:56:12 +01:00
info . setToken ( SecurityTokenProvider . instance . get ( ) ) ;
2019-04-08 17:09:18 +02:00
if ( ! writer . write ( info , login , usersHome , filename , scriptToExecute ) ) return Response . serverError ( ) . build ( ) ;
2016-10-03 12:43:47 +02:00
return createResponse ( AuthorizationProvider . instance . get ( ) . getClient ( ) . getId ( ) ) ;
}
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
private Response createResponse ( String userName ) {
try {
String keyFilePath = context . getInitParameter ( " storedKeyPath " ) ;
String rStudioServerAddress = context . getInitParameter ( " rStudioAddress " ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
log . debug ( " key file path: " + keyFilePath ) ;
log . debug ( " rstudio server address: " + rStudioServerAddress ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
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 ( ) ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
File keyFile = new File ( keyFilePath ) ;
if ( ! keyFile . exists ( ) )
return Response . serverError ( ) . build ( ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
byte [ ] keyByte = Files . readAllBytes ( keyFile . toPath ( ) ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
SecretKeySpec keySpec = new SecretKeySpec ( keyByte ,
2019-04-08 17:09:18 +02:00
" HmacSHA256 " ) ;
2016-10-03 12:43:47 +02:00
Mac mac = Mac . getInstance ( " HmacSHA256 " ) ;
mac . init ( keySpec ) ;
byte [ ] result = mac . doFinal ( ( userName + format ) . getBytes ( ) ) ;
String encoded = URLEncoder . encode ( DatatypeConverter . printBase64Binary ( result ) ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
String cookieValue = userName + " | " + URLEncoder . encode ( format ) . replaceAll ( " \\ + " , " %20 " ) + " | " + encoded ;
NewCookie cookie = new NewCookie ( " user-id " ,
cookieValue ,
" / " , rStudioServerAddress , " " , - 1 , false , true ) ;
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
return Response . seeOther ( new URI ( " http:// " + rStudioServerAddress ) )
. cookie ( cookie ) . build ( ) ;
} catch ( Exception e ) {
log . error ( " error creating response " , e ) ;
return Response . serverError ( ) . build ( ) ; }
}
2019-04-08 17:09:18 +02:00
2016-10-03 12:43:47 +02:00
}