Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Handling creation of duplicate role for a dataset object #10474

Merged
merged 13 commits into from
Jun 10, 2024
1 change: 1 addition & 0 deletions doc/release-notes/9729-release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An error is now correctly reported when an attempt is made to assign an identical role to the same collection, dataset, or file. #9729 #10465
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.authorization.DataverseRole;
Expand All @@ -18,6 +17,8 @@
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.IllegalCommandException;
import edu.harvard.iq.dataverse.util.BundleUtil;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -68,11 +69,22 @@ public RoleAssignment execute(CommandContext ctxt) throws CommandException {
throw new IllegalCommandException("User " + user.getUserIdentifier() + " is deactivated and cannot be given a role.", this);
}
}
if(isExistingRole(ctxt)){
throw new IllegalCommandException(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);
return ctxt.roles().save(roleAssignment);
}

private boolean isExistingRole(CommandContext ctxt) {
return ctxt.roles()
.directRoleAssignments(grantee, defPoint)
.stream()
.map(RoleAssignment::getRole)
.anyMatch(it -> it.equals(role));
}

@Override
public Map<String, Set<Permission>> getRequiredPermissions() {
// for data file check permission on owning dataset
Expand Down
1 change: 1 addition & 0 deletions src/main/java/propertyFiles/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2671,6 +2671,7 @@ datasets.api.datasize.ioerror=Fatal IO error while trying to determine the total
datasets.api.grant.role.not.found.error=Cannot find role named ''{0}'' in dataverse {1}
datasets.api.grant.role.cant.create.assignment.error=Cannot create assignment: {0}
datasets.api.grant.role.assignee.not.found.error=Assignee not found
datasets.api.grant.role.assignee.has.role.error=User already has this role for this dataset
datasets.api.revoke.role.not.found.error="Role assignment {0} not found"
datasets.api.revoke.role.success=Role {0} revoked for assignee {1} in {2}
datasets.api.privateurl.error.datasetnotfound=Could not find dataset.
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,9 @@ public void testAddRoles(){
giveRandoPermission.prettyPrint();
assertEquals(200, giveRandoPermission.getStatusCode());

//Asserting same role creation is covered
validateAssignExistingRole(datasetPersistentId,randomUsername,apiToken, "fileDownloader");

// Create another random user to become curator:

Response createCuratorUser = UtilIT.createRandomUser();
Expand Down Expand Up @@ -1853,6 +1856,14 @@ public void testListRoleAssignments() {
assertEquals(UNAUTHORIZED.getStatusCode(), notPermittedToListRoleAssignmentOnDataverse.getStatusCode());
}

private static void validateAssignExistingRole(String datasetPersistentId, String randomUsername, String apiToken, String role) {
final Response failedGrantPermission = UtilIT.grantRoleOnDataset(datasetPersistentId, role, "@" + randomUsername, apiToken);
failedGrantPermission.prettyPrint();
failedGrantPermission.then().assertThat()
.body("message", containsString("User already has this role for this dataset"))
.statusCode(FORBIDDEN.getStatusCode());
}

@Test
public void testFileChecksum() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DataverseRoleServiceBean;
import edu.harvard.iq.dataverse.DvObject;
import edu.harvard.iq.dataverse.RoleAssignment;
import edu.harvard.iq.dataverse.authorization.DataverseRole;
import edu.harvard.iq.dataverse.authorization.RoleAssignee;
import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser;
import edu.harvard.iq.dataverse.engine.TestCommandContext;
import edu.harvard.iq.dataverse.engine.TestDataverseEngine;
Expand All @@ -18,8 +20,8 @@
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class CreatePrivateUrlCommandTest {
Expand Down Expand Up @@ -73,6 +75,10 @@ public RoleAssignment save(RoleAssignment assignment) {
// no-op
return assignment;
}
@Override
public List<RoleAssignment> directRoleAssignments(RoleAssignee roas, DvObject dvo) {
return List.of();
}

};
}
Expand Down
Loading