improved checks for application tokens

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/catalogue-ws@164564 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2018-02-23 14:36:15 +00:00
parent 827ad3d740
commit f83ce30d82
13 changed files with 137 additions and 59 deletions

View File

@ -4,9 +4,6 @@
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="ckan-util-library-2.4.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/ckan-util-library/ckan-util-library">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="catalogue-ws"/>
<property name="java-output-path" value="/catalogue-ws/target/classes"/>
</wb-module>

View File

@ -11,7 +11,7 @@
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>catalogue-ws</artifactId>
<packaging>war</packaging>
<version>1.1.1-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<name>catalogue-ws</name>
<description>

View File

@ -3,7 +3,7 @@ package org.gcube.datacatalogue.catalogue.beans.resource;
import org.json.simple.JSONObject;
/**
* A custom field. It also stores index of the category and of the metadata field associated.
* A custom field bean. It also stores index of the category and of the metadata field associated.
* These are used to sort them before pushing the content to CKAN.
* If they are missing, indexes are set to Integer.MAX_VALUE.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)

View File

@ -41,8 +41,7 @@ public class CatalogueUtils {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CatalogueUtils.class);
/**
* Retrieve an instance of the library for the scope
* @param scope if it is null it is evaluated from the session
* Retrieve an instance of the library for the current scope
* @return
* @throws Exception
*/

View File

@ -103,7 +103,7 @@ public class Delegator {
}catch(Exception e){
logger.error("Failed to serve the request", e);
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e.getMessage());
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e);
}
}
@ -179,7 +179,7 @@ public class Delegator {
}catch(Exception e){
logger.error("Failed to serve the request", e);
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e.getMessage());
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e);
}
}
@ -268,7 +268,7 @@ public class Delegator {
}catch(Exception e){
logger.error("Failed to serve the request", e);
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e.getMessage());
return CatalogueUtils.createJSONOnFailure("Failed to serve the request: " + e);
}
}
}

View File

