Implementing moderation

This commit is contained in:
Luca Frosini 2021-11-16 18:57:05 +01:00
parent 2324531ab9
commit 8a1a7738bc
1 changed files with 208 additions and 121 deletions

View File

@ -120,6 +120,8 @@ public class CKANPackage extends CKAN {
protected final CKANInstance ckanInstance;
protected final Set<String> supportedOrganizations;
protected String moderationMessage;
public CKANPackage() {
super();
@ -615,7 +617,7 @@ public class CKANPackage extends CKAN {
}
}
protected CMItemStatus getCMItemStatus() {
protected CMItemStatus getCMItemStatus() throws Exception {
String cmItemStatusString = CMItemStatus.APPROVED.getValue();
boolean found = false;
@ -633,9 +635,12 @@ public class CKANPackage extends CKAN {
CMItemStatus cmItemStatus = CMItemStatus.getCMItemStatusFromValue(cmItemStatusString);
if(!found) {
// TODO can be used to fix an item published before activating the moderation.
// The item is considered ad approved and the item representation must be updated
return cmItemStatus;
// 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;
@ -703,40 +708,6 @@ public class CKANPackage extends CKAN {
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, false);
}
protected void setToApproved(JsonNode jsonNode) {
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
boolean approvedSet = false;
CMItemVisibility cmItemVisibility = null;
for(JsonNode extra : extras) {
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) {
((ObjectNode) extra).put(EXTRAS_VALUE_KEY, CMItemStatus.APPROVED.getValue());
approvedSet = true;
}
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_VISIBILITY) == 0) {
cmItemVisibility = CMItemVisibility.getCMItemStatusFromValue(extra.get(EXTRAS_VALUE_KEY).asText());
}
}
if(!approvedSet) {
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.APPROVED.getValue());
}
if(cmItemVisibility==null) {
cmItemVisibility = CMItemVisibility.PUBLIC;
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue());
}
((ObjectNode) jsonNode).put(PRIVATE_KEY, cmItemVisibility == CMItemVisibility.RESTRICTED ? true :false);
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true);
}
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
@Override
public String create(String json) {
@ -777,9 +748,6 @@ public class CKANPackage extends CKAN {
ArrayNode created = createResources(resourcesToBeCreated);
((ObjectNode) result).replace(RESOURCES_KEY, created);
// Adding Item URL via Resolver as
// ((ObjectNode) result).put(ITEM_URL_KEY, catalogueItemURL);
// Actions performed after a package has been correctly created on ckan.
String title = result.get(TITLE_KEY).asText();
@ -799,53 +767,6 @@ public class CKANPackage extends CKAN {
}
}
protected JsonNode checkModerationUpdate(JsonNode jsonNode){
PortalUser portalUser = ckanUser.getPortalUser();
if(isModerationEnabled()) {
CMItemStatus cmItemStatus = getCMItemStatus();
boolean setToPending = true;
switch (cmItemStatus) {
case APPROVED:
if(ckanUser.getRole() != Role.ADMIN) {
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s are entitled to update an " + cmItemStatus.getValue() + " item");
}
setToPending = false;
break;
case PENDING:
if(result.get(AUTHOR_EMAIL_KEY).asText().compareTo(portalUser.getEMail())==0) {
break;
}
if(portalUser.isCatalogueModerator()) {
break;
}
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
case REJECTED:
if(result.get(AUTHOR_EMAIL_KEY).asText().compareTo(portalUser.getEMail())==0) {
break;
}
if(ckanUser.getRole() == Role.ADMIN || portalUser.isCatalogueModerator()) {
break;
}
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
default:
break;
}
if(setToPending) {
setToPending(jsonNode);
}
}
return jsonNode;
}
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.update.package_update
@Override
public String update(String json) {
@ -903,12 +824,6 @@ public class CKANPackage extends CKAN {
ckanResource.deleteFile();
}
/*
// Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver();
String catalogueItemURL = uriResolver.getCatalogueItemURL(name);
((ObjectNode) result).put(ITEM_URL_KEY, catalogueItemURL);
*/
result = cleanResult(result);
return getAsString(result);
@ -921,26 +836,6 @@ public class CKANPackage extends CKAN {
}
}
public String approve() {
try {
read();
if(isModerationEnabled()) {
setToApproved(result);
} else {
throw new MethodNotSupportedException("The approve operation is available only in moderation mode");
}
result = cleanResult(result);
return getAsString(result);
}catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.patch.package_patch
@Override
public String patch(String json) {
@ -1000,13 +895,6 @@ public class CKANPackage extends CKAN {
ckanResource.deleteFile();
}
/*
// Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver();
String catalogueItemURL = uriResolver.getCatalogueItemURL(name);
((ObjectNode) result).put(ITEM_URL_KEY, catalogueItemURL);
*/
result = cleanResult(result);
return getAsString(result);
@ -1053,4 +941,203 @@ public class CKANPackage extends CKAN {
super.purge();
}
/**
* Used for bulk purging. Internal use only
*/
protected void purgeNoCheckNoDeleteFiles() {
// setApiKey(CKANUtility.getSysAdminAPI());
// super.purge();
}
// Moderation Related functions
protected JsonNode checkModerationUpdate(JsonNode jsonNode) throws Exception{
PortalUser portalUser = ckanUser.getPortalUser();
if(isModerationEnabled()) {
CMItemStatus cmItemStatus = getCMItemStatus();
boolean setToPending = true;
switch (cmItemStatus) {
case APPROVED:
if(ckanUser.getRole() != Role.ADMIN) {
throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s are entitled to update an " + cmItemStatus.getValue() + " item");
}
setToApproved(jsonNode);
setToPending = false;
break;
case PENDING:
if(result.get(AUTHOR_EMAIL_KEY).asText().compareTo(portalUser.getEMail())==0) {
break;
}
if(portalUser.isCatalogueModerator()) {
break;
}
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
case REJECTED:
if(result.get(AUTHOR_EMAIL_KEY).asText().compareTo(portalUser.getEMail())==0) {
break;
}
if(ckanUser.getRole() == Role.ADMIN || portalUser.isCatalogueModerator()) {
break;
}
throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item");
default:
break;
}
if(setToPending) {
setToPending(jsonNode);
}
}
return jsonNode;
}
public void setModerationMessage(String moderationMessage) {
this.moderationMessage = moderationMessage;
}
protected void setToRejected(JsonNode jsonNode) {
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.REJECTED.getValue());
}
protected void setToApproved(JsonNode jsonNode) {
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
boolean approvedSet = false;
CMItemVisibility cmItemVisibility = null;
for(JsonNode extra : extras) {
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) {
((ObjectNode) extra).put(EXTRAS_VALUE_KEY, CMItemStatus.APPROVED.getValue());
approvedSet = true;
}
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_VISIBILITY) == 0) {
cmItemVisibility = CMItemVisibility.getCMItemStatusFromValue(extra.get(EXTRAS_VALUE_KEY).asText());
}
}
if(!approvedSet) {
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.APPROVED.getValue());
}
if(cmItemVisibility==null) {
cmItemVisibility = CMItemVisibility.PUBLIC;
addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue());
}
((ObjectNode) jsonNode).put(PRIVATE_KEY, cmItemVisibility == CMItemVisibility.RESTRICTED ? true :false);
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true);
}
public String approve() {
try {
if(isModerationEnabled()) {
String ret = read();
CMItemStatus cmItemStatus = getCMItemStatus();
switch (cmItemStatus) {
case APPROVED:
// Nothing TO DO
break;
case 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:
if(ckanUser.getRole() != Role.ADMIN) {
throw new MethodNotSupportedException("Only catalogue moderator can approve a pending item.");
}
setToApproved(result);
ret = sendPostRequest(ITEM_PATCH, getAsString(result));
break;
default:
break;
}
result = mapper.readTree(ret);
result = cleanResult(result);
return getAsString(result);
}
throw new MethodNotSupportedException("The approve operation is available only in moderation mode");
}catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
public String reject() {
try {
if(isModerationEnabled()) {
String ret = read();
CMItemStatus cmItemStatus = getCMItemStatus();
switch (cmItemStatus) {
case APPROVED:
throw new MethodNotSupportedException("You can't rejected an approved item. The item must be updated first. The update will set the item in pending, than it can be approved/rejected.");
case REJECTED:
// Nothing TO DO
break;
case PENDING:
if(ckanUser.getRole() != Role.ADMIN) {
throw new MethodNotSupportedException("Only catalogue moderator can reject a pending item.");
}
setToRejected(result);
ret = sendPostRequest(ITEM_PATCH, getAsString(result));
break;
default:
break;
}
result = mapper.readTree(ret);
result = cleanResult(result);
return getAsString(result);
}
throw new MethodNotSupportedException("The reject operation is available only in moderation mode");
}catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
public void message() {
try {
if(isModerationEnabled()) {
// TODO
}
throw new MethodNotSupportedException("The message operation is available only in moderation mode");
}catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
}