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.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<FilePathDV> 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<MetadataFieldWrapper> cloneListOfMFW = cloneList(theProfileBean.getMetadataFields());
List<MetadataFieldWrapper> duplicatedList = new ArrayList<MetadataFieldWrapper>();
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<dataArray.length(); j++) {
for (int j = 0; j < dataArray.length(); j++) {
List<MetadataFieldWrapper> 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<MetadataFieldWrapper>(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<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
// 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<Payload> 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 <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.
*

View File

@ -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 {

View File

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