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 7f25b13..6c8e8ed 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java @@ -1,5 +1,6 @@ package org.gcube.gcat.persistence.ckan; +import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -75,7 +76,7 @@ public class CKANPackage extends CKAN { protected static final String ORGANIZATION_FILTER_TEMPLATE = GCatConstants.ORGANIZATION_PARAMETER + ":%s"; - protected static final String ORGANIZATION_REGEX = GCatConstants.ORGANIZATION_PARAMETER + ":[a-zA-Z_\"]*"; + protected static final String ORGANIZATION_REGEX = GCatConstants.ORGANIZATION_PARAMETER + ":[a-zA-Z0-9_\"]*"; protected static final Pattern ORGANIZATION_REGEX_PATTERN; @@ -203,8 +204,6 @@ public class CKANPackage extends CKAN { } protected CKANOrganization checkGotOrganization(String gotOrganization) throws ForbiddenException { - // TODO Check if it is allowed to publish in such organization by reading an IS resource - if(!supportedOrganizations.contains(gotOrganization)) { String error = String.format( "IS Configuration does not allow to publish in %s organizations. Allowed organization are: %s", @@ -336,81 +335,65 @@ public class CKANPackage extends CKAN { return list(parameters); } - - /* - * TODO support the allowed organization in the VRE - */ - protected void checkOrganizationFilter(String q) { + + protected Set checkOrganizationFilter(String q) { Matcher m = ORGANIZATION_REGEX_PATTERN.matcher(q); - List matches = new ArrayList<>(); + Set matches = new HashSet<>(); while(m.find()) { - matches.add(q.substring(m.start(), m.end())); + matches.add(q.substring(m.start(), m.end()).replace(GCatConstants.ORGANIZATION_PARAMETER+":", "")); } - if(matches.size() > 0) { - StringBuilder error = new StringBuilder(); - error.append("Organization filters is constrained to VRE. "); - if(matches.size() > 1) { - error.append("Remove these filters "); - } else { - error.append("Remove this filter "); - } - boolean first = true; - for(String match : matches) { - if(!first) { - error.append(", "); - } else { - first = false; - } - error.append("["); - error.append(match); - error.append("]"); - } - throw new BadRequestException(error.toString()); - } + return matches; } protected static String[] allowedListQueryParameters = new String[] {"q", "fq", "fq_list", "sort", /* "facet", "facet.mincount", "facet.limit", "facet.field", */ "include_drafts", "include_private", "ext_bbox"}; + protected String getFilterForOrganizations() { + StringWriter stringWriter = new StringWriter(); + int i=1; + for(String organizationName : supportedOrganizations) { + stringWriter.append(String.format(GCatConstants.ORGANIZATION_FILTER_TEMPLATE, organizationName)); + if(i!=supportedOrganizations.size()) { + // Please note that an item can only belong to a single organization. + // Hence the query must put supported organizations in OR. + stringWriter.append(" OR "); + } + i++; + } + return stringWriter.toString(); + } + protected Map checkListParameters(MultivaluedMap queryParameters, Map parameters) { - String organizationName = getOrganizationName(); - ScopeBean scopeBean = new ScopeBean(ContextUtility.getCurrentContext()); - String q = null; if(queryParameters.containsKey(GCatConstants.Q_KEY)) { q = queryParameters.getFirst(GCatConstants.Q_KEY); } - - // TODO check against feature #19365 - /* - * List is filter per organization only is the request arriving in a VRE. - * If the request arrive form a VO or from ROOT the request return the item in all organizations - * in the catalog. - */ - if(scopeBean.is(Type.VRE)) { - if(q != null) { - checkOrganizationFilter(q); - + if(q != null) { + Set organizations = checkOrganizationFilter(q); + + if(organizations.size()==0) { // Adding organization filter to q - parameters.put(GCatConstants.Q_KEY, - String.format("%s:%s AND %s", GCatConstants.ORGANIZATION_PARAMETER, organizationName, q)); - - } else { - parameters.put(GCatConstants.Q_KEY, - String.format(GCatConstants.ORGANIZATION_FILTER_TEMPLATE, organizationName)); + String filter = getFilterForOrganizations(); + parameters.put(GCatConstants.Q_KEY, String.format("%s AND %s", q, filter)); + }else { + organizations.removeAll(this.supportedOrganizations); + if(organizations.size()>0) { + String error = String.format("It is not possible to query the following organizations %s. Supported organization in this context are %s", organizations.toString(), supportedOrganizations.toString()); + throw new ForbiddenException(error); + } } } else { - // We are in VO or in ROOT. - // The organization filtering is allowed for the client which must provide q parameter in the form: - // q=organization:nextnext + String filter = getFilterForOrganizations(); + parameters.put(GCatConstants.Q_KEY, filter); } + for(String key : allowedListQueryParameters) { if(queryParameters.containsKey(key)) { 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 faa6073..520a5ab 100644 --- a/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java +++ b/src/test/java/org/gcube/gcat/persistence/ckan/CKANPackageTest.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Set; import javax.ws.rs.BadRequestException; +import javax.ws.rs.ForbiddenException; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; @@ -56,33 +57,64 @@ public class CKANPackageTest extends ContextTest { @Test public void listWithParameters() throws Exception { + String contextName = "/gcube/devNext/NextNext"; + ScopeBean scopeBean = new ScopeBean(contextName); + String ckanOrganizationName = CKANPackage.getOrganizationName(scopeBean); + ContextTest.setContextByName(contextName); + CKANPackage ckanPackage = new CKANPackage(); ObjectMapper mapper = new ObjectMapper(); - Map parameters = new HashMap<>(); - parameters.put(GCatConstants.Q_KEY, "organization:ckand4scienceharvest OR organization:dorne"); - // parameters.put(GCatConstants.Q_KEY, "organization:ckand4scienceharvest"); - // parameters.put(GCatConstants.Q_KEY, "organization:dorne"); + Map parameters = new HashMap<>(); parameters.put(CKANPackage.ROWS_KEY, String.valueOf(10)); parameters.put(CKANPackage.START_KEY, String.valueOf(0)); - /* - parameters.put("fl","[\"name\"]"); - */ + boolean[] values = new boolean[]{true, false}; - /* - parameters.put("facet.field","[\"name\"]"); - parameters.put("sort","name asc"); - */ + for(boolean includeFakeOrganization : values) { - String ret = ckanPackage.list(parameters); - JsonNode gotList = mapper.readTree(ret); - Assert.assertTrue(gotList instanceof ArrayNode); - - logger.debug("List :\n{}", mapper.writeValueAsString(gotList)); + MultivaluedMap queryParameters = new MultivaluedHashMap<>(); + if(includeFakeOrganization) { + queryParameters.add(GCatConstants.Q_KEY, "organization:ckand4scienceharvest OR organization:"+ckanOrganizationName); + }else { + queryParameters.add(GCatConstants.Q_KEY, "organization:"+ckanOrganizationName); + } + // parameters.put(GCatConstants.Q_KEY, "organization:ckand4scienceharvest"); + // parameters.put(GCatConstants.Q_KEY, "organization:dorne"); + + /* + queryParameters.add(CKANPackage.ROWS_KEY, String.valueOf(10)); + queryParameters.add(CKANPackage.START_KEY, String.valueOf(0)); + */ + + /* + parameters.put("fl","[\"name\"]"); + */ + + /* + parameters.put("facet.field","[\"name\"]"); + parameters.put("sort","name asc"); + */ + + try { + parameters = ckanPackage.checkListParameters(queryParameters, parameters); + }catch (ForbiddenException e) { + if(includeFakeOrganization) { + // This is the expected behaviour + continue; + }else { + throw e; + } + } + + String ret = ckanPackage.list(parameters); + JsonNode gotList = mapper.readTree(ret); + Assert.assertTrue(gotList instanceof ArrayNode); + + logger.debug("List :\n{}", mapper.writeValueAsString(gotList)); + } } - protected GenericResource instantiateGenericResource(String secondaryType, String name, String xml) throws Exception { GenericResource genericResource = new GenericResource(); org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile();