diff --git a/.settings/.gitignore b/.settings/.gitignore
new file mode 100644
index 0000000..3b1537c
--- /dev/null
+++ b/.settings/.gitignore
@@ -0,0 +1 @@
+/org.eclipse.jdt.core.prefs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cdc18b..36faec6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
# Changelog for org.gcube.spatial.data.ws-thredds
+## [v1.0.0-SNAPSHOT]
+Integration with new IAM
+Security Fixes
+
+
## [v0.2.5]
Fixes #21265
diff --git a/pom.xml b/pom.xml
index d0d1c2e..72db0fb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
org.gcube.spatial.data
ws-thredds
- 0.2.5
+ 1.0.0-SNAPSHOT
ws-thredds
prototype of WS integration with data-transfer for Thredds pubblication
@@ -42,12 +42,6 @@
org.gcube.spatial.data
sdi-library
[1.0.0-SNAPSHOT,1.3.0-SNAPSHOT)
-
-
- com.fasterxml.jackson.core
- jackson-annotations
-
-
@@ -63,17 +57,6 @@
[1.2.0-SNAPSHOT,2.0.0-SNAPSHOT)
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/TokenSetter.java b/src/main/java/org/gcube/usecases/ws/thredds/TokenSetter.java
index 4253f33..78de3c8 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/TokenSetter.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/TokenSetter.java
@@ -21,7 +21,6 @@ public class TokenSetter {
public static synchronized void set(String scope){
- try{
if(props==null) {
props=new Properties();
try {
@@ -30,12 +29,8 @@ public class TokenSetter {
throw new RuntimeException("YOU NEED TO SET TOKEN FILE IN CONFIGURATION");
}
}
- if(!props.containsKey(scope)) throw new Exception("No token found for scope : "+scope);
+ if(!props.containsKey(scope)) throw new RuntimeException("No token found for scope : "+scope);
SecurityTokenProvider.instance.set(props.getProperty(scope));
- }catch(Throwable e){
- log.trace("Unable to set token for scope "+scope,e);
- }
- ScopeProvider.instance.set(scope);
}
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Process.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Process.java
index d3134d6..c2bba7b 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Process.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Process.java
@@ -59,14 +59,15 @@ public class Process {
private CompletionCallback callback=null;
public Process(String folderId,CompletionCallback callback) throws WorkspaceInteractionException, InternalException {
- log.debug("Created Process with id {} ",processId);
+ String operator=Security.getToken();
+ log.debug("Created Process with id {}, operator {} ",processId,operator);
// this.folderId=folderId;
manager=new WorkspaceFolderManager(folderId);
manager.lock(processId);
SynchFolderConfiguration folderConfig=manager.getSynchConfiguration();
- try {
- descriptor=new ProcessDescriptor(folderId, manager.getTheFolder().get().getPath(),System.currentTimeMillis(),processId,folderConfig);
+ try {
+ descriptor=new ProcessDescriptor(folderId, manager.getTheFolder().get().getPath(),System.currentTimeMillis(),processId,operator,folderConfig);
}catch(Exception e) {
throw new WorkspaceInteractionException("Unable to read path from folder "+folderId,e);
}
@@ -225,7 +226,7 @@ public class Process {
}
String relativePath=toScanFolder.get().getMetadata().getMap().get(Constants.WorkspaceProperties.REMOTE_PATH)+"";
- ThreddsController folderController=new ThreddsController(relativePath,config.getTargetToken());
+ ThreddsController folderController=new ThreddsController(relativePath,ownerProcess.getDescriptor().getOperator());
RemoteFileDescriptor folderDesc=null;
try{
@@ -305,7 +306,7 @@ public class Process {
}catch(ItemNotFoundException e) {
log.info("Creating folder {} under {} ",item,folderPath);
folder=toScanFolder.newFolder(item, "Imported from thredds");
- WorkspaceUtils.initProperties(folder,relativePath+"/"+item , config.getFilter(), config.getTargetToken(),config.getToCreateCatalogName(),config.getValidateMetadata(),config.getRootFolderId());
+ WorkspaceUtils.initProperties(folder,relativePath+"/"+item , config.getFilter(), ownerProcess.getDescriptor().getOperator(),config.getToCreateCatalogName(),config.getValidateMetadata(),config.getRootFolderId());
generateRequests(ownerProcess, service, folder);
}
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/ProcessDescriptor.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/ProcessDescriptor.java
index e7bc75a..d84d293 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/ProcessDescriptor.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/ProcessDescriptor.java
@@ -14,6 +14,8 @@ public class ProcessDescriptor implements Cloneable{
private long launchTime;
private String processId;
+ private String operator;
+
private SynchFolderConfiguration synchConfiguration;
@Override
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Security.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Security.java
new file mode 100644
index 0000000..6212533
--- /dev/null
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/Security.java
@@ -0,0 +1,57 @@
+package org.gcube.usecases.ws.thredds.engine.impl;
+
+import static org.gcube.common.authorization.client.Constants.authorizationService;
+
+import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
+import org.gcube.common.authorization.library.AuthorizationEntry;
+import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
+import org.gcube.common.scope.api.ScopeProvider;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Security {
+
+ public static String getCurrentScope(){
+ try{
+ String token=SecurityTokenProvider.instance.get();
+ log.debug("Token is : "+token);
+ if(token==null) throw new Exception("Security Token is null");
+ AuthorizationEntry entry = authorizationService().get(token);
+ return entry.getContext();
+ }catch(Exception e ){
+ log.debug("Unable to resolve token, checking scope provider..",e);
+ return ScopeProvider.instance.get();
+ }
+ }
+
+
+ public static String getContext(String token) {
+ try{
+ log.debug("Resolving token {} ",token);
+ AuthorizationEntry entry = authorizationService().get(token);
+ return entry.getContext();
+ }catch(Exception e) {
+ log.warn("Unable to resolve "+token,e);
+ return null;
+ }
+ }
+
+ public static String getToken() {
+ return SecurityTokenProvider.instance.get();
+ }
+
+
+ public static String getCurrentCaller(){
+ try{
+ String token=SecurityTokenProvider.instance.get();
+ log.debug("Token is : "+token);
+ if(token==null) throw new Exception("Security Token is null");
+ AuthorizationEntry entry = authorizationService().get(token);
+ return entry.getClientInfo().getId();
+ }catch(Exception e ){
+ log.debug("Unable to resolve token, checking scope provider..",e);
+ return "Unidentified data-transfer user";
+ }
+ }
+}
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java
index 86d371a..fc5b448 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java
@@ -11,6 +11,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.data.transfer.model.plugins.thredds.DataSetScan;
import org.gcube.data.transfer.model.plugins.thredds.ThreddsCatalog;
import org.gcube.data.transfer.model.plugins.thredds.ThreddsInfo;
@@ -138,6 +139,16 @@ public class SynchEngineImpl implements SyncEngine{
if (!manager.isSynched()) throw new WorkspaceNotSynchedException("Folder "+folderId+" is not configured for synchronization.");
if(manager.isLocked()) throw new WorkspaceLockedException("Folder "+folderId+"is locked by an external process.");
if(!manager.isRoot()) throw new WorkspaceFolderNotRootException("Unable to launch synch operation. Folder "+folderId+" is not root configuration");
+
+ String callerContext=Security.getCurrentScope();
+ log.debug("Checking context. Caller is {} ",callerContext);
+
+ String configurationContext=Security.getContext(manager.getSynchConfiguration().getTargetToken());
+
+ if(!callerContext.equals(configurationContext))
+ throw new WorkspaceInteractionException("Cannot sync folder from context "+callerContext+". Expected context is "+configurationContext);
+
+
Process toLaunch=new Process(folderId,completionCallback);
localProcesses.put(folderId, toLaunch);
initializationExecutor.submit(new ProcessInitializationThread(toLaunch,synchronizationExecutor));
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/WorkspaceFolderManager.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/WorkspaceFolderManager.java
index dae4da4..80fda61 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/WorkspaceFolderManager.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/WorkspaceFolderManager.java
@@ -51,9 +51,27 @@ public class WorkspaceFolderManager {
private StorageHubClient sc;
+
+ private String operator=null;
+
+ private String getToken() {
+ if(operator==null) {
+ log.warn("******************Using config operator**********");
+ return config.getTargetToken();
+ }
+ else return operator;
+ }
+
+
+
+
public WorkspaceFolderManager(String folderId) throws WorkspaceInteractionException {
try{
// ws = HomeLibrary.getHomeManagerFactory().getHomeManager().getHome().getWorkspace();
+ String operator=Security.getToken();
+ log.debug("Setting operator "+operator);
+ this.operator=operator;
+
sc=WorkspaceUtils.getClient();
theFolder=sc.open(folderId).asFolder();
this.folderId=folderId;
@@ -70,7 +88,7 @@ public class WorkspaceFolderManager {
public ThreddsController getThreddsController() throws WorkspaceNotSynchedException, WorkspaceInteractionException, InternalException {
if(threddsController==null) {
SynchFolderConfiguration config=getSynchConfiguration();
- threddsController=new ThreddsController(config.getRemotePath(),config.getTargetToken());
+ threddsController=new ThreddsController(config.getRemotePath(),getToken());
}
return threddsController;
}
@@ -79,7 +97,7 @@ public class WorkspaceFolderManager {
try {
FolderContainer root=sc.open(getSynchConfiguration().getRootFolderId()).asFolder();
SynchFolderConfiguration rootConfig=WorkspaceUtils.loadConfiguration(root);
- return new ThreddsController(rootConfig.getRemotePath(),rootConfig.getTargetToken());
+ return new ThreddsController(rootConfig.getRemotePath(),getToken());
}catch(StorageHubException e) {
throw new WorkspaceInteractionException(e);
}
@@ -116,7 +134,7 @@ public class WorkspaceFolderManager {
SynchFolderConfiguration config=getSynchConfiguration();
try{
- checkFolder(theFolder,recursively,config,null,theFolder.getId(),WorkspaceUtils.safelyGetLastUpdate(theFolder.get()));
+ checkFolder(theFolder,recursively,config,null,theFolder.getId(),WorkspaceUtils.safelyGetLastUpdate(theFolder.get()),getToken());
return new SyncFolderDescriptor(this.folderId,this.theFolder.get().getPath(),config);
}catch(StorageHubException e) {
throw new WorkspaceInteractionException(e);
@@ -151,7 +169,7 @@ public class WorkspaceFolderManager {
try {
String catalogName=toSet.getToCreateCatalogName();
- ThreddsController controller= new ThreddsController(toSet.getRemotePath(),toSet.getTargetToken());
+ ThreddsController controller= new ThreddsController(toSet.getRemotePath(),getToken());
if(!controller.existsThreddsFile(null)) {
log.info("Folder not found, creating it..");
controller.createEmptyFolder(null);
@@ -241,7 +259,7 @@ public class WorkspaceFolderManager {
- private static void checkFolder(FolderContainer folder,boolean recursive, SynchFolderConfiguration rootConfig, String relativePathFromRootFolder, String rootFolderId,Date lastUpdatedRoutine) throws StorageHubException, InternalException {
+ private static void checkFolder(FolderContainer folder,boolean recursive, SynchFolderConfiguration rootConfig, String relativePathFromRootFolder, String rootFolderId,Date lastUpdatedRoutine, String toUseToken) throws StorageHubException, InternalException {
// Check folder configuration
log.trace("Checking folder {} ",folder.get().getPath());
log.debug("Configuration is {}, relativePath is {} ",rootConfig,relativePathFromRootFolder);
@@ -252,7 +270,7 @@ public class WorkspaceFolderManager {
- ThreddsController controller=new ThreddsController(currentRemotePath, rootConfig.getTargetToken());
+ ThreddsController controller=new ThreddsController(currentRemotePath, toUseToken);
HashSet currentFolderExistingItem=new HashSet();
@@ -269,7 +287,7 @@ public class WorkspaceFolderManager {
String itemRemotePath=currentRemotePath+"/"+itemName;
if(item.getType().equals(ContainerType.FOLDER)) {
if(recursive)
- checkFolder((FolderContainer) item,recursive,rootConfig,itemRelativePath,rootFolderId,lastUpdatedRoutine);
+ checkFolder((FolderContainer) item,recursive,rootConfig,itemRelativePath,rootFolderId,lastUpdatedRoutine,toUseToken);
else WorkspaceUtils.initProperties(item, itemRemotePath, rootConfig.getFilter(), rootConfig.getTargetToken(),rootConfig.getToCreateCatalogName(),rootConfig.getValidateMetadata(),rootFolderId);
}else if(rootConfig.matchesFilter(itemName)) {
if(!WorkspaceUtils.isConfigured(item.get()))
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/threads/SynchronizationThread.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/threads/SynchronizationThread.java
index 196591f..b98982a 100644
--- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/threads/SynchronizationThread.java
+++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/threads/SynchronizationThread.java
@@ -73,7 +73,7 @@ public class SynchronizationThread implements Runnable {
FolderContainer parentFolder=client.open(parentFolderItem.getId()).asFolder();
checkCancelledProcess();
SynchFolderConfiguration synchConfig=WorkspaceUtils.loadConfiguration(parentFolder);
- ThreddsController controller=new ThreddsController(synchConfig.getRemotePath(), synchConfig.getTargetToken());
+ ThreddsController controller=new ThreddsController(synchConfig.getRemotePath(), theRequest.getProcess().getDescriptor().getOperator());
if(theRequest instanceof TransferToThreddsRequest) {
TransferToThreddsRequest request=(TransferToThreddsRequest) theRequest;
diff --git a/src/main/java/org/gcube/usecases/ws/thredds/faults/GenericWebException.java b/src/main/java/org/gcube/usecases/ws/thredds/faults/GenericWebException.java
new file mode 100644
index 0000000..33f3c36
--- /dev/null
+++ b/src/main/java/org/gcube/usecases/ws/thredds/faults/GenericWebException.java
@@ -0,0 +1,49 @@
+package org.gcube.usecases.ws.thredds.faults;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString(callSuper = true)
+public class GenericWebException extends Exception{
+
+
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5200927893712698886L;
+
+ private String remoteMessage=null;
+
+ private Integer responseHTTPCode=0;
+
+ public GenericWebException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public GenericWebException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ // TODO Auto-generated constructor stub
+ }
+
+ public GenericWebException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ public GenericWebException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ public GenericWebException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+
+}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
deleted file mode 100644
index e69de29..0000000
diff --git a/src/test/java/org/gcube/usecases/ws/thredds/DTSynchUseCase.java b/src/test/java/org/gcube/usecases/ws/thredds/DTSynchUseCase.java
index 0675951..ac5275b 100644
--- a/src/test/java/org/gcube/usecases/ws/thredds/DTSynchUseCase.java
+++ b/src/test/java/org/gcube/usecases/ws/thredds/DTSynchUseCase.java
@@ -14,10 +14,13 @@ import org.gcube.usecases.ws.thredds.model.SynchFolderConfiguration;
public class DTSynchUseCase {
public static void main(String[] args) throws WorkspaceInteractionException, InternalException, ProcessNotFoundException {
- TokenSetter.set("/d4science.research-infrastructures.eu");
+// TokenSetter.set("/d4science.research-infrastructures.eu");
+// String folderId="a8cd78d3-69e8-4d02-ac90-681b2d16d84d";
+
+ TokenSetter.set("/gcube/devsec/devVRE");
+ String folderId="8ebe9ffb-e2cf-4b3e-ab91-cc6933d86625";
SyncEngine engine=SyncEngine.get();
- String folderId="a8cd78d3-69e8-4d02-ac90-681b2d16d84d";
// String folderId="8a6f9749-68d7-4a9a-a475-bd645050c3fd"; // sub folder for faster tests
diff --git a/src/test/java/org/gcube/usecases/ws/thredds/GetTrhreddsInfoTest.java b/src/test/java/org/gcube/usecases/ws/thredds/GetTrhreddsInfoTest.java
new file mode 100644
index 0000000..9a2c3cd
--- /dev/null
+++ b/src/test/java/org/gcube/usecases/ws/thredds/GetTrhreddsInfoTest.java
@@ -0,0 +1,17 @@
+package org.gcube.usecases.ws.thredds;
+
+import org.gcube.data.transfer.library.utils.ScopeUtils;
+import org.gcube.usecases.ws.thredds.faults.InternalException;
+
+public class GetTrhreddsInfoTest {
+
+
+ public static void main(String[] args) throws InternalException {
+ SyncEngine engine=SyncEngine.get();
+ // ROOT
+ System.out.println(engine.getAvailableCatalogsByToken("***REMOVED***"));
+ // MEI
+ System.out.println(engine.getAvailableCatalogsByToken("54f577de-d259-407e-b30d-29bf9e7c0dee-843339462"));
+ }
+
+}
diff --git a/src/test/java/org/gcube/usecases/ws/thredds/TestCommons.java b/src/test/java/org/gcube/usecases/ws/thredds/TestCommons.java
index 3200c5f..464309a 100644
--- a/src/test/java/org/gcube/usecases/ws/thredds/TestCommons.java
+++ b/src/test/java/org/gcube/usecases/ws/thredds/TestCommons.java
@@ -37,7 +37,7 @@ public class TestCommons {
private static Map configs=new HashMap<>();
- private static String toUseConfig="default";
+ private static String toUseConfig="simple";
static {
@@ -46,7 +46,7 @@ public class TestCommons {
// folderName="WS-Tests";
- configs.put("simple", new TestSet("Simple label ","/gcube", "Test1","public/netcdf/simpleFolder","***REMOVED***","simple"));
+ configs.put("simple", new TestSet("Simple label ","/gcube/devsec/devVRE", "Test1","public/netcdf/simpleFolder","***REMOVED***","simple"));
configs.put("cmems", new TestSet("CMEMS","/gcube", "CMEMS","public/netcdf/CMEMS","***REMOVED***","cmems"));
configs.put("default", new TestSet("Default Tests","/gcube","Thredds Catalog","public/netcdf","***REMOVED***","main"));
diff --git a/src/test/java/org/gcube/usecases/ws/thredds/TokenCheck.java b/src/test/java/org/gcube/usecases/ws/thredds/TokenCheck.java
new file mode 100644
index 0000000..6a8e82f
--- /dev/null
+++ b/src/test/java/org/gcube/usecases/ws/thredds/TokenCheck.java
@@ -0,0 +1,11 @@
+package org.gcube.usecases.ws.thredds;
+
+public class TokenCheck {
+
+//
+// public static void main (String[] args) {
+// System.out.println(Security.getContext("8e74a17c-92f1-405a-b591-3a6090066248-98187548"));
+// System.out.println(Security.getContext("0e2c7963-8d3e-4ea6-a56d-ffda530dd0fa-98187548"));
+// }
+//
+}
diff --git a/src/main/resources/log4j.properties b/src/test/resources/log4j.properties
similarity index 80%
rename from src/main/resources/log4j.properties
rename to src/test/resources/log4j.properties
index 38535ae..5d16a34 100644
--- a/src/main/resources/log4j.properties
+++ b/src/test/resources/log4j.properties
@@ -1,6 +1,6 @@
# Root logger option
-#log4j.rootLogger=INFO, SM
-log4j.logger.org.gcube.usecases.ws=DEBUG,SM
+log4j.rootLogger=DEBUG, SM
+#log4j.logger.org.gcube.usecases.ws=DEBUG,SM
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
new file mode 100644
index 0000000..b70dd26
--- /dev/null
+++ b/src/test/resources/logback.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
\ No newline at end of file