Integrated GeoportalServiceAccount management. Used to call gCat methods
This commit is contained in:
parent
2d6fac18dc
commit
888a45e9c6
|
@ -8,8 +8,12 @@ import org.gcube.application.cms.cataloguebinding.config.BindingWhen;
|
|||
import org.gcube.application.cms.cataloguebinding.freemarker.FreemarkerConfig;
|
||||
import org.gcube.application.cms.cataloguebinding.freemarker.MappingToCatalogue;
|
||||
import org.gcube.application.cms.plugins.events.ItemObserved;
|
||||
import org.gcube.application.cms.serviceaccount.GeoportalServiceAccount;
|
||||
import org.gcube.application.geoportal.common.model.document.Project;
|
||||
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
|
||||
import org.gcube.common.authorization.utils.manager.SecretManager;
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.authorization.utils.secret.Secret;
|
||||
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
@ -47,12 +51,12 @@ public class BindingAction {
|
|||
// Create or Update the item on the catalogue
|
||||
String catalogueItemJSON = toCatalogueItem();
|
||||
if (catalogueItemJSON != null)
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON);
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON, true);
|
||||
break;
|
||||
}
|
||||
case PROJECT_DELETED: {
|
||||
log.info("Going to delete item with name {} on the catalogue...", datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName, true);
|
||||
break;
|
||||
}
|
||||
case PROJECT_UPDATED: {
|
||||
|
@ -60,7 +64,7 @@ public class BindingAction {
|
|||
// Create or Update the item on the catalogue
|
||||
String catalogueItemJSON = toCatalogueItem();
|
||||
if (catalogueItemJSON != null)
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON);
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON, true);
|
||||
break;
|
||||
}
|
||||
case LIFECYCLE_STEP_PERFORMED: {
|
||||
|
@ -103,13 +107,14 @@ public class BindingAction {
|
|||
String catalogueItemJSON = toCatalogueItem();
|
||||
if (catalogueItemJSON != null) {
|
||||
log.info("Going to create item with name {} on the catalogue...", datasetName);
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON);
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(datasetName, catalogueItemJSON,
|
||||
true);
|
||||
}
|
||||
|
||||
} else if (itemPhase.equalsIgnoreCase(TARGET_PHASE_DRAFT)) {
|
||||
// Delete the item on the catalogue
|
||||
log.info("Going to delete item with name {} on the catalogue...", datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName, true);
|
||||
}
|
||||
} else {
|
||||
log.info(
|
||||
|
|
|
@ -7,6 +7,10 @@ import java.net.MalformedURLException;
|
|||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import org.gcube.application.cms.serviceaccount.GeoportalServiceAccount;
|
||||
import org.gcube.common.authorization.utils.manager.SecretManager;
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.authorization.utils.secret.Secret;
|
||||
import org.gcube.gcat.client.Item;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -18,47 +22,71 @@ import lombok.extern.slf4j.Slf4j;
|
|||
*
|
||||
* Jun 20, 2024
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class GCatCaller {
|
||||
|
||||
/**
|
||||
* Creates the or update the dataset on catalogue.
|
||||
*
|
||||
* @param datasetName the dataset name
|
||||
* @param datasetJSON the dataset JSON
|
||||
* @throws Exception
|
||||
* @param datasetName the dataset name
|
||||
* @param datasetJSON the dataset JSON
|
||||
* @param useGeoportalServiceAccount the use geoportal service account
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public void createOrUpdateTheDatasetOnCatalogue(String datasetName, String datasetJSON) throws Exception {
|
||||
log.info("createOrUpdateTheDatasetOnCatalogue with name {} called", datasetName);
|
||||
public void createOrUpdateTheDatasetOnCatalogue(String datasetName, String datasetJSON,
|
||||
boolean useGeoportalServiceAccount) throws Exception {
|
||||
log.info("createOrUpdateTheDatasetOnCatalogue with name {} called. Uses GeoportalServiceAccount: {}",
|
||||
datasetName, useGeoportalServiceAccount);
|
||||
SecretManager secretManager = null;
|
||||
try {
|
||||
|
||||
boolean datasetExists = false;
|
||||
|
||||
try {
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
|
||||
String dataset = new Item().read(datasetName);
|
||||
datasetExists = dataset != null ? true : false;
|
||||
} catch (Exception e) {
|
||||
resetGeoportalSecret(secretManager);
|
||||
}
|
||||
|
||||
log.info("datasetExists is {}", datasetExists);
|
||||
|
||||
if (!datasetExists) {
|
||||
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
|
||||
log.info("calling create dataset...");
|
||||
String itemCreated = new Item().create(datasetJSON, false);
|
||||
if (itemCreated != null)
|
||||
log.info("Dataset created with success");
|
||||
else
|
||||
log.warn("Dataset not created!");
|
||||
|
||||
resetGeoportalSecret(secretManager);
|
||||
|
||||
} else {
|
||||
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
|
||||
log.info("calling update dataset...");
|
||||
String itemCreated = new Item().update(datasetName, datasetJSON);
|
||||
if (itemCreated != null)
|
||||
log.info("Dataset updated with success!");
|
||||
else
|
||||
log.warn("Dataset not updated!");
|
||||
|
||||
resetGeoportalSecret(secretManager);
|
||||
}
|
||||
|
||||
} catch (WebApplicationException | MalformedURLException e) {
|
||||
log.error("Error occurred on creating the dataset " + datasetName + " on the catalogue", e);
|
||||
resetGeoportalSecret(secretManager);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
@ -66,24 +94,37 @@ public class GCatCaller {
|
|||
/**
|
||||
* Delete dataset on catalogue.
|
||||
*
|
||||
* @param datasetName the dataset name
|
||||
* @param datasetName the dataset name
|
||||
* @param useGeoportalServiceAccount the use geoportal service account
|
||||
*/
|
||||
public void deleteDatasetOnCatalogue(String datasetName) {
|
||||
log.info("deleteDatasetOnCatalogue with name {} called", datasetName);
|
||||
public void deleteDatasetOnCatalogue(String datasetName, boolean useGeoportalServiceAccount) {
|
||||
log.info("deleteDatasetOnCatalogue with name {} called. Uses GeoportalServiceAccount: {}", datasetName,
|
||||
useGeoportalServiceAccount);
|
||||
SecretManager secretManager = null;
|
||||
try {
|
||||
|
||||
boolean datasetExists = false;
|
||||
try {
|
||||
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
|
||||
String dataset = new Item().read(datasetName);
|
||||
datasetExists = dataset != null ? true : false;
|
||||
} catch (Exception e) {
|
||||
resetGeoportalSecret(secretManager);
|
||||
}
|
||||
|
||||
log.info("datasetExists is {}", datasetExists);
|
||||
|
||||
if (datasetExists) {
|
||||
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
|
||||
log.info("calling delete dataset and purge");
|
||||
new Item().delete(datasetName, true);
|
||||
resetGeoportalSecret(secretManager);
|
||||
log.info("Dataset deleted and purged with success!");
|
||||
} else {
|
||||
log.warn("Dataset does not exists, returning..");
|
||||
|
@ -92,19 +133,55 @@ public class GCatCaller {
|
|||
|
||||
} catch (WebApplicationException | MalformedURLException e) {
|
||||
log.error("Error occurred on deleting the dataset " + datasetName + " on the catalogue", e);
|
||||
resetGeoportalSecret(secretManager);
|
||||
}
|
||||
}
|
||||
|
||||
public String list(int limit, int offset) {
|
||||
log.info("list called");
|
||||
|
||||
public String list(int limit, int offset, boolean useGeoportalServiceAccount) {
|
||||
log.info("list called. Uses GeoportalServiceAccount: {}", useGeoportalServiceAccount);
|
||||
SecretManager secretManager = null;
|
||||
try {
|
||||
return new Item().list(limit, offset);
|
||||
if (useGeoportalServiceAccount)
|
||||
secretManager = setGeoportalClientSecret();
|
||||
String theList = new Item().list(limit, offset);
|
||||
resetGeoportalSecret(secretManager);
|
||||
return theList;
|
||||
} catch (WebApplicationException | MalformedURLException e) {
|
||||
log.error("Error occurred on listing datasets", e);
|
||||
resetGeoportalSecret(secretManager);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private SecretManager setGeoportalClientSecret() {
|
||||
log.debug("setting GeoportalClientSecret");
|
||||
try {
|
||||
|
||||
final SecretManager secretManager = SecretManagerProvider.instance.get();
|
||||
final Secret geoportalSecret = GeoportalServiceAccount.getGeoportalSecret();
|
||||
secretManager.startSession(geoportalSecret);
|
||||
log.debug("returning GeoportalSecret Manager");
|
||||
return secretManager;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error while setting GeoportalServiceAccount SecretManager", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void resetGeoportalSecret(SecretManager secretManager) {
|
||||
log.debug("resetting GeoportalClientSecret");
|
||||
if (secretManager != null) {
|
||||
try {
|
||||
log.debug("GeoportalSecret endSession");
|
||||
secretManager.endSession();
|
||||
} catch (Exception e) {
|
||||
log.warn("Error when resetting the session");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,8 +9,12 @@ import org.json.JSONException;
|
|||
import test.TestContextConfig;
|
||||
|
||||
public class CataloguePurgeDatasets {
|
||||
|
||||
|
||||
private static boolean useGeoportalServiceAccount = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
//TokenSetter.set(GCubeTest.getContext());
|
||||
|
||||
TestContextConfig.readContextSettings();
|
||||
|
||||
|
@ -21,12 +25,13 @@ public class CataloguePurgeDatasets {
|
|||
int offset = 0;
|
||||
|
||||
boolean resultExists = true;
|
||||
|
||||
|
||||
while (resultExists) {
|
||||
System.out.println("offest: " + offset + ", limit: " + limit);
|
||||
ScopeProvider.instance.set(TestContextConfig.CONTEXT);
|
||||
SecurityTokenProvider.instance.set(TestContextConfig.TOKEN);
|
||||
String items = new GCatCaller().list(limit, offset);
|
||||
String items = new GCatCaller().list(limit, offset, useGeoportalServiceAccount);
|
||||
System.out.println("items: " + items);
|
||||
if (items != null) {
|
||||
resultExists = true;
|
||||
|
@ -63,7 +68,7 @@ public class CataloguePurgeDatasets {
|
|||
System.out.println(index + ") Deleting dataset name : " + datasetName);
|
||||
ScopeProvider.instance.set(TestContextConfig.CONTEXT);
|
||||
SecurityTokenProvider.instance.set(TestContextConfig.TOKEN);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName, useGeoportalServiceAccount);
|
||||
System.out.println("sleeping..." + sleepingTime);
|
||||
Thread.sleep(sleepingTime);
|
||||
}
|
||||
|
@ -82,7 +87,7 @@ public class CataloguePurgeDatasets {
|
|||
try {
|
||||
ScopeProvider.instance.set(TestContextConfig.CONTEXT);
|
||||
SecurityTokenProvider.instance.set(TestContextConfig.TOKEN);
|
||||
String items = new GCatCaller().list(limit, offset);
|
||||
String items = new GCatCaller().list(limit, offset, useGeoportalServiceAccount);
|
||||
System.out.println("items: " + items);
|
||||
|
||||
JSONArray array = new JSONArray(items);
|
||||
|
@ -91,7 +96,7 @@ public class CataloguePurgeDatasets {
|
|||
System.out.println(i + ") name : " + datasetName);
|
||||
ScopeProvider.instance.set(TestContextConfig.CONTEXT);
|
||||
SecurityTokenProvider.instance.set(TestContextConfig.TOKEN);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName);
|
||||
new GCatCaller().deleteDatasetOnCatalogue(datasetName, useGeoportalServiceAccount);
|
||||
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
|
|
@ -60,13 +60,15 @@ import test.TestContextConfig;
|
|||
public class GeoportalToCatalogueBatchPublisher {
|
||||
|
||||
public final static String profileID = "profiledConcessioni";
|
||||
public final static Integer MAX_ITEMS = 100;
|
||||
public final static Integer MAX_ITEMS = 1;
|
||||
|
||||
static PrintWriter reportPrintWriter;
|
||||
static PrintWriter errorPrintWriter;
|
||||
private static long startTime;
|
||||
|
||||
private static final String CSV_DELIMITER = ";";
|
||||
|
||||
private static boolean useGeoportalServiceAccount = false;
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
|
@ -75,10 +77,10 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
//procedureToPublishProjectsOnCatalogue();
|
||||
procedureToPublishProjectsOnCatalogue();
|
||||
|
||||
String projectId = " 6663016a312dc236d217be5c";
|
||||
checkMappingToJSONForProjectByID(projectId);
|
||||
// String projectId = " 6663016a312dc236d217be5c";
|
||||
// checkMappingToJSONForProjectByID(projectId);
|
||||
|
||||
}
|
||||
|
||||
|
@ -137,9 +139,8 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
System.out.println("Procedure starting at: "+getFormattedDateTime());
|
||||
|
||||
System.out.println("Procedure starting at: " + getFormattedDateTime());
|
||||
startTime = System.currentTimeMillis();
|
||||
|
||||
Integer totalProjects = null;
|
||||
|
@ -201,8 +202,8 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
*/
|
||||
String targetScope = "";
|
||||
String targetToken = "";
|
||||
|
||||
if(targetScope==null || targetToken==null) {
|
||||
|
||||
if (targetScope == null || targetToken == null) {
|
||||
throw new Exception("Check targetScope and/or targetToken!!!");
|
||||
}
|
||||
|
||||
|
@ -252,10 +253,10 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
errorPrintWriter.close();
|
||||
|
||||
System.out.println("\n\nFINISHED!!!");
|
||||
System.out.println("Procedure terimated at: "+getFormattedDateTime());
|
||||
long millis = System.currentTimeMillis()-startTime;
|
||||
System.out.println("Procedure terimated at: " + getFormattedDateTime());
|
||||
long millis = System.currentTimeMillis() - startTime;
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
|
||||
System.out.println("Done! In ms: "+(millis) + ", minutes: "+minutes);
|
||||
System.out.println("Done! In ms: " + (millis) + ", minutes: " + minutes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -269,7 +270,7 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
*/
|
||||
public static void publishOnCatalogue(Project theProject, String toCatalogueJSON) throws Exception {
|
||||
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(theProject.getId(), toCatalogueJSON);
|
||||
new GCatCaller().createOrUpdateTheDatasetOnCatalogue(theProject.getId(), toCatalogueJSON, useGeoportalServiceAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -445,13 +446,13 @@ public class GeoportalToCatalogueBatchPublisher {
|
|||
errorPrintWriter.println(newline);
|
||||
errorPrintWriter.flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the formatted date time.
|
||||
*
|
||||
* @return the formatted date time
|
||||
*/
|
||||
public static String getFormattedDateTime(){
|
||||
public static String getFormattedDateTime() {
|
||||
long yourmilliseconds = System.currentTimeMillis();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss");
|
||||
Date resultdate = new Date(yourmilliseconds);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# Changelog for org.gcube.application.cms-plugin-framework
|
||||
|
||||
## [v1.0.5-SNAPSHOT] - 2023-12-21
|
||||
## [v1.0.5-SNAPSHOT] - 2024-07-02
|
||||
|
||||
- Implemented Event Broker [#26321]
|
||||
- Added Geoportal Service Account management
|
||||
|
||||
## [v1.0.4] - 2023-09-06
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package org.gcube.application.cms.serviceaccount;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.ws.rs.InternalServerErrorException;
|
||||
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.authorization.utils.secret.JWTSecret;
|
||||
import org.gcube.common.authorization.utils.secret.Secret;
|
||||
import org.gcube.common.keycloak.KeycloakClientFactory;
|
||||
import org.gcube.common.keycloak.model.TokenResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class GeoportalServiceAccount {
|
||||
|
||||
//geoportal service account config property file
|
||||
protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
|
||||
|
||||
private static String clientId = "geoportal";
|
||||
|
||||
private static Entry<String, String> getClientIdAndClientSecret(String context) {
|
||||
try {
|
||||
IAMClientCredentials credentials = IAMClientCredentialsReader.getCredentials();
|
||||
|
||||
clientId = credentials.getClientId()==null?clientId:credentials.getClientId();
|
||||
String clientSecret = credentials.getClientSecret();
|
||||
SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
|
||||
return entry;
|
||||
} catch(Exception e) {
|
||||
throw new InternalServerErrorException(
|
||||
"Unable to retrieve Application Token for context " + SecretManagerProvider.instance.get().getContext(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static TokenResponse getJWTAccessToken() throws Exception {
|
||||
String context = SecretManagerProvider.instance.get().getContext();
|
||||
Entry<String,String> entry = getClientIdAndClientSecret(context);
|
||||
TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(context, entry.getKey(), entry.getValue(), context, null);
|
||||
return tr;
|
||||
}
|
||||
|
||||
public static Secret getGeoportalSecret() throws Exception {
|
||||
TokenResponse tr = getJWTAccessToken();
|
||||
Secret secret = new JWTSecret(tr.getAccessToken());
|
||||
return secret;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package org.gcube.application.cms.serviceaccount;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The Class IAMClientCredentials.
|
||||
*
|
||||
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
*
|
||||
* Sep 23, 2021
|
||||
*/
|
||||
public class IAMClientCredentials implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7242909633989611318L;
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
|
||||
/**
|
||||
* Instantiates a new IAM client credentials.
|
||||
*/
|
||||
public IAMClientCredentials() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new IAM client credentials.
|
||||
*
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
*/
|
||||
public IAMClientCredentials(String clientId, String clientSecret) {
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client id.
|
||||
*
|
||||
* @return the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client secret.
|
||||
*
|
||||
* @return the client secret
|
||||
*/
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client id.
|
||||
*
|
||||
* @param clientId the new client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client secret.
|
||||
*
|
||||
* @param clientSecret the new client secret
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* To string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("IAMClientCredentials [clientId=");
|
||||
builder.append(clientId);
|
||||
builder.append(", clientSecret=");
|
||||
builder.append(clientSecret != null ? clientSecret.subSequence(0, 5) + "_MASKED_SECRET" : null);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package org.gcube.application.cms.serviceaccount;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The Class GNABaseMapsResourceReader.
|
||||
*
|
||||
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
*
|
||||
* Sep 23, 2021
|
||||
*/
|
||||
@Slf4j
|
||||
public class IAMClientCredentialsReader {
|
||||
|
||||
private static final String SE_PROFILE_NAME = "geoportal";
|
||||
private static final String SE_CATEGORY_NAME = "SystemWorkspaceClient";
|
||||
|
||||
/**
|
||||
* Gets the credentials.
|
||||
*
|
||||
* @return the credentials
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static IAMClientCredentials getCredentials() throws Exception {
|
||||
|
||||
String currentContext = SecretManagerProvider.instance.get().getContext();
|
||||
|
||||
log.info("Searching SE in the scope: " + currentContext + " with profile name: " + SE_PROFILE_NAME
|
||||
+ " and category name: " + SE_CATEGORY_NAME);
|
||||
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Name/text() eq '" + SE_PROFILE_NAME + "'");
|
||||
query.addCondition("$resource/Profile/Category/text() eq '" + SE_CATEGORY_NAME + "'");
|
||||
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> resources = client.submit(query);
|
||||
|
||||
if (resources.size() > 0)
|
||||
log.info("The query returned " + resources.size() + " ServiceEndpoint/s");
|
||||
else
|
||||
throw new RuntimeException("ServiceEndpoint not found. Searching for profile name '" + SE_PROFILE_NAME
|
||||
+ "' and category name '" + SE_CATEGORY_NAME + "' in the scope: " + currentContext);
|
||||
|
||||
ServiceEndpoint se = resources.get(0);
|
||||
Collection<AccessPoint> theAccessPoints = se.profile().accessPoints().asCollection();
|
||||
String clientId = null;
|
||||
String secredPwd = null;
|
||||
for (AccessPoint accessPoint : theAccessPoints) {
|
||||
clientId = accessPoint.username();
|
||||
secredPwd = accessPoint.password();
|
||||
log.debug("Found clientId: " + clientId + " and encrypted secret: " + secredPwd);
|
||||
// decrypting the pwd
|
||||
try {
|
||||
if (secredPwd != null) {
|
||||
secredPwd = StringEncrypter.getEncrypter().decrypt(secredPwd);
|
||||
log.debug("Secret decrypted is: " + secredPwd.substring(0, secredPwd.length() / 2)
|
||||
+ "_MASKED_TOKEN_");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error on decrypting the pwd: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Returning keycloack credentials for SE {} read from SE", SE_PROFILE_NAME);
|
||||
return new IAMClientCredentials(clientId, secredPwd);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -70,12 +70,6 @@
|
|||
<artifactId>commons-text</artifactId>
|
||||
<version>1.11.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-utils</artifactId>
|
||||
<version>${authorization-utils-range}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Fix the issue with JUnit tests: java.lang.NoClassDefFoundError : javax/xml/soap/SOAPException -->
|
||||
<!-- <dependency> -->
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.ws.rs.InternalServerErrorException;
|
||||
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.authorization.utils.secret.JWTSecret;
|
||||
import org.gcube.common.authorization.utils.secret.Secret;
|
||||
import org.gcube.common.keycloak.KeycloakClientFactory;
|
||||
import org.gcube.common.keycloak.model.TokenResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class GeoportalServiceAccount {
|
||||
|
||||
//geoportal service account config property file
|
||||
protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
|
||||
|
||||
private static String clientId = "geoportal";
|
||||
|
||||
private static Entry<String, String> getClientIdAndClientSecret(String context) {
|
||||
try {
|
||||
IAMClientCredentials credentials = IAMClientCredentialsReader.getCredentials();
|
||||
|
||||
clientId = credentials.getClientId()==null?clientId:credentials.getClientId();
|
||||
String clientSecret = credentials.getClientSecret();
|
||||
SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
|
||||
return entry;
|
||||
} catch(Exception e) {
|
||||
throw new InternalServerErrorException(
|
||||
"Unable to retrieve Application Token for context " + SecretManagerProvider.instance.get().getContext(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static TokenResponse getJWTAccessToken() throws Exception {
|
||||
String context = SecretManagerProvider.instance.get().getContext();
|
||||
Entry<String,String> entry = getClientIdAndClientSecret(context);
|
||||
TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(context, entry.getKey(), entry.getValue(), context, null);
|
||||
return tr;
|
||||
}
|
||||
|
||||
public static Secret getGeoportalSecret() throws Exception {
|
||||
TokenResponse tr = getJWTAccessToken();
|
||||
Secret secret = new JWTSecret(tr.getAccessToken());
|
||||
return secret;
|
||||
}
|
||||
|
||||
}
|
||||
//package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
//
|
||||
//import java.util.AbstractMap.SimpleEntry;
|
||||
//import java.util.Map.Entry;
|
||||
//
|
||||
//import javax.ws.rs.InternalServerErrorException;
|
||||
//
|
||||
//import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
//import org.gcube.common.authorization.utils.secret.JWTSecret;
|
||||
//import org.gcube.common.authorization.utils.secret.Secret;
|
||||
//import org.gcube.common.keycloak.KeycloakClientFactory;
|
||||
//import org.gcube.common.keycloak.model.TokenResponse;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
//@Slf4j
|
||||
//public class GeoportalServiceAccount {
|
||||
//
|
||||
// //geoportal service account config property file
|
||||
// protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
|
||||
//
|
||||
// private static String clientId = "geoportal";
|
||||
//
|
||||
// private static Entry<String, String> getClientIdAndClientSecret(String context) {
|
||||
// try {
|
||||
// IAMClientCredentials credentials = IAMClientCredentialsReader.getCredentials();
|
||||
//
|
||||
// clientId = credentials.getClientId()==null?clientId:credentials.getClientId();
|
||||
// String clientSecret = credentials.getClientSecret();
|
||||
// SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
|
||||
// return entry;
|
||||
// } catch(Exception e) {
|
||||
// throw new InternalServerErrorException(
|
||||
// "Unable to retrieve Application Token for context " + SecretManagerProvider.instance.get().getContext(), e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static TokenResponse getJWTAccessToken() throws Exception {
|
||||
// String context = SecretManagerProvider.instance.get().getContext();
|
||||
// Entry<String,String> entry = getClientIdAndClientSecret(context);
|
||||
// TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(context, entry.getKey(), entry.getValue(), context, null);
|
||||
// return tr;
|
||||
// }
|
||||
//
|
||||
// public static Secret getGeoportalSecret() throws Exception {
|
||||
// TokenResponse tr = getJWTAccessToken();
|
||||
// Secret secret = new JWTSecret(tr.getAccessToken());
|
||||
// return secret;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The Class IAMClientCredentials.
|
||||
*
|
||||
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
*
|
||||
* Sep 23, 2021
|
||||
*/
|
||||
public class IAMClientCredentials implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7242909633989611318L;
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
|
||||
/**
|
||||
* Instantiates a new IAM client credentials.
|
||||
*/
|
||||
public IAMClientCredentials() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new IAM client credentials.
|
||||
*
|
||||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
*/
|
||||
public IAMClientCredentials(String clientId, String clientSecret) {
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client id.
|
||||
*
|
||||
* @return the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client secret.
|
||||
*
|
||||
* @return the client secret
|
||||
*/
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client id.
|
||||
*
|
||||
* @param clientId the new client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client secret.
|
||||
*
|
||||
* @param clientSecret the new client secret
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* To string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("IAMClientCredentials [clientId=");
|
||||
builder.append(clientId);
|
||||
builder.append(", clientSecret=");
|
||||
builder.append(clientSecret != null ? clientSecret.subSequence(0, 5) + "_MASKED_SECRET" : null);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
//package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
//
|
||||
//import java.io.Serializable;
|
||||
//
|
||||
///**
|
||||
// * The Class IAMClientCredentials.
|
||||
// *
|
||||
// * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
// *
|
||||
// * Sep 23, 2021
|
||||
// */
|
||||
//public class IAMClientCredentials implements Serializable {
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// private static final long serialVersionUID = 7242909633989611318L;
|
||||
// private String clientId;
|
||||
// private String clientSecret;
|
||||
//
|
||||
// /**
|
||||
// * Instantiates a new IAM client credentials.
|
||||
// */
|
||||
// public IAMClientCredentials() {
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Instantiates a new IAM client credentials.
|
||||
// *
|
||||
// * @param clientId the client id
|
||||
// * @param clientSecret the client secret
|
||||
// */
|
||||
// public IAMClientCredentials(String clientId, String clientSecret) {
|
||||
// this.clientId = clientId;
|
||||
// this.clientSecret = clientSecret;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets the client id.
|
||||
// *
|
||||
// * @return the client id
|
||||
// */
|
||||
// public String getClientId() {
|
||||
// return clientId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets the client secret.
|
||||
// *
|
||||
// * @return the client secret
|
||||
// */
|
||||
// public String getClientSecret() {
|
||||
// return clientSecret;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Sets the client id.
|
||||
// *
|
||||
// * @param clientId the new client id
|
||||
// */
|
||||
// public void setClientId(String clientId) {
|
||||
// this.clientId = clientId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Sets the client secret.
|
||||
// *
|
||||
// * @param clientSecret the new client secret
|
||||
// */
|
||||
// public void setClientSecret(String clientSecret) {
|
||||
// this.clientSecret = clientSecret;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * To string.
|
||||
// *
|
||||
// * @return the string
|
||||
// */
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// StringBuilder builder = new StringBuilder();
|
||||
// builder.append("IAMClientCredentials [clientId=");
|
||||
// builder.append(clientId);
|
||||
// builder.append(", clientSecret=");
|
||||
// builder.append(clientSecret != null ? clientSecret.subSequence(0, 5) + "_MASKED_SECRET" : null);
|
||||
// builder.append("]");
|
||||
// return builder.toString();
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
@ -1,82 +1,82 @@
|
|||
package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The Class GNABaseMapsResourceReader.
|
||||
*
|
||||
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
*
|
||||
* Sep 23, 2021
|
||||
*/
|
||||
@Slf4j
|
||||
public class IAMClientCredentialsReader {
|
||||
|
||||
private static final String SE_PROFILE_NAME = "geoportal";
|
||||
private static final String SE_CATEGORY_NAME = "SystemWorkspaceClient";
|
||||
|
||||
/**
|
||||
* Gets the credentials.
|
||||
*
|
||||
* @return the credentials
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static IAMClientCredentials getCredentials() throws Exception {
|
||||
|
||||
String currentContext = SecretManagerProvider.instance.get().getContext();
|
||||
|
||||
log.info("Searching SE in the scope: " + currentContext + " with profile name: " + SE_PROFILE_NAME
|
||||
+ " and category name: " + SE_CATEGORY_NAME);
|
||||
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Name/text() eq '" + SE_PROFILE_NAME + "'");
|
||||
query.addCondition("$resource/Profile/Category/text() eq '" + SE_CATEGORY_NAME + "'");
|
||||
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> resources = client.submit(query);
|
||||
|
||||
if (resources.size() > 0)
|
||||
log.info("The query returned " + resources.size() + " ServiceEndpoint/s");
|
||||
else
|
||||
throw new RuntimeException("ServiceEndpoint not found. Searching for profile name '" + SE_PROFILE_NAME
|
||||
+ "' and category name '" + SE_CATEGORY_NAME + "' in the scope: " + currentContext);
|
||||
|
||||
ServiceEndpoint se = resources.get(0);
|
||||
Collection<AccessPoint> theAccessPoints = se.profile().accessPoints().asCollection();
|
||||
String clientId = null;
|
||||
String secredPwd = null;
|
||||
for (AccessPoint accessPoint : theAccessPoints) {
|
||||
clientId = accessPoint.username();
|
||||
secredPwd = accessPoint.password();
|
||||
log.debug("Found clientId: " + clientId + " and encrypted secret: " + secredPwd);
|
||||
// decrypting the pwd
|
||||
try {
|
||||
if (secredPwd != null) {
|
||||
secredPwd = StringEncrypter.getEncrypter().decrypt(secredPwd);
|
||||
log.debug("Secret decrypted is: " + secredPwd.substring(0, secredPwd.length() / 2)
|
||||
+ "_MASKED_TOKEN_");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error on decrypting the pwd: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Returning keycloack credentials for SE {} read from SE", SE_PROFILE_NAME);
|
||||
return new IAMClientCredentials(clientId, secredPwd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//package org.gcube.application.cms.notifications.config.serviceaccount;
|
||||
//
|
||||
//import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
//import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
//
|
||||
//import java.util.Collection;
|
||||
//import java.util.List;
|
||||
//
|
||||
//import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
||||
//import org.gcube.common.encryption.StringEncrypter;
|
||||
//import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
//import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
//import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
//import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
///**
|
||||
// * The Class GNABaseMapsResourceReader.
|
||||
// *
|
||||
// * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
||||
// *
|
||||
// * Sep 23, 2021
|
||||
// */
|
||||
//@Slf4j
|
||||
//public class IAMClientCredentialsReader {
|
||||
//
|
||||
// private static final String SE_PROFILE_NAME = "geoportal";
|
||||
// private static final String SE_CATEGORY_NAME = "SystemWorkspaceClient";
|
||||
//
|
||||
// /**
|
||||
// * Gets the credentials.
|
||||
// *
|
||||
// * @return the credentials
|
||||
// * @throws Exception the exception
|
||||
// */
|
||||
// public static IAMClientCredentials getCredentials() throws Exception {
|
||||
//
|
||||
// String currentContext = SecretManagerProvider.instance.get().getContext();
|
||||
//
|
||||
// log.info("Searching SE in the scope: " + currentContext + " with profile name: " + SE_PROFILE_NAME
|
||||
// + " and category name: " + SE_CATEGORY_NAME);
|
||||
//
|
||||
// SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
// query.addCondition("$resource/Profile/Name/text() eq '" + SE_PROFILE_NAME + "'");
|
||||
// query.addCondition("$resource/Profile/Category/text() eq '" + SE_CATEGORY_NAME + "'");
|
||||
//
|
||||
// DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
// List<ServiceEndpoint> resources = client.submit(query);
|
||||
//
|
||||
// if (resources.size() > 0)
|
||||
// log.info("The query returned " + resources.size() + " ServiceEndpoint/s");
|
||||
// else
|
||||
// throw new RuntimeException("ServiceEndpoint not found. Searching for profile name '" + SE_PROFILE_NAME
|
||||
// + "' and category name '" + SE_CATEGORY_NAME + "' in the scope: " + currentContext);
|
||||
//
|
||||
// ServiceEndpoint se = resources.get(0);
|
||||
// Collection<AccessPoint> theAccessPoints = se.profile().accessPoints().asCollection();
|
||||
// String clientId = null;
|
||||
// String secredPwd = null;
|
||||
// for (AccessPoint accessPoint : theAccessPoints) {
|
||||
// clientId = accessPoint.username();
|
||||
// secredPwd = accessPoint.password();
|
||||
// log.debug("Found clientId: " + clientId + " and encrypted secret: " + secredPwd);
|
||||
// // decrypting the pwd
|
||||
// try {
|
||||
// if (secredPwd != null) {
|
||||
// secredPwd = StringEncrypter.getEncrypter().decrypt(secredPwd);
|
||||
// log.debug("Secret decrypted is: " + secredPwd.substring(0, secredPwd.length() / 2)
|
||||
// + "_MASKED_TOKEN_");
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException("Error on decrypting the pwd: ", e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// log.info("Returning keycloack credentials for SE {} read from SE", SE_PROFILE_NAME);
|
||||
// return new IAMClientCredentials(clientId, secredPwd);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
@ -8,11 +8,11 @@ import java.util.stream.Collectors;
|
|||
import org.gcube.application.cms.notifications.config.ExportAsPDF;
|
||||
import org.gcube.application.cms.notifications.config.NotificationWhen;
|
||||
import org.gcube.application.cms.notifications.config.Notify;
|
||||
import org.gcube.application.cms.notifications.config.serviceaccount.GeoportalServiceAccount;
|
||||
import org.gcube.application.cms.notifications.social.SocialClients;
|
||||
import org.gcube.application.cms.notifications.substitutor.NMessagesPlaceholdersSubstitutorUtil;
|
||||
import org.gcube.application.cms.plugins.events.ItemObserved;
|
||||
import org.gcube.application.cms.plugins.events.ItemObserved.OPTIONAL_FIELD;
|
||||
import org.gcube.application.cms.serviceaccount.GeoportalServiceAccount;
|
||||
import org.gcube.application.geoportal.common.model.document.Project;
|
||||
import org.gcube.application.geoportal.common.model.document.accounting.User;
|
||||
import org.gcube.common.authorization.utils.manager.SecretManager;
|
||||
|
|
Loading…
Reference in New Issue