Revisited moderation code
This commit is contained in:
parent
3333d15b87
commit
e769f7ef2b
|
@ -28,6 +28,7 @@ import org.gcube.gcat.api.CMItemStatus;
|
||||||
import org.gcube.gcat.api.CMItemVisibility;
|
import org.gcube.gcat.api.CMItemVisibility;
|
||||||
import org.gcube.gcat.api.GCatConstants;
|
import org.gcube.gcat.api.GCatConstants;
|
||||||
import org.gcube.gcat.api.Role;
|
import org.gcube.gcat.api.Role;
|
||||||
|
import org.gcube.gcat.api.interfaces.Moderated;
|
||||||
import org.gcube.gcat.oldutils.Validator;
|
import org.gcube.gcat.oldutils.Validator;
|
||||||
import org.gcube.gcat.profile.MetadataUtility;
|
import org.gcube.gcat.profile.MetadataUtility;
|
||||||
import org.gcube.gcat.social.PortalUser;
|
import org.gcube.gcat.social.PortalUser;
|
||||||
|
@ -40,7 +41,7 @@ import org.slf4j.LoggerFactory;
|
||||||
/**
|
/**
|
||||||
* @author Luca Frosini (ISTI - CNR)
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
*/
|
*/
|
||||||
public class CKANPackage extends CKAN {
|
public class CKANPackage extends CKAN implements Moderated {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CKANPackage.class);
|
private static final Logger logger = LoggerFactory.getLogger(CKANPackage.class);
|
||||||
/*
|
/*
|
||||||
|
@ -121,7 +122,6 @@ public class CKANPackage extends CKAN {
|
||||||
protected final CKANInstance ckanInstance;
|
protected final CKANInstance ckanInstance;
|
||||||
protected final Set<String> supportedOrganizations;
|
protected final Set<String> supportedOrganizations;
|
||||||
|
|
||||||
protected String moderationMessage;
|
|
||||||
protected ZulipStream zulipStream;
|
protected ZulipStream zulipStream;
|
||||||
|
|
||||||
public CKANPackage() {
|
public CKANPackage() {
|
||||||
|
@ -198,7 +198,6 @@ public class CKANPackage extends CKAN {
|
||||||
return jsonNode;
|
return jsonNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param json The json to check
|
* @param json The json to check
|
||||||
* @param allowPartialInfo used for patch method which provide only partial information (i.e. the info to patch)
|
* @param allowPartialInfo used for patch method which provide only partial information (i.e. the info to patch)
|
||||||
|
@ -302,49 +301,7 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int count() {
|
protected Map<String,String> getListCountParameters(int limit, int offset) {
|
||||||
Map<String,String> parameters = new HashMap<>();
|
|
||||||
if(uriInfo != null) {
|
|
||||||
MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
|
|
||||||
parameters = checkListParameters(queryParameters, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
int limit = 1;
|
|
||||||
parameters.put(ROWS_KEY, String.valueOf(limit));
|
|
||||||
int offset = 0;
|
|
||||||
parameters.put(START_KEY, String.valueOf(offset * limit));
|
|
||||||
|
|
||||||
if(!parameters.containsKey(GCatConstants.Q_KEY)) {
|
|
||||||
String filter = getFilterForOrganizations();
|
|
||||||
parameters.put(GCatConstants.Q_KEY, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendGetRequest(LIST, parameters);
|
|
||||||
|
|
||||||
int count = result.get(GCatConstants.COUNT_KEY).asInt();
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CMItemStatus getRequestedCMItemStatus() {
|
|
||||||
CMItemStatus cmItemStatus = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
|
|
||||||
|
|
||||||
if(queryParameters.containsKey(GCatConstants.CM_ITEM_STATUS_QUERY_PARAMETER)) {
|
|
||||||
String cmItemStatusString = queryParameters.getFirst(GCatConstants.CM_ITEM_STATUS_QUERY_PARAMETER);
|
|
||||||
cmItemStatus = CMItemStatus.getCMItemStatusFromValue(cmItemStatusString);
|
|
||||||
}
|
|
||||||
}catch (Exception e) {
|
|
||||||
cmItemStatus = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmItemStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String list(int limit, int offset) {
|
|
||||||
Map<String,String> parameters = new HashMap<>();
|
Map<String,String> parameters = new HashMap<>();
|
||||||
if(limit <= 0) {
|
if(limit <= 0) {
|
||||||
// According to CKAN documentation
|
// According to CKAN documentation
|
||||||
|
@ -369,62 +326,49 @@ public class CKANPackage extends CKAN {
|
||||||
parameters.put(GCatConstants.Q_KEY, filter);
|
parameters.put(GCatConstants.Q_KEY, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isModerationEnabled()) {
|
parameters = addModerationStatusFilter(parameters);
|
||||||
String q = parameters.get(GCatConstants.Q_KEY);
|
|
||||||
|
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
return parameters;
|
||||||
stringBuffer.append("(");
|
|
||||||
stringBuffer.append(CM_STATUS_QUERY_FILTER_KEY);
|
|
||||||
stringBuffer.append(":");
|
|
||||||
|
|
||||||
CMItemStatus cmItemStatus = getRequestedCMItemStatus();
|
|
||||||
|
|
||||||
if(!ckanUser.getPortalUser().isCatalogueModerator()) {
|
|
||||||
|
|
||||||
switch (ckanUser.getRole()) {
|
|
||||||
case ADMIN:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EDITOR:
|
|
||||||
if(cmItemStatus!=null && cmItemStatus!=CMItemStatus.APPROVED) {
|
|
||||||
q = String.format("%s AND %s:%s", q, AUTHOR_EMAIL_KEY, ckanUser.getPortalUser().getEMail());
|
|
||||||
}else{
|
|
||||||
cmItemStatus = CMItemStatus.APPROVED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MEMBER:
|
|
||||||
if(cmItemStatus!=null && cmItemStatus!=CMItemStatus.APPROVED) {
|
|
||||||
throw new ForbiddenException("You are only authorized to list " + CMItemStatus.APPROVED.getValue() + " items");
|
|
||||||
}
|
|
||||||
cmItemStatus = CMItemStatus.APPROVED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String list(Map<String,String> parameters) {
|
||||||
|
sendGetRequest(LIST, parameters);
|
||||||
|
|
||||||
|
ArrayNode results = (ArrayNode) result.get(RESULTS_KEY);
|
||||||
|
|
||||||
|
ArrayNode arrayNode = mapper.createArrayNode();
|
||||||
|
for(JsonNode node : results) {
|
||||||
|
try {
|
||||||
|
String name = node.get(NAME_KEY).asText();
|
||||||
|
arrayNode.add(name);
|
||||||
|
} catch(Exception e) {
|
||||||
|
try {
|
||||||
|
logger.error("Unable to get the ID of {}. the result will not be included in the result",
|
||||||
|
mapper.writeValueAsString(node));
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cmItemStatus!=null) {
|
return getAsString(arrayNode);
|
||||||
stringBuffer.append(cmItemStatus.getValue());
|
|
||||||
if(cmItemStatus == CMItemStatus.APPROVED) {
|
|
||||||
stringBuffer.append(" OR (*:* -");
|
|
||||||
stringBuffer.append(CM_STATUS_QUERY_FILTER_KEY);
|
|
||||||
stringBuffer.append(":[* TO *])");
|
|
||||||
}
|
|
||||||
stringBuffer.append(")");
|
|
||||||
q = String.format("%s AND %s", q, stringBuffer.toString());
|
|
||||||
parameters.put(GCatConstants.Q_KEY, q);
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters.put(INCLUDE_PRIVATE_KEY, String.valueOf(true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String list(int limit, int offset) {
|
||||||
|
Map<String,String> parameters = getListCountParameters(limit, offset);
|
||||||
return list(parameters);
|
return list(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int count() {
|
||||||
|
Map<String,String> parameters = getListCountParameters(1, 0);
|
||||||
|
|
||||||
|
sendGetRequest(LIST, parameters);
|
||||||
|
|
||||||
|
int count = result.get(GCatConstants.COUNT_KEY).asInt();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
protected Set<String> checkOrganizationFilter(String q) {
|
protected Set<String> checkOrganizationFilter(String q) {
|
||||||
Matcher m = ORGANIZATION_REGEX_PATTERN.matcher(q);
|
Matcher m = ORGANIZATION_REGEX_PATTERN.matcher(q);
|
||||||
|
|
||||||
|
@ -498,30 +442,6 @@ public class CKANPackage extends CKAN {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String list(Map<String,String> parameters) {
|
|
||||||
|
|
||||||
sendGetRequest(LIST, parameters);
|
|
||||||
|
|
||||||
ArrayNode results = (ArrayNode) result.get(RESULTS_KEY);
|
|
||||||
|
|
||||||
ArrayNode arrayNode = mapper.createArrayNode();
|
|
||||||
for(JsonNode node : results) {
|
|
||||||
try {
|
|
||||||
String name = node.get(NAME_KEY).asText();
|
|
||||||
arrayNode.add(name);
|
|
||||||
} catch(Exception e) {
|
|
||||||
try {
|
|
||||||
logger.error("Unable to get the ID of {}. the result will not be included in the result",
|
|
||||||
mapper.writeValueAsString(node));
|
|
||||||
} catch(Exception ex) {
|
|
||||||
logger.error("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getAsString(arrayNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void rollbackManagedResources() {
|
protected void rollbackManagedResources() {
|
||||||
for(CKANResource ckanResource : managedResources) {
|
for(CKANResource ckanResource : managedResources) {
|
||||||
try {
|
try {
|
||||||
|
@ -619,35 +539,6 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CMItemStatus getCMItemStatus() throws Exception {
|
|
||||||
|
|
||||||
String cmItemStatusString = CMItemStatus.APPROVED.getValue();
|
|
||||||
boolean found = false;
|
|
||||||
if(result.has(EXTRAS_KEY)) {
|
|
||||||
ArrayNode extras = (ArrayNode) result.get(EXTRAS_KEY);
|
|
||||||
for(JsonNode extra : extras) {
|
|
||||||
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) {
|
|
||||||
cmItemStatusString = extra.get(EXTRAS_VALUE_KEY).asText();
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CMItemStatus cmItemStatus = CMItemStatus.getCMItemStatusFromValue(cmItemStatusString);
|
|
||||||
|
|
||||||
if(!found) {
|
|
||||||
// The item was published before activating the moderation.
|
|
||||||
// The item is considered as approved and the item representation must be updated
|
|
||||||
setToApproved(result);
|
|
||||||
String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
|
|
||||||
result = mapper.readTree(ret);
|
|
||||||
result = cleanResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmItemStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isItemCreator() {
|
protected boolean isItemCreator() {
|
||||||
return result.get(AUTHOR_EMAIL_KEY).asText().compareTo(ckanUser.getPortalUser().getEMail())==0;
|
return result.get(AUTHOR_EMAIL_KEY).asText().compareTo(ckanUser.getPortalUser().getEMail())==0;
|
||||||
}
|
}
|
||||||
|
@ -660,29 +551,7 @@ public class CKANPackage extends CKAN {
|
||||||
result = mapper.readTree(ret);
|
result = mapper.readTree(ret);
|
||||||
result = cleanResult(result);
|
result = cleanResult(result);
|
||||||
|
|
||||||
if(isModerationEnabled()) {
|
checkModerationRead();
|
||||||
|
|
||||||
CMItemStatus cmItemStatus = getCMItemStatus();
|
|
||||||
|
|
||||||
if(cmItemStatus == CMItemStatus.APPROVED) {
|
|
||||||
return getAsString(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
PortalUser portalUser = ckanUser.getPortalUser();
|
|
||||||
|
|
||||||
if(isItemCreator()) {
|
|
||||||
// The author is entitled to read its own items independently from the status
|
|
||||||
return getAsString(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ckanUser.getRole() == Role.ADMIN || portalUser.isCatalogueModerator()) {
|
|
||||||
// Catalogue-Admin and Catalogue-Moderator are entitled to read items with any statues
|
|
||||||
return getAsString(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ForbiddenException("You are not entitled to read a " + cmItemStatus.getValue() + " item");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return getAsString(result);
|
return getAsString(result);
|
||||||
|
|
||||||
|
@ -694,23 +563,6 @@ public class CKANPackage extends CKAN {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setToPending(JsonNode jsonNode) {
|
|
||||||
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.PENDING.getValue());
|
|
||||||
|
|
||||||
CMItemVisibility cmItemVisibility = CMItemVisibility.PUBLIC;
|
|
||||||
|
|
||||||
if(jsonNode.has(PRIVATE_KEY)) {
|
|
||||||
boolean privatePackage = jsonNode.get(PRIVATE_KEY).asBoolean();
|
|
||||||
if(privatePackage) {
|
|
||||||
cmItemVisibility = CMItemVisibility.RESTRICTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue());
|
|
||||||
|
|
||||||
((ObjectNode) jsonNode).put(PRIVATE_KEY, true);
|
|
||||||
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
|
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
|
||||||
@Override
|
@Override
|
||||||
public String create(String json) {
|
public String create(String json) {
|
||||||
|
@ -730,7 +582,8 @@ public class CKANPackage extends CKAN {
|
||||||
|
|
||||||
JsonNode jsonNode = validateJson(json);
|
JsonNode jsonNode = validateJson(json);
|
||||||
|
|
||||||
if(isModerationEnabled()) {
|
boolean moderationEnabled = isModerationEnabled();
|
||||||
|
if(moderationEnabled) {
|
||||||
setToPending(jsonNode);
|
setToPending(jsonNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,7 +611,7 @@ public class CKANPackage extends CKAN {
|
||||||
sendSocialPost(title, catalogueItemURL);
|
sendSocialPost(title, catalogueItemURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isModerationEnabled()) {
|
if(moderationEnabled) {
|
||||||
createNewStream();
|
createNewStream();
|
||||||
postItemCreatedToStream();
|
postItemCreatedToStream();
|
||||||
}
|
}
|
||||||
|
@ -917,9 +770,7 @@ public class CKANPackage extends CKAN {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void delete() {
|
protected void delete() {
|
||||||
if(isModerationEnabled()) {
|
checkModerationDelete();
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
super.delete();
|
super.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,8 +786,14 @@ public class CKANPackage extends CKAN {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setApiKey(CKANUtility.getSysAdminAPI());
|
setApiKey(CKANUtility.getSysAdminAPI());
|
||||||
read();
|
read();
|
||||||
|
|
||||||
|
if(ckanUser.getRole()!=Role.ADMIN && !isItemCreator()) {
|
||||||
|
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to purge an the item");
|
||||||
|
}
|
||||||
|
|
||||||
if(result.has(RESOURCES_KEY)) {
|
if(result.has(RESOURCES_KEY)) {
|
||||||
itemID = result.get(ID_KEY).asText();
|
itemID = result.get(ID_KEY).asText();
|
||||||
ArrayNode arrayNode = (ArrayNode) result.get(RESOURCES_KEY);
|
ArrayNode arrayNode = (ArrayNode) result.get(RESOURCES_KEY);
|
||||||
|
@ -958,12 +815,59 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------------------
|
* --------------------------------------------------------------------------------------------------------
|
||||||
* Moderation Related functions
|
* Moderation Related functions
|
||||||
* ----------------------------------------------------------------------------------------
|
* --------------------------------------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
protected CMItemStatus getCMItemStatus() {
|
||||||
|
|
||||||
|
String cmItemStatusString = CMItemStatus.APPROVED.getValue();
|
||||||
|
boolean found = false;
|
||||||
|
if(result.has(EXTRAS_KEY)) {
|
||||||
|
ArrayNode extras = (ArrayNode) result.get(EXTRAS_KEY);
|
||||||
|
for(JsonNode extra : extras) {
|
||||||
|
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) {
|
||||||
|
cmItemStatusString = extra.get(EXTRAS_VALUE_KEY).asText();
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMItemStatus cmItemStatus = CMItemStatus.getCMItemStatusFromValue(cmItemStatusString);
|
||||||
|
|
||||||
|
if(!found) {
|
||||||
|
// The item was published before activating the moderation.
|
||||||
|
// The item is considered as approved and the item representation must be updated
|
||||||
|
setToApproved(result);
|
||||||
|
String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
|
||||||
|
try {
|
||||||
|
result = mapper.readTree(ret);
|
||||||
|
}catch (Exception e) {
|
||||||
|
new InternalServerErrorException(e);
|
||||||
|
}
|
||||||
|
result = cleanResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmItemStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CMItemStatus getRequestedCMItemStatus() {
|
||||||
|
CMItemStatus cmItemStatus = null;
|
||||||
|
try {
|
||||||
|
MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
|
||||||
|
if(queryParameters.containsKey(GCatConstants.CM_ITEM_STATUS_QUERY_PARAMETER)) {
|
||||||
|
String cmItemStatusString = queryParameters.getFirst(GCatConstants.CM_ITEM_STATUS_QUERY_PARAMETER);
|
||||||
|
cmItemStatus = CMItemStatus.getCMItemStatusFromValue(cmItemStatusString);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
cmItemStatus = null;
|
||||||
|
}
|
||||||
|
return cmItemStatus;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isModerationEnabled() {
|
protected boolean isModerationEnabled() {
|
||||||
boolean moderationEnabled = ckanInstance.isModerationEnabled();
|
boolean moderationEnabled = ckanInstance.isModerationEnabled();
|
||||||
if(moderationEnabled && zulipStream==null) {
|
if(moderationEnabled && zulipStream==null) {
|
||||||
|
@ -972,36 +876,102 @@ public class CKANPackage extends CKAN {
|
||||||
return moderationEnabled;
|
return moderationEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private String getItemName() {
|
protected Map<String,String> addModerationStatusFilter(Map<String,String> parameters){
|
||||||
// String itemName = result.get(name).asText();
|
if(isModerationEnabled()) {
|
||||||
// return itemName;
|
String q = parameters.get(GCatConstants.Q_KEY);
|
||||||
// }
|
|
||||||
|
|
||||||
private void createNewStream() throws Exception {
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
zulipStream.setItemCoordinates(itemID, name);
|
stringBuffer.append("(");
|
||||||
zulipStream.setCKANUser(ckanUser);
|
stringBuffer.append(CM_STATUS_QUERY_FILTER_KEY);
|
||||||
zulipStream.create();
|
stringBuffer.append(":");
|
||||||
|
|
||||||
|
CMItemStatus cmItemStatus = getRequestedCMItemStatus();
|
||||||
|
|
||||||
|
if(!ckanUser.getPortalUser().isCatalogueModerator()) {
|
||||||
|
|
||||||
|
switch (ckanUser.getRole()) {
|
||||||
|
case ADMIN:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EDITOR:
|
||||||
|
if(cmItemStatus!=null && cmItemStatus!=CMItemStatus.APPROVED) {
|
||||||
|
q = String.format("%s AND %s:%s", q, AUTHOR_EMAIL_KEY, ckanUser.getPortalUser().getEMail());
|
||||||
|
}else{
|
||||||
|
cmItemStatus = CMItemStatus.APPROVED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEMBER:
|
||||||
|
if(cmItemStatus!=null && cmItemStatus!=CMItemStatus.APPROVED) {
|
||||||
|
throw new ForbiddenException("You are only authorized to list " + CMItemStatus.APPROVED.getValue() + " items");
|
||||||
|
}
|
||||||
|
cmItemStatus = CMItemStatus.APPROVED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postItemCreatedToStream() {
|
|
||||||
zulipStream.postItemCreatedToStream();
|
}
|
||||||
|
|
||||||
|
if(cmItemStatus!=null) {
|
||||||
|
stringBuffer.append(cmItemStatus.getValue());
|
||||||
|
if(cmItemStatus == CMItemStatus.APPROVED) {
|
||||||
|
stringBuffer.append(" OR (*:* -");
|
||||||
|
stringBuffer.append(CM_STATUS_QUERY_FILTER_KEY);
|
||||||
|
stringBuffer.append(":[* TO *])");
|
||||||
|
}
|
||||||
|
stringBuffer.append(")");
|
||||||
|
q = String.format("%s AND %s", q, stringBuffer.toString());
|
||||||
|
parameters.put(GCatConstants.Q_KEY, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters.put(INCLUDE_PRIVATE_KEY, String.valueOf(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkModerationRead() {
|
||||||
|
if(isModerationEnabled()) {
|
||||||
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
|
if(cmItemStatus == CMItemStatus.APPROVED) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonNode checkModerationUpdate(JsonNode jsonNode) throws Exception{
|
|
||||||
PortalUser portalUser = ckanUser.getPortalUser();
|
PortalUser portalUser = ckanUser.getPortalUser();
|
||||||
|
if(isItemCreator()) {
|
||||||
|
// The author is entitled to read its own items independently from the status
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ckanUser.getRole() == Role.ADMIN || portalUser.isCatalogueModerator()) {
|
||||||
|
// Catalogue-Admin and Catalogue-Moderator are entitled to read items with any statues
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ForbiddenException("You are not entitled to read the item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonNode checkModerationUpdate(JsonNode jsonNode) {
|
||||||
if(isModerationEnabled()) {
|
if(isModerationEnabled()) {
|
||||||
CMItemStatus cmItemStatus = getCMItemStatus();
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
|
|
||||||
boolean setToPending = true;
|
boolean setToPending = true;
|
||||||
|
|
||||||
|
PortalUser portalUser = ckanUser.getPortalUser();
|
||||||
|
|
||||||
switch (cmItemStatus) {
|
switch (cmItemStatus) {
|
||||||
case APPROVED:
|
case APPROVED:
|
||||||
if(ckanUser.getRole() != Role.ADMIN) {
|
if(ckanUser.getRole() != Role.ADMIN && !isItemCreator()) {
|
||||||
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s are entitled to update an " + cmItemStatus.getValue() + " item");
|
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to update an " + cmItemStatus.getValue() + " item");
|
||||||
}
|
}
|
||||||
|
if(ckanUser.getRole() == Role.ADMIN) {
|
||||||
setToApproved(jsonNode);
|
setToApproved(jsonNode);
|
||||||
setToPending = false;
|
setToPending = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PENDING:
|
case PENDING:
|
||||||
|
@ -1017,7 +987,7 @@ public class CKANPackage extends CKAN {
|
||||||
if(isItemCreator()) {
|
if(isItemCreator()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(ckanUser.getRole() == Role.ADMIN || portalUser.isCatalogueModerator()) {
|
if(portalUser.isCatalogueModerator()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
|
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
|
||||||
|
@ -1035,17 +1005,70 @@ public class CKANPackage extends CKAN {
|
||||||
return jsonNode;
|
return jsonNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void checkModerationDelete() {
|
||||||
|
if(isModerationEnabled()) {
|
||||||
|
read();
|
||||||
|
|
||||||
public void setModerationMessage(String moderationMessage) {
|
PortalUser portalUser = ckanUser.getPortalUser();
|
||||||
this.moderationMessage = moderationMessage;
|
|
||||||
|
if(ckanUser.getRole() == Role.ADMIN) {
|
||||||
|
// Ad Admin can delete any item independently from the status
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
|
|
||||||
|
switch (cmItemStatus) {
|
||||||
|
case APPROVED:
|
||||||
|
if(isItemCreator()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to delete an " + cmItemStatus.getValue() + " item");
|
||||||
|
|
||||||
|
case REJECTED:
|
||||||
|
if(isItemCreator()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(portalUser.isCatalogueModerator()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw new ForbiddenException("You are not entitled to delete a " + cmItemStatus.getValue() + " item");
|
||||||
|
|
||||||
|
case PENDING:
|
||||||
|
if(isItemCreator()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(portalUser.isCatalogueModerator()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setToRejected(JsonNode jsonNode) {
|
protected void setToRejected(JsonNode jsonNode) {
|
||||||
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.REJECTED.getValue());
|
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.REJECTED.getValue());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setToPending(JsonNode jsonNode) {
|
||||||
|
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.PENDING.getValue());
|
||||||
|
|
||||||
|
CMItemVisibility cmItemVisibility = CMItemVisibility.PUBLIC;
|
||||||
|
|
||||||
|
if(jsonNode.has(PRIVATE_KEY)) {
|
||||||
|
boolean privatePackage = jsonNode.get(PRIVATE_KEY).asBoolean();
|
||||||
|
if(privatePackage) {
|
||||||
|
cmItemVisibility = CMItemVisibility.RESTRICTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue());
|
||||||
|
|
||||||
|
((ObjectNode) jsonNode).put(PRIVATE_KEY, true);
|
||||||
|
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, false);
|
||||||
|
}
|
||||||
|
|
||||||
protected void setToApproved(JsonNode jsonNode) {
|
protected void setToApproved(JsonNode jsonNode) {
|
||||||
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
|
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
|
||||||
|
@ -1078,11 +1101,22 @@ public class CKANPackage extends CKAN {
|
||||||
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true);
|
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String approve() {
|
private void createNewStream() throws Exception {
|
||||||
|
zulipStream.setItemCoordinates(itemID, name);
|
||||||
|
zulipStream.setCKANUser(ckanUser);
|
||||||
|
zulipStream.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postItemCreatedToStream() {
|
||||||
|
zulipStream.postItemCreatedToStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String approve(String moderatorMessage) {
|
||||||
try {
|
try {
|
||||||
if(isModerationEnabled()) {
|
if(isModerationEnabled()) {
|
||||||
String ret = read();
|
String ret = read();
|
||||||
|
PortalUser portalUser = ckanUser.getPortalUser();
|
||||||
CMItemStatus cmItemStatus = getCMItemStatus();
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
switch (cmItemStatus) {
|
switch (cmItemStatus) {
|
||||||
case APPROVED:
|
case APPROVED:
|
||||||
|
@ -1093,7 +1127,7 @@ public class CKANPackage extends CKAN {
|
||||||
throw new MethodNotSupportedException("You can't approve a rejected item. The item must be updated first. The update will set the item in pending, than it can be approved/rejected.");
|
throw new MethodNotSupportedException("You can't approve a rejected item. The item must be updated first. The update will set the item in pending, than it can be approved/rejected.");
|
||||||
|
|
||||||
case PENDING:
|
case PENDING:
|
||||||
if(ckanUser.getRole() != Role.ADMIN) {
|
if(!portalUser.isCatalogueModerator()) {
|
||||||
throw new MethodNotSupportedException("Only catalogue moderator can approve a pending item.");
|
throw new MethodNotSupportedException("Only catalogue moderator can approve a pending item.");
|
||||||
}
|
}
|
||||||
setToApproved(result);
|
setToApproved(result);
|
||||||
|
@ -1110,15 +1144,13 @@ public class CKANPackage extends CKAN {
|
||||||
ZulipStream zulipStream = new ZulipStream();
|
ZulipStream zulipStream = new ZulipStream();
|
||||||
zulipStream.setItemCoordinates(itemID, name);
|
zulipStream.setItemCoordinates(itemID, name);
|
||||||
zulipStream.postItemCreatedToStream();
|
zulipStream.postItemCreatedToStream();
|
||||||
if(moderationMessage!=null && moderationMessage.compareTo("")!=0) {
|
if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) {
|
||||||
zulipStream.postMessageToStream(CMItemStatus.PENDING, moderationMessage);
|
zulipStream.postMessageToStream(CMItemStatus.PENDING, moderatorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAsString(result);
|
return getAsString(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MethodNotSupportedException("The approve operation is available only in moderation mode");
|
throw new MethodNotSupportedException("The approve operation is available only in moderation mode");
|
||||||
|
|
||||||
}catch(WebApplicationException e) {
|
}catch(WebApplicationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
@ -1126,11 +1158,12 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String reject() {
|
@Override
|
||||||
|
public String reject(String moderatorMessage) {
|
||||||
try {
|
try {
|
||||||
if(isModerationEnabled()) {
|
if(isModerationEnabled()) {
|
||||||
String ret = read();
|
String ret = read();
|
||||||
|
PortalUser portalUser = ckanUser.getPortalUser();
|
||||||
CMItemStatus cmItemStatus = getCMItemStatus();
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
switch (cmItemStatus) {
|
switch (cmItemStatus) {
|
||||||
case APPROVED:
|
case APPROVED:
|
||||||
|
@ -1141,7 +1174,7 @@ public class CKANPackage extends CKAN {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PENDING:
|
case PENDING:
|
||||||
if(ckanUser.getRole() != Role.ADMIN) {
|
if(!portalUser.isCatalogueModerator()) {
|
||||||
throw new MethodNotSupportedException("Only catalogue moderator can reject a pending item.");
|
throw new MethodNotSupportedException("Only catalogue moderator can reject a pending item.");
|
||||||
}
|
}
|
||||||
setToRejected(result);
|
setToRejected(result);
|
||||||
|
@ -1158,15 +1191,13 @@ public class CKANPackage extends CKAN {
|
||||||
ZulipStream zulipStream = new ZulipStream();
|
ZulipStream zulipStream = new ZulipStream();
|
||||||
zulipStream.setItemCoordinates(itemID, name);
|
zulipStream.setItemCoordinates(itemID, name);
|
||||||
zulipStream.postItemRejectedToStream();
|
zulipStream.postItemRejectedToStream();
|
||||||
if(moderationMessage!=null && moderationMessage.compareTo("")!=0) {
|
if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) {
|
||||||
zulipStream.postMessageToStream(CMItemStatus.REJECTED, moderationMessage);
|
zulipStream.postMessageToStream(CMItemStatus.REJECTED, moderatorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAsString(result);
|
return getAsString(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MethodNotSupportedException("The reject operation is available only in moderation mode");
|
throw new MethodNotSupportedException("The reject operation is available only in moderation mode");
|
||||||
|
|
||||||
}catch(WebApplicationException e) {
|
}catch(WebApplicationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
@ -1174,10 +1205,11 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void message() {
|
@Override
|
||||||
|
public void message(String message) {
|
||||||
try {
|
try {
|
||||||
if(isModerationEnabled()) {
|
if(isModerationEnabled()) {
|
||||||
if(moderationMessage==null || moderationMessage.compareTo("")==0) {
|
if(message==null || message.compareTo("")==0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,10 +1225,8 @@ public class CKANPackage extends CKAN {
|
||||||
|
|
||||||
ZulipStream zulipStream = new ZulipStream();
|
ZulipStream zulipStream = new ZulipStream();
|
||||||
zulipStream.setItemCoordinates(itemID, name);
|
zulipStream.setItemCoordinates(itemID, name);
|
||||||
|
|
||||||
CMItemStatus cmItemStatus = getCMItemStatus();
|
CMItemStatus cmItemStatus = getCMItemStatus();
|
||||||
|
zulipStream.postMessageToStream(cmItemStatus, message);
|
||||||
zulipStream.postMessageToStream(cmItemStatus, moderationMessage);
|
|
||||||
}
|
}
|
||||||
throw new MethodNotSupportedException("The message operation is available only in moderation mode");
|
throw new MethodNotSupportedException("The message operation is available only in moderation mode");
|
||||||
}catch(WebApplicationException e) {
|
}catch(WebApplicationException e) {
|
||||||
|
@ -1206,5 +1236,4 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ public class Item extends REST<CKANPackage> implements org.gcube.gcat.api.interf
|
||||||
|
|
||||||
public static final String ITEM_ID_PARAMETER = "ITEM_ID";
|
public static final String ITEM_ID_PARAMETER = "ITEM_ID";
|
||||||
|
|
||||||
|
protected String moderationMessage;
|
||||||
|
|
||||||
public Item() {
|
public Item() {
|
||||||
super(ITEMS, ITEM_ID_PARAMETER, CKANPackage.class);
|
super(ITEMS, ITEM_ID_PARAMETER, CKANPackage.class);
|
||||||
}
|
}
|
||||||
|
@ -127,4 +129,22 @@ public class Item extends REST<CKANPackage> implements org.gcube.gcat.api.interf
|
||||||
return delete(name, new Boolean(purge));
|
return delete(name, new Boolean(purge));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String approve(String moderatorMessage) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String reject(String moderatorMessage) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String message) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue