Skip to content

Commit

Permalink
#4405 make MoveDataset a Superuser only command
Browse files Browse the repository at this point in the history
  • Loading branch information
sekmiller committed Feb 1, 2018
1 parent 0d7b85a commit 74240c8
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 42 deletions.
13 changes: 8 additions & 5 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -439,23 +439,26 @@ public Response publishDataset(@PathParam("id") String id, @QueryParam("type") S
}

@POST
@Path("{id}/{targetDataverseAlias}/move")
public Response moveDataset(@PathParam("id") String id, @PathParam("targetDataverseAlias") String targetDataverseAlias) {
@Path("{id}/move/{targetDataverseAlias}")
public Response moveDataset(@PathParam("id") String id, @PathParam("targetDataverseAlias") String targetDataverseAlias) {
try{
User u = findUserOrDie();
if (!u.isSuperuser()) {
return error(Response.Status.FORBIDDEN, "Not a superuser");
}

Dataset ds = findDatasetOrDie(id);
Dataverse target = dataverseService.findByAlias(targetDataverseAlias);
if (target == null){
return error(Response.Status.BAD_REQUEST, "Target Dataverse not found.");
}

execCommand(new MoveDatasetCommand(
createDataverseRequest(findAuthenticatedUserOrDie()), ds, target
createDataverseRequest(u), ds, target
));
return ok("Dataset moved successfully");
} catch (WrappedResponse ex) {
return ex.getResponse();
}

}
@GET
@Path("{id}/links")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@

import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.MetadataBlock;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissionsMap;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import java.util.List;
import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -25,53 +25,37 @@
*
* @author skraffmi
*/
@RequiredPermissionsMap({
@RequiredPermissions(dataverseName = "moved", value = {Permission.PublishDataset}),
@RequiredPermissions(dataverseName = "source", value = Permission.EditDataset),
@RequiredPermissions(dataverseName = "destination", value = {Permission.AddDataset})
})

// the permission annotation is open, since this is a superuser-only command -
// and that's enforced in the command body:
@RequiredPermissions({})
public class MoveDatasetCommand extends AbstractVoidCommand {

private static final Logger logger = Logger.getLogger(MoveDatasetCommand.class.getCanonicalName());
final Dataset moved;
final Dataverse destination;

public MoveDatasetCommand(DataverseRequest aRequest, Dataset moved, Dataverse destination) {
super(aRequest, dv("moved", moved),
dv("source", moved.getOwner()),
dv("destination", destination));
super(aRequest, moved);
this.moved = moved;
this.destination = destination;
}

@Override
public void executeImpl(CommandContext ctxt) throws CommandException {

// first check if user is a superuser
if ( (!(getUser() instanceof AuthenticatedUser) || !getUser().isSuperuser() ) ) {
throw new PermissionException("Move Dataset can only be called by superusers.",
this, Collections.singleton(Permission.DeleteDatasetDraft), moved);
}


// validate the move makes sense
if (moved.getOwner().equals(destination)) {
throw new IllegalCommandException("Dataset already in this Dataverse ", this);
}

//Test Metadata Blocks
// As long as the target DV has all of the blocks contained in the source it's OK
// target may have more blocks.
List<MetadataBlock> sourceMetadataBlocks = moved.getOwner().getMetadataBlocks();

List<MetadataBlock> targetMetadataBlocks = destination.getMetadataBlocks();
boolean containsAll = true;
for (MetadataBlock mdbSource : sourceMetadataBlocks) {
boolean found = false;
for (MetadataBlock mdbTarget : targetMetadataBlocks) {
if (mdbTarget.equals(mdbSource)) {
found = true;
}
}
containsAll &= found;
}

if (!containsAll) {
throw new IllegalCommandException("Metadata Blocks are incompatible for moving this Dataset ", this);
}

// OK, move
moved.setOwner(destination);
ctxt.em().merge(moved);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.DataverseServiceBean;
import edu.harvard.iq.dataverse.MetadataBlock;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.engine.DataverseEngine;
import edu.harvard.iq.dataverse.engine.TestCommandContext;
import edu.harvard.iq.dataverse.engine.TestDataverseEngine;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import static edu.harvard.iq.dataverse.mocks.MocksFactory.makeAuthenticatedUser;
import edu.harvard.iq.dataverse.search.IndexServiceBean;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -34,6 +37,8 @@
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.metamodel.Metamodel;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
Expand All @@ -49,10 +54,18 @@ public class MoveDatasetCommandTest {
Dataverse root, childA, childB, grandchildAA;
DataverseEngine testEngine;
MetadataBlock blockA, blockB, blockC, blockD;
AuthenticatedUser auth, nobody;
@Context
protected HttpServletRequest httpRequest;

@Before
public void setUp() {

auth = makeAuthenticatedUser("Super", "User");
auth.setSuperuser(true);
nobody = makeAuthenticatedUser("Nick", "Nobody");
nobody.setSuperuser(false);

blockA = new MetadataBlock();
blockA.setName("blockA");
blockA.setId(1l);
Expand Down Expand Up @@ -394,23 +407,23 @@ public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass) {
@Test
public void testValidMove() throws Exception {


testEngine.submit(new MoveDatasetCommand(null, moved, childA));
DataverseRequest aRequest = new DataverseRequest(auth, httpRequest);
testEngine.submit(new MoveDatasetCommand(aRequest, moved, childA));

assertEquals( childA, moved.getOwner() );

}

/**
* Moving DS to DV without congruent metadata blocks.
* Moving DS to its owning DV
* @throws java.lang.Exception
*/
@Test( expected=IllegalCommandException.class )
public void testInvalidMove() throws Exception {


DataverseRequest aRequest = new DataverseRequest(auth, httpRequest);
testEngine.submit(
new MoveDatasetCommand(null, moved, childB));
new MoveDatasetCommand(aRequest, moved, root));
fail();
}

Expand Down

0 comments on commit 74240c8

Please sign in to comment.