RConnector/src/main/java/org/gcube/data/analysis/rconnector/Resource.java

127 lines
4.3 KiB
Java

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;
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;
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
public class Resource {
@Inject
ConfigFileWriter writer;
@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 || login == null || tabularResourceId ==null ) return Response.serverError().build();
Info info;
try{
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, 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 (login == null ) return Response.serverError().build();
Info info = new Info();
info.setUsername(login);
info.setToken(SecurityTokenProvider.instance.get());
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");
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();}
}
}