Skip to content

Commit

Permalink
Private URL: avoid commands so Contributor can delete draft #3200 #3201
Browse files Browse the repository at this point in the history
  • Loading branch information
pdurbin committed Jul 8, 2016
1 parent 4015d35 commit 24df280
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.FileMetadata;
import edu.harvard.iq.dataverse.RoleAssignment;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser;

import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
Expand All @@ -13,6 +15,7 @@
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import edu.harvard.iq.dataverse.privateurl.PrivateUrl;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

/**
Expand Down Expand Up @@ -68,10 +71,25 @@ protected void executeImpl(CommandContext ctxt) throws CommandException {
dvIt.remove();
}
}
PrivateUrl privateUrl = ctxt.engine().submit(new GetPrivateUrlCommand(getRequest(), doomed));
/**
* DeleteDatasetDraft, which is required by this command,
* DeleteDatasetVersionCommand is not sufficient for running
* GetPrivateUrlCommand nor DeletePrivateUrlCommand, both of
* which require ManageDatasetPermissions because
* DeletePrivateUrlCommand calls RevokeRoleCommand which
* requires ManageDatasetPermissions when executed on a dataset
* so we make direct calls to the service bean so that a lowly
* Contributor who does NOT have ManageDatasetPermissions can
* still successfully delete a Private URL.
*/
PrivateUrl privateUrl = ctxt.privateUrl().getPrivateUrlFromDatasetId(doomed.getId());
if (privateUrl != null) {
logger.fine("Deleting Private URL for dataset id " + doomed.getId());
ctxt.engine().submit(new DeletePrivateUrlCommand(getRequest(), doomed));
PrivateUrlUser privateUrlUser = new PrivateUrlUser(doomed.getId());
List<RoleAssignment> roleAssignments = ctxt.roles().directRoleAssignments(privateUrlUser, doomed);
for (RoleAssignment roleAssignment : roleAssignments) {
ctxt.roles().revoke(roleAssignment);
}
}
boolean doNormalSolrDocCleanUp = true;
ctxt.index().indexDataset(doomed, doNormalSolrDocCleanUp);
Expand Down
45 changes: 3 additions & 42 deletions src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,48 +336,9 @@ public void testPrivateUrl() {
// A Contributor has DeleteDatasetDraft
Response deleteDraftVersionAsContributor = UtilIT.deleteDatasetVersionViaNativeApi(datasetId, ":draft", contributorApiToken);
deleteDraftVersionAsContributor.prettyPrint();
boolean bugs3200and3201haveBeenFixed = false;
if (bugs3200and3201haveBeenFixed) {
deleteDraftVersionAsContributor.then().assertThat()
.statusCode(OK.getStatusCode());
} else {
/**
* The problem here is that the deletion of the dataset version by
* the contributor only half worked! The version is gone but the
* Private URL was not deleted and reindexing didn't happen. The
* DeleteDatasetVersionCommand exited early. If you allow more
* information to be reported, you will see "status:ERROR" and this
* message:
*
* "User @userbaed3c79 is not permitted to perform requested action.
* Can't execute command
* edu.harvard.iq.dataverse.engine.command.impl.GetPrivateUrlCommand@70d1d3e4,
* because request [DataverseRequest
* user:edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser@69@127.0.0.1]
* is missing permissions [ManageDatasetPermissions] on Object
* Darwin's Finches. granted: [ViewUnpublishedDataset, DownloadFile,
* EditDataset, DeleteDatasetDraft]"
*
* This is fairly awful because you are left with the impression
* that the deletion of the dataset version did not happen
* (UNAUTHORIZED) but it really did! Yikes!
*
* To get the dataset out of its invalid state (indexing cruft left
* behind and a Private URL on a published version), we create a new
* draft.
*/
deleteDraftVersionAsContributor.then().assertThat()
.statusCode(UNAUTHORIZED.getStatusCode())
.body("message", equalTo("User @" + contributorUsername + " is not permitted to perform requested action."));
String workaroundTitle = "I am creating a new draft as a workaround while bugs 3200 and 3100 exist. This way the creator can delete it cleanly.";
Response workAroundSoWeCanDeleteDraft = UtilIT.updateDatasetTitleViaSword(dataset1PersistentId, workaroundTitle, apiToken);
workAroundSoWeCanDeleteDraft.prettyPrint();
assertEquals(OK.getStatusCode(), workAroundSoWeCanDeleteDraft.getStatusCode());
Response deleteDraftVersionAsCreator = UtilIT.deleteDatasetVersionViaNativeApi(datasetId, ":draft", apiToken);
deleteDraftVersionAsCreator.prettyPrint();
deleteDraftVersionAsCreator.then().assertThat()
.statusCode(OK.getStatusCode());
}
deleteDraftVersionAsContributor.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.message", equalTo("Draft version of dataset " + datasetId + " deleted"));

Response privateUrlRoleAssignmentShouldBeGoneAfterDraftDeleted = UtilIT.getRoleAssignmentsOnDataset(datasetId.toString(), null, apiToken);
privateUrlRoleAssignmentShouldBeGoneAfterDraftDeleted.prettyPrint();
Expand Down

0 comments on commit 24df280

Please sign in to comment.