Skip to content

Commit b203662

Browse files
committed
IQSS#11083: prevent NPE in MyData when all dataverses are harvested dataverses
1 parent 6e3a250 commit b203662

File tree

3 files changed

+69
-14
lines changed

3 files changed

+69
-14
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

src/main/java/edu/harvard/iq/dataverse/mydata/MyDataFinder.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,19 +439,6 @@ private boolean runStep1RoleAssignments() {
439439
if (results == null) {
440440
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.null"));
441441
return false;
442-
} else if (results.isEmpty()) {
443-
List<String> roleNames = this.rolePermissionHelper.getRoleNamesByIdList(this.filterParams.getRoleIds());
444-
if ((roleNames == null) || (roleNames.isEmpty())) {
445-
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.no.role"));
446-
} else {
447-
final List<String> args = Arrays.asList(StringUtils.join(roleNames, ", "));
448-
if (roleNames.size() == 1) {
449-
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.role.empty", args));
450-
} else {
451-
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.roles.empty", args));
452-
}
453-
}
454-
return false;
455442
}
456443

457444
// Iterate through assigned objects, a single object may end up in
@@ -485,6 +472,21 @@ private boolean runStep1RoleAssignments() {
485472
}
486473
directDvObjectIds.add(dvId);
487474
}
475+
476+
if (directDvObjectIds.isEmpty()) {
477+
List<String> roleNames = this.rolePermissionHelper.getRoleNamesByIdList(this.filterParams.getRoleIds());
478+
if ((roleNames == null) || (roleNames.isEmpty())) {
479+
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.no.role"));
480+
} else {
481+
final List<String> args = Arrays.asList(StringUtils.join(roleNames, ", "));
482+
if (roleNames.size() == 1) {
483+
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.role.empty", args));
484+
} else {
485+
this.addErrorMessage(BundleUtil.getStringFromBundle("myDataFinder.error.result.roles.empty", args));
486+
}
487+
}
488+
return false;
489+
}
488490
return true;
489491
}
490492

src/test/java/edu/harvard/iq/dataverse/api/DataRetrieverApiIT.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import io.restassured.RestAssured;
44
import io.restassured.response.Response;
55
import edu.harvard.iq.dataverse.api.auth.ApiKeyAuthMechanism;
6+
import edu.harvard.iq.dataverse.authorization.DataverseRole;
67
import edu.harvard.iq.dataverse.util.BundleUtil;
78

9+
import io.restassured.path.json.JsonPath;
810
import org.junit.jupiter.api.BeforeAll;
911
import org.junit.jupiter.api.Test;
1012

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

47-
// Call as superuser with valid user identifier
49+
// Call as superuser with valid user identifier and no roles
4850
Response createSecondUserResponse = UtilIT.createRandomUser();
4951
String userIdentifier = UtilIT.getUsernameFromResponse(createSecondUserResponse);
5052
Response validUserIdentifierResponse = UtilIT.retrieveMyDataAsJsonString(superUserApiToken, userIdentifier, emptyRoleIdsList);
5153
assertEquals(prettyPrintError("myDataFinder.error.result.no.role", null), validUserIdentifierResponse.prettyPrint());
5254
assertEquals(OK.getStatusCode(), validUserIdentifierResponse.getStatusCode());
55+
56+
// Call as normal user with one valid role and no results
57+
Response createNormalUserResponse = UtilIT.createRandomUser();
58+
String normalUserUsername = UtilIT.getUsernameFromResponse(createNormalUserResponse);
59+
String normalUserApiToken = UtilIT.getApiTokenFromResponse(createNormalUserResponse);
60+
Response noResultwithOneRoleResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L)));
61+
assertEquals(prettyPrintError("myDataFinder.error.result.role.empty", Arrays.asList("Dataset Creator")), noResultwithOneRoleResponse.prettyPrint());
62+
assertEquals(OK.getStatusCode(), noResultwithOneRoleResponse.getStatusCode());
63+
64+
// Call as normal user with multiple valid roles and no results
65+
Response noResultWithMultipleRoleResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L, 6L)));
66+
assertEquals(prettyPrintError("myDataFinder.error.result.roles.empty", Arrays.asList("Dataset Creator, Contributor")), noResultWithMultipleRoleResponse.prettyPrint());
67+
assertEquals(OK.getStatusCode(), noResultWithMultipleRoleResponse.getStatusCode());
68+
69+
// Call as normal user with one valid dataset role and one dataset result
70+
Response createDataverseResponse = UtilIT.createRandomDataverse(normalUserApiToken);
71+
createDataverseResponse.prettyPrint();
72+
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);
73+
74+
Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, normalUserApiToken);
75+
createDatasetResponse.prettyPrint();
76+
Integer datasetId = UtilIT.getDatasetIdFromResponse(createDatasetResponse);
77+
UtilIT.sleepForReindex(datasetId.toString(), normalUserApiToken, 4);
78+
Response oneDatasetResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(6L)));
79+
assertEquals(OK.getStatusCode(), oneDatasetResponse.getStatusCode());
80+
JsonPath jsonPathOneDataset = oneDatasetResponse.getBody().jsonPath();
81+
assertEquals(1, jsonPathOneDataset.getInt("data.total_count"));
82+
assertEquals(datasetId, jsonPathOneDataset.getInt("data.items[0].entity_id"));
83+
84+
// Call as normal user with one valid dataverse role and one dataverse result
85+
UtilIT.grantRoleOnDataverse(dataverseAlias, DataverseRole.DS_CONTRIBUTOR.toString(),
86+
"@" + normalUserUsername, superUserApiToken);
87+
Response oneDataverseResponse = UtilIT.retrieveMyDataAsJsonString(normalUserApiToken, "", new ArrayList<>(Arrays.asList(5L)));
88+
assertEquals(OK.getStatusCode(), oneDataverseResponse.getStatusCode());
89+
JsonPath jsonPathOneDataverse = oneDataverseResponse.getBody().jsonPath();
90+
assertEquals(1, jsonPathOneDataverse.getInt("data.total_count"));
91+
assertEquals(dataverseAlias, jsonPathOneDataverse.getString("data.items[0].name"));
92+
93+
// Clean up
94+
Response deleteDatasetResponse = UtilIT.deleteDatasetViaNativeApi(datasetId, normalUserApiToken);
95+
deleteDatasetResponse.prettyPrint();
96+
assertEquals(200, deleteDatasetResponse.getStatusCode());
97+
98+
Response deleteDataverseResponse = UtilIT.deleteDataverse(dataverseAlias, normalUserApiToken);
99+
deleteDataverseResponse.prettyPrint();
100+
assertEquals(200, deleteDataverseResponse.getStatusCode());
101+
102+
Response deleteUserResponse = UtilIT.deleteUser(normalUserUsername);
103+
deleteUserResponse.prettyPrint();
104+
assertEquals(200, deleteUserResponse.getStatusCode());
53105
}
54106

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

0 commit comments

Comments
 (0)