Improved and fixed reading of Access Policy from the Document

This commit is contained in:
Francesco Mangiacrapa 2023-04-06 11:33:22 +02:00
parent f5a8e08b88
commit 4f799628e0
3 changed files with 144 additions and 92 deletions

View File

@ -11,6 +11,7 @@ import org.bson.Document;
import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy; import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportalcommon.ConvertToDataServiceModel;
import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel;
import org.gcube.application.geoportalcommon.geoportal.access.GeportalCheckAccessPolicy; import org.gcube.application.geoportalcommon.geoportal.access.GeportalCheckAccessPolicy;
import org.gcube.application.geoportalcommon.geoportal.serdes.Payload; import org.gcube.application.geoportalcommon.geoportal.serdes.Payload;
@ -39,6 +40,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider; import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider;
@ -87,7 +89,7 @@ public class Geoportal_JSON_Mapper {
LOG.debug("theProjectDV as JSON: " + theWholeProjectAsJSON); LOG.debug("theProjectDV as JSON: " + theWholeProjectAsJSON);
LOG.trace("theProjectDV as MAP: " + theProjectDV.getTheDocument().getDocumentAsMap()); LOG.trace("theProjectDV as MAP: " + theProjectDV.getTheDocument().getDocumentAsMap());
ProjectEdit projectEdit = new ProjectEdit(); ProjectEdit projectEdit = new ProjectEdit();
projectEdit.setTheProjectDV(theProjectDV); projectEdit.setTheProjectDV(theProjectDV);
@ -131,8 +133,8 @@ public class Geoportal_JSON_Mapper {
for (GcubeProfilesMetadataForUCD gcubeProfileMetaForUCD : listProfilesBean) { for (GcubeProfilesMetadataForUCD gcubeProfileMetaForUCD : listProfilesBean) {
GcubeProfileDV gcubeProfileDV = gcubeProfileMetaForUCD.getGcubeProfile(); GcubeProfileDV gcubeProfileDV = gcubeProfileMetaForUCD.getGcubeProfile();
LOG.debug("\n\n##### Creating the section: " + gcubeProfileDV.getSectionTitle()); LOG.info("\n\n##### Creating the section: " + gcubeProfileDV.getSectionTitle());
LOG.debug("\n\nThe profile is: " + gcubeProfileDV); LOG.info("\n\nThe profile is: " + gcubeProfileDV);
// Building JSON/section full PATH and section name // Building JSON/section full PATH and section name
String sectionJSONPath = ""; String sectionJSONPath = "";
String parentPathFromProfile = gcubeProfileDV.getParentName() == null ? "" : gcubeProfileDV.getParentName(); String parentPathFromProfile = gcubeProfileDV.getParentName() == null ? "" : gcubeProfileDV.getParentName();
@ -195,7 +197,6 @@ public class Geoportal_JSON_Mapper {
theProfileBeanExt.setTitle(theProfileBean.getTitle()); theProfileBeanExt.setTitle(theProfileBean.getTitle());
theProfileBeanExt.setType(theProfileBean.getType()); theProfileBeanExt.setType(theProfileBean.getType());
theProfileBeanExt.setGcubeProfile(gcubeProfileDV); theProfileBeanExt.setGcubeProfile(gcubeProfileDV);
Document fromSectionDoc = listBSONDocument.get(i); Document fromSectionDoc = listBSONDocument.get(i);
LOG.debug("\n\nNew section DOC for index " + i + " is: " LOG.debug("\n\nNew section DOC for index " + i + " is: "
+ new JSONObject(fromSectionDoc.toJson()).toString(2)); + new JSONObject(fromSectionDoc.toJson()).toString(2));
@ -203,19 +204,18 @@ public class Geoportal_JSON_Mapper {
// Reading policy and license statically // Reading policy and license statically
// eg. "_access":{"_policy":"OPEN","_license":"CC0-1.0"}} // eg. "_access":{"_policy":"OPEN","_license":"CC0-1.0"}}
Document docAccess = null;
Access access = null; Access access = null;
try { try {
docAccess = fromSectionDoc.get("_access", Document.class);
LOG.trace("docAccess is: " + docAccess); List<FilePathDV> fileSetPaths = gcubeProfileDV.getFilePaths();
access = new Access(); if (fileSetPaths != null && fileSetPaths.size() > 0) {
access.setPolicy(AccessPolicy.valueOf(docAccess.getString("_policy"))); FilePathDV firstOne = fileSetPaths.get(0);
access.setLicense(docAccess.getString("_license")); access = getAccessPolicyObject(fromSectionDoc.toJson(),
// Access. access.get("_policy"); JSON_$_POINTER + "." + firstOne.getFieldName());
// access.get("_license");
System.out.println("access is: " + access); }
} catch (Exception e) { } catch (Exception e) {
LOG.warn("No " + AccessPolicy.class.getSimpleName() + "found in the section " LOG.warn("No " + AccessPolicy.class.getSimpleName() + " found in the section "
+ fromSectionDoc.toJson()); + fromSectionDoc.toJson());
LOG.debug("No AccessPolicy.class.getSimpleName(): ", e); LOG.debug("No AccessPolicy.class.getSimpleName(): ", e);
} }
@ -223,7 +223,7 @@ public class Geoportal_JSON_Mapper {
List<MetadataFieldWrapper> cloneListOfMFW = cloneList(theProfileBean.getMetadataFields()); List<MetadataFieldWrapper> cloneListOfMFW = cloneList(theProfileBean.getMetadataFields());
List<MetadataFieldWrapper> duplicatedList = new ArrayList<MetadataFieldWrapper>(); List<MetadataFieldWrapper> duplicatedList = new ArrayList<MetadataFieldWrapper>();
for (MetadataFieldWrapper metadataField : cloneListOfMFW) { for (MetadataFieldWrapper metadataField : cloneListOfMFW) {
String theFieldName = metadataField.getFieldId() != null ? metadataField.getFieldId() String theFieldName = metadataField.getFieldId() != null ? metadataField.getFieldId()
@ -233,47 +233,50 @@ public class Geoportal_JSON_Mapper {
if (access != null) { if (access != null) {
if (theFieldName.equalsIgnoreCase("policy")) { if (theFieldName.equalsIgnoreCase("policy")) {
metadataField.setCurrentValue(access.getPolicy().name()); metadataField.setCurrentValue(access.getPolicy().name());
duplicatedList.add(metadataField);
continue; continue;
} else if (theFieldName.equalsIgnoreCase("licenseID")) { } else if (theFieldName.equalsIgnoreCase("licenseID")) {
metadataField.setCurrentValue(access.getLicense()); metadataField.setCurrentValue(access.getLicense());
duplicatedList.add(metadataField);
continue; continue;
} }
} }
Object theOBJFieldValue = fromSectionDoc.get(theFieldName); Object theOBJFieldValue = fromSectionDoc.get(theFieldName);
if(theOBJFieldValue!=null) { if (theOBJFieldValue != null) {
//Converting multiple values stored as array (e.g. [a,b,c]) in multiple MetadataFieldWrapper // Converting multiple values stored as array (e.g. [a,b,c]) in multiple
//repeatable fields // MetadataFieldWrapper
LOG.debug("value "+theOBJFieldValue+ " is instanceof Array"); // repeatable fields
LOG.debug("value " + theOBJFieldValue + " is instanceof Array");
try { try {
JSONArray dataArray = new JSONArray(theOBJFieldValue+""); JSONArray dataArray = new JSONArray(theOBJFieldValue + "");
LOG.debug("It is an Array"); LOG.debug("It is an Array");
for (int j=0; j<dataArray.length(); j++) { for (int j = 0; j < dataArray.length(); j++) {
List<MetadataFieldWrapper> cloned = cloneList(Arrays.asList(metadataField)); List<MetadataFieldWrapper> cloned = cloneList(Arrays.asList(metadataField));
MetadataFieldWrapper mfw = cloned.get(0); MetadataFieldWrapper mfw = cloned.get(0);
mfw.setCurrentValue(dataArray.getString(j)); mfw.setCurrentValue(dataArray.getString(j));
//From the second repeated field settings // From the second repeated field settings
//mandatory false and one instance // mandatory false and one instance
//These properties are managed properly with the // These properties are managed properly with the
//first occurrence of the field // first occurrence of the field
if(j>=1) { if (j >= 1) {
mfw.setMandatory(false); mfw.setMandatory(false);
mfw.setMaxOccurs(1); mfw.setMaxOccurs(1);
} }
duplicatedList.add(mfw); duplicatedList.add(mfw);
} }
continue; continue;
}catch (Exception e) { } catch (Exception e) {
LOG.debug("It is not an Array"); LOG.debug("It is not an Array");
String theValue = theOBJFieldValue + ""; String theValue = theOBJFieldValue + "";
metadataField.setCurrentValue(theValue); metadataField.setCurrentValue(theValue);
} }
} }
duplicatedList.add(metadataField); duplicatedList.add(metadataField);
} }
theProfileBeanExt.setMetadataFields(new ArrayList<MetadataFieldWrapper>(duplicatedList)); theProfileBeanExt.setMetadataFields(new ArrayList<MetadataFieldWrapper>(duplicatedList));
@ -382,6 +385,7 @@ public class Geoportal_JSON_Mapper {
.get(scope); .get(scope);
// NO UCD defined, applying default // NO UCD defined, applying default
//Never checked. It coluld be buggy
if (linkedMap_UCDId_gCubeProfiles.size() == 0) { if (linkedMap_UCDId_gCubeProfiles.size() == 0) {
LOG.warn("No " + GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles + " found in the UCD"); LOG.warn("No " + GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles + " found in the UCD");
LOG.info("Applying default business logic to display the project"); LOG.info("Applying default business logic to display the project");
@ -476,6 +480,15 @@ public class Geoportal_JSON_Mapper {
LOG.debug("Data is instace of: " + data.getClass()); LOG.debug("Data is instace of: " + data.getClass());
LOG.debug("data to string: " + data.toString()); LOG.debug("data to string: " + data.toString());
List<FilePathDV> fileSetPaths = gcubeProfileDV.getFilePaths();
String filesetPath = JSON_$_POINTER;
if (fileSetPaths != null && fileSetPaths.size() > 0) {
//Reading the first fieldName that defines the name of the "fileset" field
FilePathDV firstOne = fileSetPaths.get(0);
filesetPath +="."+firstOne.getFieldName();
}
// Splitting the General Document in bson.Document according to list of // Splitting the General Document in bson.Document according to list of
// GcubeProfiles // GcubeProfiles
@ -484,7 +497,7 @@ public class Geoportal_JSON_Mapper {
String jsonString = data.toString(); String jsonString = data.toString();
LOG.debug("the JSON to string: " + jsonString); LOG.debug("the JSON to string: " + jsonString);
Document sectionDoc = Document.parse(jsonString); Document sectionDoc = Document.parse(jsonString);
boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, sectionJSONPath, boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, filesetPath,
username); username);
if (isAccessibleSection) { if (isAccessibleSection) {
listBSONDocument.add(sectionDoc); listBSONDocument.add(sectionDoc);
@ -545,18 +558,18 @@ public class Geoportal_JSON_Mapper {
// Reading Fileset _payloads // Reading Fileset _payloads
String filesetJSONPath = String.format("%s.%s", JSON_$_POINTER, filePath.getFieldName()); String filesetJSONPath = String.format("%s.%s", JSON_$_POINTER, filePath.getFieldName());
List<Payload> listPayloads = readPayloadsForFileset(filesetJSONPath, fromSectionDocJSON); List<Payload> listPayloads = readPayloadsForFileset(filesetJSONPath, fromSectionDocJSON);
if(LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
for (Payload payload : listPayloads) { for (Payload payload : listPayloads) {
LOG.debug("read payload: " + payload); LOG.debug("read payload: " + payload);
} }
} }
FilesetDV filesetImages = new FilesetDV(); FilesetDV filesetImages = new FilesetDV();
FilesetDV filesetFiles = new FilesetDV(); FilesetDV filesetFiles = new FilesetDV();
for (Payload payload : listPayloads) { for (Payload payload : listPayloads) {
PayloadDV payloadDV = ConvertToDataValueObjectModel.toPayloadDV(payload); PayloadDV payloadDV = ConvertToDataValueObjectModel.toPayloadDV(payload);
//filesetDV.addPayloadDV(payloadDV); // filesetDV.addPayloadDV(payloadDV);
boolean isImage = ImageDetector.isImage(payload.getMimetype()); boolean isImage = ImageDetector.isImage(payload.getMimetype());
if (isImage) { if (isImage) {
@ -567,12 +580,12 @@ public class Geoportal_JSON_Mapper {
filesetFiles.setName(filePath.getGcubeProfileFieldName()); filesetFiles.setName(filePath.getGcubeProfileFieldName());
} }
} }
//Setting only if one element exists // Setting only if one element exists
if(filesetImages.getListPayload()!=null && filesetImages.getListPayload().size()>0) { if (filesetImages.getListPayload() != null && filesetImages.getListPayload().size() > 0) {
listImages.add(filesetImages); listImages.add(filesetImages);
} }
if(filesetFiles.getListPayload()!=null && filesetFiles.getListPayload().size()>0) { if (filesetFiles.getListPayload() != null && filesetFiles.getListPayload().size() > 0) {
listFiles.add(filesetFiles); listFiles.add(filesetFiles);
} }
@ -745,7 +758,7 @@ public class Geoportal_JSON_Mapper {
} else if (objectJSON instanceof JSONObject) { } else if (objectJSON instanceof JSONObject) {
JSONObject theJsonObject = (JSONObject) objectJSON; JSONObject theJsonObject = (JSONObject) objectJSON;
LOG.trace("theJSONObject: " + theJsonObject.toString(3)); LOG.trace("theJSONObject: " + theJsonObject.toString(3));
GCubeSDIViewerLayerDV gsdiLayer = converLayer(config, theJsonObject); GCubeSDIViewerLayerDV gsdiLayer = convertLayer(config, theJsonObject);
listSDILayers.add(gsdiLayer); listSDILayers.add(gsdiLayer);
} }
@ -794,14 +807,14 @@ public class Geoportal_JSON_Mapper {
} }
/** /**
* Conver layer. * Convert layer.
* *
* @param config the config * @param config the config
* @param thJsonObject the th json object * @param thJsonObject the th json object
* @return the g cube SDI viewer layer DV * @return the g cube SDI viewer layer DV
*/ */
// TODO THIS PART SHOULD BE REVISITED/OPTIMIZED // TODO THIS PART SHOULD BE REVISITED/OPTIMIZED
private static GCubeSDIViewerLayerDV converLayer(com.jayway.jsonpath.Configuration config, private static GCubeSDIViewerLayerDV convertLayer(com.jayway.jsonpath.Configuration config,
JSONObject thJsonObject) { JSONObject thJsonObject) {
LOG.debug("converLayer called for " + thJsonObject); LOG.debug("converLayer called for " + thJsonObject);
@ -849,7 +862,8 @@ public class Geoportal_JSON_Mapper {
LOG.debug("converLayer returning: " + gsdiLayer); LOG.debug("converLayer returning: " + gsdiLayer);
return gsdiLayer; return gsdiLayer;
} }
/** /**
* Checks if is accessible section according to policy. * Checks if is accessible section according to policy.
* *
@ -858,76 +872,81 @@ public class Geoportal_JSON_Mapper {
* @param myLogin the my login * @param myLogin the my login
* @return true, if is accessible section according to policy * @return true, if is accessible section according to policy
*/ */
private static boolean isAccessibleSectionAccordingToPolicy(Document section, String sectionJSONPath, private static boolean isAccessibleSectionAccordingToPolicy(Document section, String filesetPath,
String myLogin) { String myLogin) {
LOG.debug("isAccessibleSectionAccordingToPolicy called"); LOG.debug("isAccessibleSectionAccordingToPolicy called");
boolean isAccessible = true; boolean isAccessible = true;
// Skipping the root, going to check the access_policy of subsections // Skipping the root, going to check the access_policy of subsections
if (sectionJSONPath.compareTo(JSON_$_POINTER) != 0) { //if (sectionJSONPath.compareTo(JSON_$_POINTER) != 0) {
isAccessible = checkAccessPolicy(section.toJson(), myLogin); isAccessible = checkAccessPolicy(section.toJson(), filesetPath, myLogin);
} //}
return isAccessible; return isAccessible;
} }
/** /**
* Check access policy. * Check access policy.
* *
* @param sectionDocumentJSON the section document JSON * @param sectionDocumentJSON the section document JSON
* @param filesetPath the fileset path. eg. $.filest | $.filesetIta | $.filesetEng, etc.
* @param myLogin the my login * @param myLogin the my login
* @return true, if successful * @return true, if successful
*/ */
private static boolean checkAccessPolicy(String sectionDocumentJSON, String myLogin) { private static boolean checkAccessPolicy(String sectionDocumentJSON, String filesetPath, String myLogin) {
LOG.info("checkAccessPolicy called"); LOG.debug("checkAccessPolicy called");
// CHECKING THE POLICY // CHECKING THE POLICY
// see ticket #24390 // see ticket #24390
// First reading the access policy from the fileset // First reading the access policy from the fileset*
String accessPolicyPath = JSON_$_POINTER + ".fileset._access._policy"; //String _policy = getAccessPolicy(sectionDocumentJSON);
Access _access = getAccessPolicyObject(sectionDocumentJSON, filesetPath);
boolean isAccessible = true; boolean isAccessible = true;
try { try {
com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() String _policy= _access!=null? _access.getPolicy().name():null;
.jsonProvider(new JsonOrgJsonProvider()).build();
LOG.debug("Reading access policy at {} into section document {}", accessPolicyPath, sectionDocumentJSON);
String _policy = null;
try {
JsonPath theSectionPolycJsonPath = JsonPath.compile(accessPolicyPath);
_policy = theSectionPolycJsonPath.read(sectionDocumentJSON, configuration).toString();
if (_policy == null)
throw new Exception("Policy is null");
} catch (Exception e) {
LOG.debug("Access policy not found in: " + accessPolicyPath);
}
// If policy does not exist into fileset, reading from the parent section
if (_policy == null) {
accessPolicyPath = JSON_$_POINTER + "._access._policy";
LOG.debug("Reading access policy at {} into section document {}", accessPolicyPath,
sectionDocumentJSON);
try {
JsonPath theSectionPolycJsonPath = JsonPath.compile(accessPolicyPath);
_policy = theSectionPolycJsonPath.read(sectionDocumentJSON, configuration).toString();
if (_policy == null)
throw new Exception("Policy is null");
} catch (Exception e) {
LOG.debug("Access policy not found in: " + accessPolicyPath);
}
}
LOG.debug("The section {} has policy {}", accessPolicyPath, _policy);
isAccessible = GeportalCheckAccessPolicy.isAccessible(_policy, myLogin); isAccessible = GeportalCheckAccessPolicy.isAccessible(_policy, myLogin);
} catch (Exception e) { } catch (Exception e) {
LOG.error(accessPolicyPath + " not found. Check OK"); LOG.error("AccessPolicy not found. Check OK");
} }
LOG.info("It is {} accessible the section {} accessible? {}", isAccessible, sectionDocumentJSON); LOG.info("It is {} accessible the section {}", isAccessible, sectionDocumentJSON);
return isAccessible; return isAccessible;
} }
/**
* Gets the access policy object.
*
* @param theSectionDoc the the section doc
* @param filesetPath the fileset path
* @return the access policy object
*/
private static Access getAccessPolicyObject(String theSectionDoc, String filesetPath) {
LOG.debug("getAccessPolicyObject called");
// CHECKING THE POLICY
// see ticket #24390
// First reading the access policy from the fileset*
Configuration configuration = Configuration.builder().jsonProvider(new JsonOrgJsonProvider()).build();
// Searching the _access under the fileset field...
String accessPolicyPath = filesetPath + "._access";
Access _access = readSectionObject(configuration, theSectionDoc, accessPolicyPath, Access.class);
// If policy does not exist under the fileset field, searching it at first level
if (_access == null) {
accessPolicyPath = JSON_$_POINTER + "._access";
LOG.info(accessPolicyPath + " not found trying to read from: " + accessPolicyPath);
_access = readSectionObject(configuration, theSectionDoc, accessPolicyPath, Access.class);
}
if (_access == null) {
LOG.info(accessPolicyPath + " not found trying to read from metadata: " + JSON_$_POINTER);
_access = ConvertToDataServiceModel.getAccessFromDocumentSection(theSectionDoc, JSON_$_POINTER);
}
LOG.info("The _access is {} for the filesetPath {}", _access, filesetPath);
return _access;
}
/** /**
* Sanitize document value. * Sanitize document value.
* *
@ -964,6 +983,38 @@ public class Geoportal_JSON_Mapper {
return toDoc; return toDoc;
} }
/**
* Read section object.
*
* @param <T> the generic type
* @param configuration the configuration
* @param sectionDocumentJSON the section document JSON
* @param accessPolicyPath the access policy path
* @param theClass the the class
* @return the t
*/
private static <T> T readSectionObject(com.jayway.jsonpath.Configuration configuration, String sectionDocumentJSON,
String accessPolicyPath, Class<T> theClass) {
T _theObject = null;
LOG.debug("Reading access at {} into section document {}", accessPolicyPath, sectionDocumentJSON);
try {
JsonPath theSectionPolycJsonPath = JsonPath.compile(accessPolicyPath);
String _objectString = theSectionPolycJsonPath.read(sectionDocumentJSON, configuration).toString();
LOG.info("Read at {} the _objectString {}", accessPolicyPath, _objectString);
if (_objectString != null) {
_theObject = Serialization.read(_objectString, theClass);
}
} catch (Exception e) {
LOG.warn("Access policy not found in: " + accessPolicyPath);
}
return _theObject;
}
/** /**
* Pretty print JSON. * Pretty print JSON.
* *

View File

@ -40,7 +40,7 @@ public class Geoportal_DataMapper_Tests {
private ProjectsCaller clientProjects; private ProjectsCaller clientProjects;
private static String PROFILE_ID = "profiledConcessioni"; private static String PROFILE_ID = "profiledConcessioni";
private static String PROJECT_ID = "6384aaac308f5c28c5ee0888"; private static String PROJECT_ID = "642d4c6bc2133270c058eca8"; //63d011c4dcac4551b9a6b930
private static String USERNAME = "francesco.mangiacrapa"; private static String USERNAME = "francesco.mangiacrapa";
@ -85,7 +85,7 @@ public class Geoportal_DataMapper_Tests {
/** /**
* Test read project edit. * Test read project edit.
*/ */
@Test //@Test
public void testReadProjectEdit() { public void testReadProjectEdit() {
try { try {
@ -110,7 +110,7 @@ public class Geoportal_DataMapper_Tests {
/** /**
* Test read project view. * Test read project view.
*/ */
// @Test //@Test
public void testReadProjectView() { public void testReadProjectView() {
try { try {

View File

@ -1 +1,2 @@
/gcube_config.properties /gcube_config.properties
/log4j.properties