diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java index b8b6449..659e8a1 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java @@ -892,11 +892,11 @@ public class CKANPackage extends CKAN implements Moderated { throw new ForbiddenException(stringBuffer.toString()); } - Map readSystemFields = getSystemFields(json); - if(readSystemFields.size()>0) { - readSystemFields.remove(EXTRAS_KEY_VALUE_SYSTEM_TYPE); - throw new BadRequestException("Client cannot manage the system metadata e.g. " + readSystemFields.toString()); + Map providedSystemMetadata = getModerationSystemMetadata(json); + if(providedSystemMetadata.size()>0) { + throw new BadRequestException("You cannot manage the system metadata. Got " + providedSystemMetadata.toString()); } + JsonNode jsonNode = validateJson(json); setItemToPending(jsonNode); @@ -941,9 +941,11 @@ public class CKANPackage extends CKAN implements Moderated { } public static final String JSON_PATH_EXPRESSION_FIND_SYSTEM_METADATA = "$.extras[?(@.key =~ /system.*?/i)]"; + public static final String JSON_PATH_EXPRESSION_FIND_SYSTEM_TYPE_METADATA = "$.extras[?(@.key == 'system:type')].value"; + public static final String JSON_PATH_EXPRESSION_FIND_MODERATION_SYSTEM_METADATA = "$.extras[?(@.key =~ /system\\:cm_.*?/i)]"; - protected Map getSystemFields(String json){ - JSONArray array = JsonPath.read(json, JSON_PATH_EXPRESSION_FIND_SYSTEM_METADATA); + protected static Map getExtraFieldsViaJsonPath(String json, String jsonPath){ + JSONArray array = JsonPath.read(json, jsonPath); logger.trace("Found system metadata {} ", array); Map systemFieldMap = new HashMap<>(); @@ -956,6 +958,18 @@ public class CKANPackage extends CKAN implements Moderated { return systemFieldMap; } + protected static Map getSystemMetadata(String json){ + return getExtraFieldsViaJsonPath(json, JSON_PATH_EXPRESSION_FIND_SYSTEM_METADATA); + } + + protected static Map getSystemTypeMetadata(String json){ + return getExtraFieldsViaJsonPath(json, JSON_PATH_EXPRESSION_FIND_SYSTEM_TYPE_METADATA); + } + + protected static Map getModerationSystemMetadata(String json){ + return getExtraFieldsViaJsonPath(json, JSON_PATH_EXPRESSION_FIND_MODERATION_SYSTEM_METADATA); + } + // see https://docs.ckan.org/en/latest/api/#ckan.logic.action.update.package_update @Override public String update(String json) { @@ -965,15 +979,11 @@ public class CKANPackage extends CKAN implements Moderated { this.result = null; readItem(); - String readJson = mapper.writeValueAsString(this.result); - Map readSystemFields = getSystemFields(readJson); - JsonNode jsonNode = validateJson(json); - Map providedSystemFields = getSystemFields(json); - if(!readSystemFields.equals(providedSystemFields)) { - throw new BadRequestException("Client cannot manage the system metadata. Expected " + - readSystemFields.toString() + " - Got " + providedSystemFields.toString()); + Map providedSystemMetadata = CKANPackage.getModerationSystemMetadata(json); + if(providedSystemMetadata.size()>0) { + throw new BadRequestException("You cannot manage the system metadata. Got " + providedSystemMetadata.toString()); } jsonNode = checkModerationUpdate(jsonNode); @@ -1045,9 +1055,9 @@ public class CKANPackage extends CKAN implements Moderated { this.result = null; readItem(); - Map providedSystemFields = getSystemFields(json); - if(providedSystemFields.size()>0) { - throw new BadRequestException("Client cannot manage the system metadata"); + Map providedSystemMetadata = CKANPackage.getSystemMetadata(json); + if(providedSystemMetadata.size()>0) { + throw new BadRequestException("You cannot manage the system metadata. Got " + providedSystemMetadata.toString()); } JsonNode jsonNode = checkBaseInformation(json, true); diff --git a/src/test/java/org/gcube/gcat/jsonpath/JsonPathTester.java b/src/test/java/org/gcube/gcat/jsonpath/JsonPathTester.java index 4c09a57..67150a4 100644 --- a/src/test/java/org/gcube/gcat/jsonpath/JsonPathTester.java +++ b/src/test/java/org/gcube/gcat/jsonpath/JsonPathTester.java @@ -12,6 +12,7 @@ import java.util.Map; import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; +import org.gcube.gcat.persistence.ckan.CKANPackage; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; @@ -44,28 +45,27 @@ public class JsonPathTester { File itemFile = new File(examplesDir, "item-01.json"); String json = readFile(itemFile); - List systemTypes = JsonPath.read(json, "$.extras[?(@.key == 'system:type')].value"); - Assert.assertTrue(systemTypes.size()==1); - logger.trace("System Type : {}", systemTypes); + JSONArray systemType = JsonPath.read(json, CKANPackage.JSON_PATH_EXPRESSION_FIND_SYSTEM_TYPE_METADATA); + Assert.assertTrue(systemType.size()==1); + logger.trace("System Type : {}", systemType); - List systemFields = JsonPath.read(json, "$.extras[?(@.key =~ /system.*?/i)]"); - logger.trace("System Fields : {}", systemFields); - - JSONArray array = JsonPath.read(json, "$.extras[?(@.key =~ /system.*?/i)]"); - logger.trace("Array {} ", array); + JSONArray systemMetadata = JsonPath.read(json, CKANPackage.JSON_PATH_EXPRESSION_FIND_SYSTEM_METADATA); + logger.trace("System Metadata {} ", systemMetadata); Map systemFieldMap = new HashMap<>(); Map anotherSystemFieldMap = new HashMap<>(); - for(Object obj : array) { + for(Object obj : systemMetadata) { LinkedHashMap element = (LinkedHashMap) obj; - systemFieldMap.put(element.get("key"), element.get("value")); - anotherSystemFieldMap.put(element.get("key"), element.get("value")); + systemFieldMap.put(element.get(CKANPackage.EXTRAS_KEY_KEY), element.get(CKANPackage.EXTRAS_VALUE_KEY)); + anotherSystemFieldMap.put(element.get(CKANPackage.EXTRAS_KEY_KEY), element.get(CKANPackage.EXTRAS_VALUE_KEY)); } - - Assert.assertTrue(systemFieldMap.equals(anotherSystemFieldMap)); + JSONArray moderationSystemMetadata = JsonPath.read(json, CKANPackage.JSON_PATH_EXPRESSION_FIND_MODERATION_SYSTEM_METADATA); + logger.trace("Moderation System Fields {} ", moderationSystemMetadata); + Assert.assertTrue(moderationSystemMetadata.size()+1 == systemMetadata.size()); + } } diff --git a/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java b/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java index 28ce1a7..a919c1a 100644 --- a/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java +++ b/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java @@ -508,9 +508,37 @@ public class CKANPackageTest extends ContextTest { CKANPackage ckanPackage = new CKANPackage(); ckanPackage.setName("a_test_item"); File examplesDir = getExamplesDirectory(); - File itemFile = new File(examplesDir, "a_test_item_ko.json"); - String json = readFile(itemFile); - ckanPackage.create(json); + File createFile = new File(examplesDir, "a_test_item_create_ko.json"); + String json = readFile(createFile); + try { + ckanPackage.create(json); + }catch (Exception e) { + logger.error(e.getMessage()); + } + } + + @Test(expected = BadRequestException.class) + public void testUpdateWithChangedModerationSystemMetadata() throws Exception { + try { + CKANPackage ckanPackage = new CKANPackage(); + ckanPackage.setName("a_test_item"); + File examplesDir = getExamplesDirectory(); + File createFile = new File(examplesDir, "a_test_item_create_ok.json"); + String json = readFile(createFile); + json = ckanPackage.create(json); + JsonNode jsonNode = ckanPackage.mapper.readTree(json); + ckanPackage.setItemToPending(jsonNode); + String updateJson = ckanPackage.mapper.writeValueAsString(jsonNode); + ckanPackage.update(updateJson); + } catch (Exception e) { + logger.error(e.getMessage()); + throw e; + }finally { + CKANPackage ckanPackage = new CKANPackage(); + ckanPackage.setName("a_test_item"); + ckanPackage.purge(); + } + } @Test diff --git a/src/test/resources/examples/a_test_item_create_ok.json b/src/test/resources/examples/a_test_item_create_ok.json new file mode 100644 index 0000000..3d27d25 --- /dev/null +++ b/src/test/resources/examples/a_test_item_create_ok.json @@ -0,0 +1,40 @@ +{ + "name": "a_test_item", + "title": "A Test Item", + "license_id": "CC-BY-SA-4.0", + "private": false, + "notes": "A test item of Luca Frosini", + "url": "http://www.d4science.org", + "tags": [ + { + "name": "Test" + } + ], + "resources": [], + "extras": [ + { + "key": "Language", + "value": "EN" + }, + { + "key": "system:type", + "value": "EmptyProfile" + }, + { + "key": "system:cm_item_author", + "value": "francesco_mangiacrapa" + }, + { + "key": "system:cm_item_author_fullname", + "value": "Francesco Mangiacrapa" + }, + { + "key": "system:cm_item_status", + "value": "approved" + }, + { + "key": "system:cm_item_visibility", + "value": "restricted" + } + ] +} \ No newline at end of file