Skip to content

Commit

Permalink
IQSS#11083: prevent NPE in MyData when all dataverses are harvested …
Browse files Browse the repository at this point in the history
…dataverses
  • Loading branch information
plecor committed Dec 11, 2024
1 parent 6e3a250 commit b203662
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug with My Data where listing dataverses for a user with only rights on harvested dataverses would result in a server error response.
28 changes: 15 additions & 13 deletions src/main/java/edu/harvard/iq/dataverse/mydata/MyDataFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -439,19 +439,6 @@ private boolean runStep1RoleAssignments() {
if (results == null) {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.null"));
return false;
} else if (results.isEmpty()) {
List<String> roleNames = this.rolePermissionHelper.getRoleNamesByIdList(this.filterParams.getRoleIds());
if ((roleNames == null) || (roleNames.isEmpty())) {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.no.role"));
} else {
final List<String> args = Arrays.asList(StringUtils.join(roleNames, ", "));
if (roleNames.size() == 1) {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.role.empty", args));
} else {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.roles.empty", args));
}
}
return false;
}

// Iterate through assigned objects, a single object may end up in
Expand Down Expand Up @@ -485,6 +472,21 @@ private boolean runStep1RoleAssignments() {
}
directDvObjectIds.add(dvId);
}

if (directDvObjectIds.isEmpty()) {
List<String> roleNames = this.rolePermissionHelper.getRoleNamesByIdList(this.filterParams.getRoleIds());
if ((roleNames == null) || (roleNames.isEmpty())) {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.no.role"));
} else {
final List<String> args = Arrays.asList(StringUtils.join(roleNames, ", "));
if (roleNames.size() == 1) {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.role.empty", args));
} else {
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.roles.empty", args));
}
}
return false;
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import io.restassured.RestAssured;
import io.restassured.response.Response;
import edu.harvard.iq.dataverse.api.auth.ApiKeyAuthMechanism;
import edu.harvard.iq.dataverse.authorization.DataverseRole;
import edu.harvard.iq.dataverse.util.BundleUtil;

import io.restassured.path.json.JsonPath;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -44,12 +46,62 @@ public void testRetrieveMyDataAsJsonString() {
assertEquals(prettyPrintError("dataretrieverAPI.user.not.found", Arrays.asList(badUserIdentifier)), invalidUserIdentifierResponse.prettyPrint());
assertEquals(OK.getStatusCode(), invalidUserIdentifierResponse.getStatusCode());

// Call as superuser with valid user identifier
// Call as superuser with valid user identifier and no roles
Response createSecondUserResponse = UtilIT.createRandomUser();
String userIdentifier = UtilIT.getUsernameFromResponse(createSecondUserResponse);
Response validUserIdentifierResponse = UtilIT.retrieveMyDataAsJsonString(superUserApiToken, userIdentifier, emptyRoleIdsList);
assertEquals(prettyPrintError("myDataFinder.error.result.no.role", null), validUserIdentifierResponse.prettyPrint());
assertEquals(OK.getStatusCode(), validUserIdentifierResponse.getStatusCode());

// Call as normal user with one valid role and no results
Response createNormalUserResponse = UtilIT.createRandomUser();
String normalUserUsername = UtilIT.getUsernameFromResponse(createNormalUserResponse);
String normalUserApiToken = UtilIT.getApiTokenFromResponse(createNormalUserResponse);
Response noResultwithOneRoleResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L)));
assertEquals(prettyPrintError("myDataFinder.error.result.role.empty", Arrays.asList("Dataset Creator")), noResultwithOneRoleResponse.prettyPrint());
assertEquals(OK.getStatusCode(), noResultwithOneRoleResponse.getStatusCode());

// Call as normal user with multiple valid roles and no results
Response noResultWithMultipleRoleResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L, 6L)));
assertEquals(prettyPrintError("myDataFinder.error.result.roles.empty", Arrays.asList("Dataset Creator, Contributor")), noResultWithMultipleRoleResponse.prettyPrint());
assertEquals(OK.getStatusCode(), noResultWithMultipleRoleResponse.getStatusCode());

// Call as normal user with one valid dataset role and one dataset result
Response createDataverseResponse = UtilIT.createRandomDataverse(normalUserApiToken);
createDataverseResponse.prettyPrint();
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);

Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, normalUserApiToken);
createDatasetResponse.prettyPrint();
Integer datasetId = UtilIT.getDatasetIdFromResponse(createDatasetResponse);
UtilIT.sleepForReindex(datasetId.toString(), normalUserApiToken, 4);
Response oneDatasetResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(6L)));
assertEquals(OK.getStatusCode(), oneDatasetResponse.getStatusCode());
JsonPath jsonPathOneDataset = oneDatasetResponse.getBody().jsonPath();
assertEquals(1, jsonPathOneDataset.getInt("data.total_count"));
assertEquals(datasetId, jsonPathOneDataset.getInt("data.items[0].entity_id"));

// Call as normal user with one valid dataverse role and one dataverse result
UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.DS_CONTRIBUTOR.toString(),
"@" + normalUserUsername, superUserApiToken);
Response oneDataverseResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L)));
assertEquals(OK.getStatusCode(), oneDataverseResponse.getStatusCode());
JsonPath jsonPathOneDataverse = oneDataverseResponse.getBody().jsonPath();
assertEquals(1, jsonPathOneDataverse.getInt("data.total_count"));
assertEquals(dataverseAlias, jsonPathOneDataverse.getString("data.items[0].name"));

// Clean up
Response deleteDatasetResponse = UtilIT.deleteDatasetViaNativeApi(datasetId, normalUserApiToken);
deleteDatasetResponse.prettyPrint();
assertEquals(200, deleteDatasetResponse.getStatusCode());

Response deleteDataverseResponse = UtilIT.deleteDataverse(dataverseAlias, normalUserApiToken);
deleteDataverseResponse.prettyPrint();
assertEquals(200, deleteDataverseResponse.getStatusCode());

Response deleteUserResponse = UtilIT.deleteUser(normalUserUsername);
deleteUserResponse.prettyPrint();
assertEquals(200, deleteUserResponse.getStatusCode());
}

private static String prettyPrintError(String resourceBundleKey, List<String> params) {
Expand Down

0 comments on commit b203662

Please sign in to comment.