From 4f799628e09b3128f85962ec7fc37fee7dc37075 Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Thu, 6 Apr 2023 11:33:22 +0200 Subject: [PATCH] Improved and fixed reading of Access Policy from the Document --- .../Geoportal_JSON_Mapper.java | 229 +++++++++++------- src/test/java/Geoportal_DataMapper_Tests.java | 6 +- src/test/resources/.gitignore | 1 + 3 files changed, 144 insertions(+), 92 deletions(-) diff --git a/src/main/java/org/gcube/application/geoportaldatamapper/Geoportal_JSON_Mapper.java b/src/main/java/org/gcube/application/geoportaldatamapper/Geoportal_JSON_Mapper.java index 9b68bc1..5dad24d 100644 --- a/src/main/java/org/gcube/application/geoportaldatamapper/Geoportal_JSON_Mapper.java +++ b/src/main/java/org/gcube/application/geoportaldatamapper/Geoportal_JSON_Mapper.java @@ -11,6 +11,7 @@ import org.bson.Document; 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.AccessPolicy; +import org.gcube.application.geoportalcommon.ConvertToDataServiceModel; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.geoportal.access.GeportalCheckAccessPolicy; 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.JsonObject; import com.google.gson.JsonParser; +import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider; @@ -87,7 +89,7 @@ public class Geoportal_JSON_Mapper { LOG.debug("theProjectDV as JSON: " + theWholeProjectAsJSON); LOG.trace("theProjectDV as MAP: " + theProjectDV.getTheDocument().getDocumentAsMap()); - + ProjectEdit projectEdit = new ProjectEdit(); projectEdit.setTheProjectDV(theProjectDV); @@ -131,8 +133,8 @@ public class Geoportal_JSON_Mapper { for (GcubeProfilesMetadataForUCD gcubeProfileMetaForUCD : listProfilesBean) { GcubeProfileDV gcubeProfileDV = gcubeProfileMetaForUCD.getGcubeProfile(); - LOG.debug("\n\n##### Creating the section: " + gcubeProfileDV.getSectionTitle()); - LOG.debug("\n\nThe profile is: " + gcubeProfileDV); + LOG.info("\n\n##### Creating the section: " + gcubeProfileDV.getSectionTitle()); + LOG.info("\n\nThe profile is: " + gcubeProfileDV); // Building JSON/section full PATH and section name String sectionJSONPath = ""; String parentPathFromProfile = gcubeProfileDV.getParentName() == null ? "" : gcubeProfileDV.getParentName(); @@ -195,7 +197,6 @@ public class Geoportal_JSON_Mapper { theProfileBeanExt.setTitle(theProfileBean.getTitle()); theProfileBeanExt.setType(theProfileBean.getType()); theProfileBeanExt.setGcubeProfile(gcubeProfileDV); - Document fromSectionDoc = listBSONDocument.get(i); LOG.debug("\n\nNew section DOC for index " + i + " is: " + new JSONObject(fromSectionDoc.toJson()).toString(2)); @@ -203,19 +204,18 @@ public class Geoportal_JSON_Mapper { // Reading policy and license statically // eg. "_access":{"_policy":"OPEN","_license":"CC0-1.0"}} - Document docAccess = null; Access access = null; try { - docAccess = fromSectionDoc.get("_access", Document.class); - LOG.trace("docAccess is: " + docAccess); - access = new Access(); - access.setPolicy(AccessPolicy.valueOf(docAccess.getString("_policy"))); - access.setLicense(docAccess.getString("_license")); - // Access. access.get("_policy"); - // access.get("_license"); - System.out.println("access is: " + access); + + List fileSetPaths = gcubeProfileDV.getFilePaths(); + if (fileSetPaths != null && fileSetPaths.size() > 0) { + FilePathDV firstOne = fileSetPaths.get(0); + access = getAccessPolicyObject(fromSectionDoc.toJson(), + JSON_$_POINTER + "." + firstOne.getFieldName()); + + } } 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()); LOG.debug("No AccessPolicy.class.getSimpleName(): ", e); } @@ -223,7 +223,7 @@ public class Geoportal_JSON_Mapper { List cloneListOfMFW = cloneList(theProfileBean.getMetadataFields()); List duplicatedList = new ArrayList(); - + for (MetadataFieldWrapper metadataField : cloneListOfMFW) { String theFieldName = metadataField.getFieldId() != null ? metadataField.getFieldId() @@ -233,47 +233,50 @@ public class Geoportal_JSON_Mapper { if (access != null) { if (theFieldName.equalsIgnoreCase("policy")) { metadataField.setCurrentValue(access.getPolicy().name()); + duplicatedList.add(metadataField); continue; } else if (theFieldName.equalsIgnoreCase("licenseID")) { metadataField.setCurrentValue(access.getLicense()); + duplicatedList.add(metadataField); continue; } } - + Object theOBJFieldValue = fromSectionDoc.get(theFieldName); - - if(theOBJFieldValue!=null) { - //Converting multiple values stored as array (e.g. [a,b,c]) in multiple MetadataFieldWrapper - //repeatable fields - LOG.debug("value "+theOBJFieldValue+ " is instanceof Array"); + + if (theOBJFieldValue != null) { + // Converting multiple values stored as array (e.g. [a,b,c]) in multiple + // MetadataFieldWrapper + // repeatable fields + LOG.debug("value " + theOBJFieldValue + " is instanceof Array"); try { - JSONArray dataArray = new JSONArray(theOBJFieldValue+""); + JSONArray dataArray = new JSONArray(theOBJFieldValue + ""); LOG.debug("It is an Array"); - for (int j=0; j cloned = cloneList(Arrays.asList(metadataField)); MetadataFieldWrapper mfw = cloned.get(0); mfw.setCurrentValue(dataArray.getString(j)); - - //From the second repeated field settings - //mandatory false and one instance - //These properties are managed properly with the - //first occurrence of the field - if(j>=1) { + + // From the second repeated field settings + // mandatory false and one instance + // These properties are managed properly with the + // first occurrence of the field + if (j >= 1) { mfw.setMandatory(false); mfw.setMaxOccurs(1); } duplicatedList.add(mfw); } continue; - }catch (Exception e) { + } catch (Exception e) { LOG.debug("It is not an Array"); String theValue = theOBJFieldValue + ""; metadataField.setCurrentValue(theValue); } } - + duplicatedList.add(metadataField); - + } theProfileBeanExt.setMetadataFields(new ArrayList(duplicatedList)); @@ -382,6 +385,7 @@ public class Geoportal_JSON_Mapper { .get(scope); // NO UCD defined, applying default + //Never checked. It coluld be buggy if (linkedMap_UCDId_gCubeProfiles.size() == 0) { LOG.warn("No " + GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles + " found in the UCD"); 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 to string: " + data.toString()); + + List 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 // GcubeProfiles @@ -484,7 +497,7 @@ public class Geoportal_JSON_Mapper { String jsonString = data.toString(); LOG.debug("the JSON to string: " + jsonString); Document sectionDoc = Document.parse(jsonString); - boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, sectionJSONPath, + boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, filesetPath, username); if (isAccessibleSection) { listBSONDocument.add(sectionDoc); @@ -545,18 +558,18 @@ public class Geoportal_JSON_Mapper { // Reading Fileset _payloads String filesetJSONPath = String.format("%s.%s", JSON_$_POINTER, filePath.getFieldName()); List listPayloads = readPayloadsForFileset(filesetJSONPath, fromSectionDocJSON); - if(LOG.isDebugEnabled()) { + if (LOG.isDebugEnabled()) { for (Payload payload : listPayloads) { LOG.debug("read payload: " + payload); } } - + FilesetDV filesetImages = new FilesetDV(); FilesetDV filesetFiles = new FilesetDV(); - + for (Payload payload : listPayloads) { PayloadDV payloadDV = ConvertToDataValueObjectModel.toPayloadDV(payload); - //filesetDV.addPayloadDV(payloadDV); + // filesetDV.addPayloadDV(payloadDV); boolean isImage = ImageDetector.isImage(payload.getMimetype()); if (isImage) { @@ -567,12 +580,12 @@ public class Geoportal_JSON_Mapper { filesetFiles.setName(filePath.getGcubeProfileFieldName()); } } - - //Setting only if one element exists - if(filesetImages.getListPayload()!=null && filesetImages.getListPayload().size()>0) { + + // Setting only if one element exists + if (filesetImages.getListPayload() != null && filesetImages.getListPayload().size() > 0) { listImages.add(filesetImages); } - if(filesetFiles.getListPayload()!=null && filesetFiles.getListPayload().size()>0) { + if (filesetFiles.getListPayload() != null && filesetFiles.getListPayload().size() > 0) { listFiles.add(filesetFiles); } @@ -745,7 +758,7 @@ public class Geoportal_JSON_Mapper { } else if (objectJSON instanceof JSONObject) { JSONObject theJsonObject = (JSONObject) objectJSON; LOG.trace("theJSONObject: " + theJsonObject.toString(3)); - GCubeSDIViewerLayerDV gsdiLayer = converLayer(config, theJsonObject); + GCubeSDIViewerLayerDV gsdiLayer = convertLayer(config, theJsonObject); listSDILayers.add(gsdiLayer); } @@ -794,14 +807,14 @@ public class Geoportal_JSON_Mapper { } /** - * Conver layer. + * Convert layer. * * @param config the config * @param thJsonObject the th json object * @return the g cube SDI viewer layer DV */ // 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) { LOG.debug("converLayer called for " + thJsonObject); @@ -849,7 +862,8 @@ public class Geoportal_JSON_Mapper { LOG.debug("converLayer returning: " + gsdiLayer); return gsdiLayer; } - + + /** * Checks if is accessible section according to policy. * @@ -858,76 +872,81 @@ public class Geoportal_JSON_Mapper { * @param myLogin the my login * @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) { LOG.debug("isAccessibleSectionAccordingToPolicy called"); boolean isAccessible = true; // Skipping the root, going to check the access_policy of subsections - if (sectionJSONPath.compareTo(JSON_$_POINTER) != 0) { - isAccessible = checkAccessPolicy(section.toJson(), myLogin); - } + //if (sectionJSONPath.compareTo(JSON_$_POINTER) != 0) { + isAccessible = checkAccessPolicy(section.toJson(), filesetPath, myLogin); + //} return isAccessible; } + /** * Check access policy. * * @param sectionDocumentJSON the section document JSON + * @param filesetPath the fileset path. eg. $.filest | $.filesetIta | $.filesetEng, etc. * @param myLogin the my login * @return true, if successful */ - private static boolean checkAccessPolicy(String sectionDocumentJSON, String myLogin) { - LOG.info("checkAccessPolicy called"); + private static boolean checkAccessPolicy(String sectionDocumentJSON, String filesetPath, String myLogin) { + LOG.debug("checkAccessPolicy called"); // CHECKING THE POLICY // see ticket #24390 - // First reading the access policy from the fileset - String accessPolicyPath = JSON_$_POINTER + ".fileset._access._policy"; + // First reading the access policy from the fileset* + //String _policy = getAccessPolicy(sectionDocumentJSON); + Access _access = getAccessPolicyObject(sectionDocumentJSON, filesetPath); boolean isAccessible = true; try { - com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() - .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); + String _policy= _access!=null? _access.getPolicy().name():null; isAccessible = GeportalCheckAccessPolicy.isAccessible(_policy, myLogin); } 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; } + + /** + * 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. * @@ -964,6 +983,38 @@ public class Geoportal_JSON_Mapper { return toDoc; } + /** + * Read section object. + * + * @param 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 readSectionObject(com.jayway.jsonpath.Configuration configuration, String sectionDocumentJSON, + String accessPolicyPath, Class 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. * diff --git a/src/test/java/Geoportal_DataMapper_Tests.java b/src/test/java/Geoportal_DataMapper_Tests.java index 93e3207..514af6c 100644 --- a/src/test/java/Geoportal_DataMapper_Tests.java +++ b/src/test/java/Geoportal_DataMapper_Tests.java @@ -40,7 +40,7 @@ public class Geoportal_DataMapper_Tests { private ProjectsCaller clientProjects; 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"; @@ -85,7 +85,7 @@ public class Geoportal_DataMapper_Tests { /** * Test read project edit. */ - @Test + //@Test public void testReadProjectEdit() { try { @@ -110,7 +110,7 @@ public class Geoportal_DataMapper_Tests { /** * Test read project view. */ - // @Test + //@Test public void testReadProjectView() { try { diff --git a/src/test/resources/.gitignore b/src/test/resources/.gitignore index 3f12f69..c336e9b 100644 --- a/src/test/resources/.gitignore +++ b/src/test/resources/.gitignore @@ -1 +1,2 @@ /gcube_config.properties +/log4j.properties