@ -64,7 +64,7 @@ public class GcoreEndpointReaderSNL {
}
/**
* @return the RESOURCEEntyName
* @return the base path of the service
*/
public String getServiceBasePath() {
return serviceBasePath;

View File

@ -8,8 +8,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang.math.NumberUtils;
import org.gcube.common.authorization.library.utils.Caller;
@ -17,7 +17,7 @@ import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.datacatalogue.catalogue.beans.resource.CustomField;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.DataType;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataFormat;
@ -469,11 +469,11 @@ public class Validator {
}
for (String title : groupNames) {
logger.debug("Adding group to which add this item " + UtilMethods.fromGroupTitleToName(title));
logger.debug("Adding group to which add this item " + CatalogueUtilMethods.fromGroupTitleToName(title));
JSONObject group = new JSONObject();
group.put("name", UtilMethods.fromGroupTitleToName(title));
group.put("name", CatalogueUtilMethods.fromGroupTitleToName(title));
if(propagateUp){
List<String> parents = CatalogueUtils.getGroupHierarchyNames(UtilMethods.fromGroupTitleToName(title), username, isApplication);
List<String> parents = CatalogueUtils.getGroupHierarchyNames(CatalogueUtilMethods.fromGroupTitleToName(title), username, isApplication);
for (String parent : parents) {
JSONObject groupP = new JSONObject();
groupP.put("name", parent);

View File

@ -191,6 +191,7 @@ public class WritePostCatalogueManagerThread extends Thread {
* @param userFullname
* @param hashtags
*/
@SuppressWarnings("unchecked")
private static void writePost(CloseableHttpClient client, String path, String productName, String productUrl, String userFullname, List<String> hashtags,
boolean enablePostNotification) {

View File

@ -13,6 +13,7 @@ import javax.ws.rs.core.UriInfo;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.catalogue.utils.CatalogueUtils;
import org.gcube.datacatalogue.catalogue.utils.Constants;
import org.gcube.datacatalogue.catalogue.utils.Delegator;
@ -32,19 +33,21 @@ public class Group {
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.group_show
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
return Delegator.delegateGet(caller, context, Constants.GROUP_SHOW, uriInfo, false);
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.GROUP_SHOW, uriInfo, isApplication);
}
@GET
@Path(Constants.LIST_METHOD)
@Produces(MediaType.APPLICATION_JSON)
public String organizationList(@Context UriInfo uriInfo){
public String list(@Context UriInfo uriInfo){
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.group_list
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
return Delegator.delegateGet(caller, context, Constants.GROUP_LIST, uriInfo, false);
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.GROUP_LIST, uriInfo, isApplication);
}

View File

@ -10,19 +10,20 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.datacatalogue.catalogue.utils.CatalogueUtils;
import org.gcube.datacatalogue.catalogue.utils.Constants;
import org.gcube.datacatalogue.catalogue.utils.Delegator;
import org.gcube.datacatalogue.catalogue.utils.PackageCreatePostActions;
import org.gcube.datacatalogue.catalogue.utils.Validator;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@ -50,7 +51,35 @@ public class Item {
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.ITEM_SHOW, uriInfo, isApplication);
String username = caller.getClient().getId();
if(!isApplication)
return Delegator.delegateGet(caller, context, Constants.ITEM_SHOW, uriInfo, false);
else{
try{
DataCatalogue utils = CatalogueUtils.getCatalogue();
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(context);
String datasetId = null;
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(false);
List<String> ids = queryParams.get("id");
if(ids == null || ids.isEmpty())
throw new Exception("'id' field is missing!");
datasetId = ids.get(0);
CkanDataset item = utils.getDataset(datasetId, CatalogueUtils.fetchSysAPI(context));
if(organization.equalsIgnoreCase(item.getOrganization().getName()) && username.equals(item.getAuthor())){
return Delegator.delegateGet(caller, context, Constants.ITEM_SHOW, uriInfo, true);
}else
throw new Exception("You are not authorized to access this item");
}catch(Exception e){
return CatalogueUtils.createJSONOnFailure(e.toString());
}
}
}
@ -146,8 +175,7 @@ public class Item {
DataCatalogue utils = CatalogueUtils.getCatalogue();
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(context);
String datasetId = null;
JSONParser parser = new JSONParser();
@ -185,18 +213,13 @@ public class Item {
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
// we need to extend this method wrt ckan: admins can purge the organization data, while editors just their own
DataCatalogue utils = CatalogueUtils.getCatalogue();
// we need also to check if the request comes from an application token
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(isApplication){
try {
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(context);
String datasetId = null;
JSONParser parser = new JSONParser();
@ -311,5 +334,4 @@ public class Item {
// return CatalogueUtils.delegatePost(caller, context, Constants.ITEM_PATCH, json);
//
// }
}

View File

@ -30,8 +30,8 @@ public class License {
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.license_list
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
boolean applicationToken = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.LICENSES_SHOW, uriInfo, applicationToken);
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.LICENSES_SHOW, uriInfo, isApplication);
}

View File

@ -1,5 +1,7 @@
package org.gcube.datacatalogue.catalogue.ws;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@ -8,6 +10,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
@ -16,6 +19,10 @@ import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.catalogue.utils.CatalogueUtils;
import org.gcube.datacatalogue.catalogue.utils.Constants;
import org.gcube.datacatalogue.catalogue.utils.Delegator;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
@Path(Constants.ORGANIZATIONS)
@ -33,8 +40,37 @@ public class Organization {
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.organization_show
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
boolean applicationToken = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.ORGANIZATION_SHOW, uriInfo, applicationToken);
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(!isApplication)
return Delegator.delegateGet(caller, context, Constants.ORGANIZATION_SHOW, uriInfo, false);
else{
try{
DataCatalogue utils = CatalogueUtils.getCatalogue();
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(context);
String organizationId = null;
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(false);
List<String> ids = queryParams.get("id");
if(ids == null || ids.isEmpty())
throw new Exception("'id' field is missing!");
organizationId = ids.get(0);
CkanOrganization fetchedOrganization = utils.getOrganizationByName(organizationId);
if(organization.equalsIgnoreCase(fetchedOrganization.getName())){
return Delegator.delegateGet(caller, context, Constants.ORGANIZATION_SHOW, uriInfo, true);
}else
throw new Exception("You are not authorized to access this organization");
}catch(Exception e){
return CatalogueUtils.createJSONOnFailure(e.toString());
}
}
}
@ -46,8 +82,8 @@ public class Organization {
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.organization_list
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
boolean applicationToken = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.ORGANIZATION_LIST, uriInfo, applicationToken);
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
return Delegator.delegateGet(caller, context, Constants.ORGANIZATION_LIST, uriInfo, isApplication);
}

View File

@ -1,6 +1,8 @@
package org.gcube.datacatalogue.catalogue.ws;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@ -10,6 +12,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
@ -20,6 +23,7 @@ import org.gcube.datacatalogue.catalogue.utils.CatalogueUtils;
import org.gcube.datacatalogue.catalogue.utils.Constants;
import org.gcube.datacatalogue.catalogue.utils.Delegator;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
@ -46,7 +50,34 @@ public class Resource {
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.resource_show
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
return Delegator.delegateGet(caller, context, Constants.RESOURCE_SHOW, uriInfo, false);
String username = caller.getClient().getId();
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(isApplication){
try{
DataCatalogue utils = CatalogueUtils.getCatalogue();
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(context);
String resourceId = null;
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(false);
List<String> ids = queryParams.get("id");
if(ids == null || ids.isEmpty())
throw new Exception("'id' field is missing!");
CkanResource resource = utils.getResource(resourceId, CatalogueUtils.fetchSysAPI(context));
CkanDataset item = utils.getDataset(resource.getPackageId(), CatalogueUtils.fetchSysAPI(context));
if(organization.equalsIgnoreCase(item.getOrganization().getName()) && username.equals(item.getAuthor())){
return Delegator.delegateGet(caller, context, Constants.RESOURCE_SHOW, uriInfo, true);
}else
throw new Exception("You are not authorized to access this resource");
} catch (Exception e) {
return CatalogueUtils.createJSONOnFailure(e.toString());
}
}
return Delegator.delegateGet(caller, context, Constants.RESOURCE_SHOW, uriInfo, isApplication);
}
@ -69,8 +100,7 @@ public class Resource {
DataCatalogue utils = CatalogueUtils.getCatalogue();
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
String organization = CatalogueUtilMethods.getOrganizationNameFromScope(ScopeProvider.instance.get());
String datasetId = null;
JSONParser parser = new JSONParser();
@ -107,16 +137,6 @@ public class Resource {
@Context final HttpServletRequest request
){
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.create.resource_create
// see also multipart https://www.mkyong.com/webservices/jax-rs/file-upload-example-in-jersey/
/*List<BodyPart> bodyParts = multiPart.getBodyParts();
for (BodyPart bodyPart : bodyParts) {
logger.info("Body name is " + bodyPart.getContentDisposition().getFileName());
}
Map<String, List<FormDataBodyPart>> fields = multiPart.getFields();
logger.info(fields);*/
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
@ -166,7 +186,7 @@ public class Resource {
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(!isApplication)
return Delegator.delegatePost(caller, context, Constants.RESOURCE_DELETE, json, uriInfo, false);
else{
@ -176,10 +196,10 @@ public class Resource {
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject)parser.parse(json);
String resourceId = (String)obj.get("id"); // within the resource it is defined this way
if(resourceId == null || resourceId.isEmpty())
throw new Exception("'id' field is missing!");
@ -214,7 +234,7 @@ public class Resource {
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(!isApplication)
return Delegator.delegatePost(caller, context, Constants.RESOURCE_UPDATE, json, uriInfo, false);
else{
@ -224,10 +244,10 @@ public class Resource {
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject)parser.parse(json);
String resourceId = (String)obj.get("id"); // within the resource it is defined this way
if(resourceId == null || resourceId.isEmpty())
throw new Exception("'id' field is missing!");
@ -262,7 +282,7 @@ public class Resource {
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
boolean isApplication = CatalogueUtils.isApplicationToken(caller);
if(!isApplication)
return Delegator.delegatePost(caller, context, Constants.RESOURCE_PATCH, json, uriInfo, false);
else{
@ -272,10 +292,10 @@ public class Resource {
// in this case we check the author has been filled with the same qualifier of this token: the same qualifier can be used in two different contexts
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
String organization = bean.name().toLowerCase().replace(" ", "_").replace("-", "_");
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject)parser.parse(json);
String resourceId = (String)obj.get("id"); // within the resource it is defined this way
if(resourceId == null || resourceId.isEmpty())
throw new Exception("'id' field is missing!");
@ -296,7 +316,7 @@ public class Resource {
return CatalogueUtils.createJSONOnFailure(e.toString());
}
}
}