diff --git a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java index 2ee5730153e..1c8984f47d3 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java @@ -892,6 +892,8 @@ protected T execCommand( Command cmd ) throws WrappedResponse { throw new WrappedResponse(ex, badRequest(ex.getMessage(), ex.getFieldErrors())); } catch (InvalidCommandArgumentsException ex) { throw new WrappedResponse(ex, error(Status.BAD_REQUEST, ex.getMessage())); + } catch (ConflictException ex) { + throw new WrappedResponse(ex, conflict(ex.getMessage())); } catch (CommandException ex) { Logger.getLogger(AbstractApiBean.class.getName()).log(Level.SEVERE, "Error while executing command " + cmd, ex); throw new WrappedResponse(ex, error(Status.INTERNAL_SERVER_ERROR, ex.getMessage())); diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/exception/ConflictException.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/exception/ConflictException.java new file mode 100644 index 00000000000..6927bae630d --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/exception/ConflictException.java @@ -0,0 +1,14 @@ +package edu.harvard.iq.dataverse.engine.command.exception; + +import edu.harvard.iq.dataverse.engine.command.Command; + +/** + * An exception raised when a command cannot be executed because it clashes with the current state, e.g. when trying to + * create a resource that already exists. + */ +public class ConflictException extends CommandException { + + public ConflictException(String message, Command aCommand) { + super(message, aCommand); + } +} diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AssignRoleCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AssignRoleCommand.java index db3c41f0f03..4b4c42e15d9 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AssignRoleCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AssignRoleCommand.java @@ -16,6 +16,7 @@ import edu.harvard.iq.dataverse.engine.command.CommandContext; import edu.harvard.iq.dataverse.engine.command.DataverseRequest; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; +import edu.harvard.iq.dataverse.engine.command.exception.ConflictException; import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException; import edu.harvard.iq.dataverse.util.BundleUtil; @@ -73,7 +74,7 @@ public RoleAssignment execute(CommandContext ctxt) throws CommandException { } } if(isExistingRole(ctxt)){ - throw new IllegalCommandException(BundleUtil.getStringFromBundle("datasets.api.grant.role.assignee.has.role.error"), this); + throw new ConflictException(BundleUtil.getStringFromBundle("datasets.api.grant.role.assignee.has.role.error"), this); } // TODO make sure the role is defined on the dataverse. RoleAssignment roleAssignment = new RoleAssignment(role, grantee, defPoint, privateUrlToken, anonymizedAccess); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java index dc658c7134b..632ac39eb4e 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java @@ -2867,4 +2867,46 @@ public void testDataverseMetadataLanguage() { singleLang.then().assertThat().body("data", equalTo(List.of(Map.of("locale", "en", "title", "English")))); } + @Test + public void testAssignRoleOnDataverse() { + // Create user + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + String username = UtilIT.getUsernameFromResponse(createUser); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + + // Create collection as that user + Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken); + createDataverseResponse.prettyPrint(); + String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse); + + // Create second user + Response createSecondUserResponse = UtilIT.createRandomUser(); + String secondUsername = UtilIT.getUsernameFromResponse(createSecondUserResponse); + String secondApiToken = UtilIT.getApiTokenFromResponse(createSecondUserResponse); + + // Let the first user assign a role on their collection to the second user + Response grantRoleResponse = UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.DS_CONTRIBUTOR, "@" + secondUsername, apiToken); + grantRoleResponse.prettyPrint(); + grantRoleResponse.then().assertThat().statusCode(OK.getStatusCode()); + + // Let the first user assign the same role to the same user again -> 409 Conflict + Response grantRoleTwiceResponse = UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.DS_CONTRIBUTOR, "@" + secondUsername, apiToken); + grantRoleTwiceResponse.prettyPrint(); + grantRoleTwiceResponse.then().assertThat().statusCode(CONFLICT.getStatusCode()); + + // Clean up + Response deleteDataverse = UtilIT.deleteDataverse(dataverseAlias, apiToken); + deleteDataverse.prettyPrint(); + deleteDataverse.then().assertThat().statusCode(OK.getStatusCode()); + + Response deleteUserResponse = UtilIT.deleteUser(username); + deleteUserResponse.prettyPrint(); + assertEquals(200, deleteUserResponse.getStatusCode()); + + Response deleteSecondUserResponse = UtilIT.deleteUser(secondUsername); + deleteSecondUserResponse.prettyPrint(); + assertEquals(200, deleteSecondUserResponse.getStatusCode()); + } + }