Skip to content

Commit b330d21

Browse files
authored
Merge pull request #11636 from IQSS/11465-api-fetch-download-size-file-count
Bug: block guest from calling api
2 parents bfe59f0 + 2f2fd80 commit b330d21

File tree

7 files changed

+148
-7
lines changed

7 files changed

+148
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The following APIs have now been blocked for Guest Users:
2+
3+
/api/v1/datasets/:persistentId/versions/:latest-published/downloadsize?persistentId=doi:10.5072/FK2/VSAYEM&includeDeaccessioned=true&mode=Archival
4+
/api/v1/datasets/:persistentId/versions/1.0/files/counts?persistentId=doi:10.5072/FK2/VSAYEM&includeDeaccessioned=true

doc/sphinx-guides/source/api/native-api.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,6 +1800,8 @@ The returned file counts are based on different criteria:
18001800
- Per tabular tag name
18011801
- Per access status (Possible values: Public, Restricted, EmbargoedThenRestricted, EmbargoedThenPublic, RetentionPeriodExpired)
18021802

1803+
Note: Authentication is required. This call will return a 403/Forbidden response for Guest users.
1804+
18031805
.. code-block:: bash
18041806
18051807
export SERVER_URL=https://demo.dataverse.org
@@ -2781,6 +2783,7 @@ Get the size of Downloading all the files of a Dataset Version
27812783
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27822784

27832785
Shows the combined size in bytes of all the files available for download from version ``versionId`` of dataset ``id``.
2786+
Note: Authentication is required. This call will return a 403/Forbidden response for Guest users.
27842787

27852788
.. code-block:: bash
27862789

src/main/java/edu/harvard/iq/dataverse/api/Datasets.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,11 @@ public Response getVersionFileCounts(@Context ContainerRequestContext crc,
571571
@QueryParam("includeDeaccessioned") boolean includeDeaccessioned,
572572
@Context UriInfo uriInfo,
573573
@Context HttpHeaders headers) {
574+
try {
575+
getRequestAuthenticatedUserOrDie(crc);
576+
} catch (WrappedResponse e) {
577+
return forbidden(BundleUtil.getStringFromBundle("datasets.api.version.files.invalid.auth"));
578+
}
574579
return response(req -> {
575580
FileSearchCriteria fileSearchCriteria;
576581
try {
@@ -3516,7 +3521,11 @@ public Response getDownloadSize(@Context ContainerRequestContext crc,
35163521
@QueryParam("includeDeaccessioned") boolean includeDeaccessioned,
35173522
@Context UriInfo uriInfo,
35183523
@Context HttpHeaders headers) {
3519-
3524+
try {
3525+
getRequestAuthenticatedUserOrDie(crc);
3526+
} catch (WrappedResponse e) {
3527+
return forbidden(BundleUtil.getStringFromBundle("datasets.api.version.files.invalid.auth"));
3528+
}
35203529
return response(req -> {
35213530
FileSearchCriteria fileSearchCriteria;
35223531
try {

src/main/java/propertyFiles/Bundle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,6 +2833,7 @@ datasets.api.curationstatuscreatetime=Status Set Time
28332833
datasets.api.curationstatussetter=Status Set By
28342834
datasets.api.version.files.invalid.order.criteria=Invalid order criteria: {0}
28352835
datasets.api.version.files.invalid.access.status=Invalid access status: {0}
2836+
datasets.api.version.files.invalid.auth=Only authenticated users can access this information.
28362837
datasets.api.deaccessionDataset.invalid.version.identifier.error=Only {0} or a specific version can be deaccessioned
28372838
datasets.api.deaccessionDataset.invalid.forward.url=Invalid deaccession forward URL: {0}
28382839
datasets.api.globusdownloaddisabled=File transfer from Dataverse via Globus is not available for this dataset.

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5617,10 +5617,10 @@ public void getVersionFileCounts() throws IOException, InterruptedException {
56175617
// Test that the dataset file counts for a deaccessioned dataset cannot be accessed by a guest
56185618
// By latest published version
56195619
Response getDatasetVersionResponse = UtilIT.getVersionFileCounts(datasetId, DS_VERSION_LATEST_PUBLISHED, null, null, null, null, null, true, null);
5620-
getDatasetVersionResponse.then().assertThat().statusCode(NOT_FOUND.getStatusCode());
5620+
getDatasetVersionResponse.then().assertThat().statusCode(FORBIDDEN.getStatusCode());
56215621
// By specific version 1.0
56225622
getDatasetVersionResponse = UtilIT.getVersionFileCounts(datasetId, "1.0", null, null, null, null, null, true, null);
5623-
getDatasetVersionResponse.then().assertThat().statusCode(NOT_FOUND.getStatusCode());
5623+
getDatasetVersionResponse.then().assertThat().statusCode(FORBIDDEN.getStatusCode());
56245624
}
56255625

56265626
@Test
@@ -5807,10 +5807,10 @@ public void getDownloadSize() throws IOException, InterruptedException {
58075807
// Test that the dataset file counts for a deaccessioned dataset cannot be accessed by a guest
58085808
// By latest published version
58095809
Response getVersionFileCountsGuestUserResponse = UtilIT.getDownloadSize(datasetId, DS_VERSION_LATEST_PUBLISHED, null, null, null, null, null, DatasetVersionFilesServiceBean.FileDownloadSizeMode.All.toString(), true, null);
5810-
getVersionFileCountsGuestUserResponse.then().assertThat().statusCode(NOT_FOUND.getStatusCode());
5810+
getVersionFileCountsGuestUserResponse.then().assertThat().statusCode(FORBIDDEN.getStatusCode());
58115811
// By specific version 1.0
58125812
getVersionFileCountsGuestUserResponse = UtilIT.getDownloadSize(datasetId, "1.0", null, null, null, null, null, DatasetVersionFilesServiceBean.FileDownloadSizeMode.All.toString(), true, null);
5813-
getVersionFileCountsGuestUserResponse.then().assertThat().statusCode(NOT_FOUND.getStatusCode());
5813+
getVersionFileCountsGuestUserResponse.then().assertThat().statusCode(FORBIDDEN.getStatusCode());
58145814
}
58155815

58165816
@Test

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

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1440,13 +1440,90 @@ public void testDataSizeInDataverse() throws InterruptedException {
14401440

14411441
magicControlString = MessageFormat.format(BundleUtil.getStringFromBundle("datasets.api.datasize.download"), magicSizeNumber);
14421442

1443-
Response datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId.toString());
1443+
Response datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId.toString(), apiTokenRando, null, null, null);
14441444
datasetDownloadSizeResponse.prettyPrint();
14451445

14461446
assertEquals(magicControlString, JsonPath.from(datasetDownloadSizeResponse.body().asString()).getString("data.message"));
14471447

14481448
}
14491449

1450+
@Test
1451+
public void testDeaccessionedDatasetGetDownloadSize() {
1452+
// Create user
1453+
String apiToken = createUserGetToken();
1454+
// Create Dataverse
1455+
String dataverseAlias = createDataverseGetAlias(apiToken);
1456+
// Create Dataset
1457+
String datasetId1 = createDatasetGetId(dataverseAlias, apiToken).toString();
1458+
String datasetId2 = createDatasetGetId(dataverseAlias, apiToken).toString();
1459+
String pathToFile = "scripts/search/data/binary/trees.png";
1460+
Response addResponse = UtilIT.uploadFileViaNative(datasetId1, pathToFile, apiToken);
1461+
1462+
// Publish
1463+
UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken);
1464+
UtilIT.publishDatasetViaNativeApi(datasetId1, "major", apiToken);
1465+
UtilIT.publishDatasetViaNativeApi(datasetId2, "major", apiToken);
1466+
1467+
// Test get sizes from Published Dataset with no files
1468+
Response datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId2, apiToken, null, Boolean.TRUE, null);
1469+
datasetDownloadSizeResponse.prettyPrint();
1470+
datasetDownloadSizeResponse.then().assertThat()
1471+
.body("data.message", containsString("0 bytes"))
1472+
.body("data.storageSize", equalTo(0))
1473+
.statusCode(OK.getStatusCode());
1474+
// Test get files count from Published Dataset with no files
1475+
Response datasetFilesCountResponse = UtilIT.findDatasetFilesCount(datasetId2, apiToken, null, Boolean.TRUE);
1476+
datasetFilesCountResponse.prettyPrint();
1477+
datasetFilesCountResponse.then().assertThat()
1478+
.body("data.total", equalTo(0))
1479+
.statusCode(OK.getStatusCode());
1480+
1481+
// Deaccession the Dataset
1482+
UtilIT.deaccessionDataset(datasetId1, "1.0", "reason", null, apiToken).prettyPrint();
1483+
UtilIT.deaccessionDataset(datasetId2, "1.0", "reason", null, apiToken).prettyPrint();
1484+
1485+
// Test get sizes from Deaccessioned Dataset with files (Auth user)
1486+
datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId1, apiToken, null, Boolean.TRUE, "Archival");
1487+
datasetDownloadSizeResponse.prettyPrint();
1488+
datasetDownloadSizeResponse.then().assertThat()
1489+
.body("data.message", containsString("8,361 bytes"))
1490+
.body("data.storageSize", equalTo(8361))
1491+
.statusCode(OK.getStatusCode());
1492+
// Test get sizes from Deaccessioned Dataset with files (Guest user)
1493+
datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId1, null, null, Boolean.TRUE, "Archival");
1494+
datasetDownloadSizeResponse.prettyPrint();
1495+
datasetDownloadSizeResponse.then().assertThat()
1496+
.statusCode(FORBIDDEN.getStatusCode())
1497+
.body("message", equalTo(BundleUtil.getStringFromBundle("datasets.api.version.files.invalid.auth")));
1498+
1499+
// Test get sizes from Deaccessioned Dataset with no files (Auth user)
1500+
datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId2, apiToken, null, Boolean.TRUE, "Archival");
1501+
datasetDownloadSizeResponse.prettyPrint();
1502+
datasetDownloadSizeResponse.then().assertThat()
1503+
.body("data.message", containsString("0 bytes"))
1504+
.body("data.storageSize", equalTo(0))
1505+
.statusCode(OK.getStatusCode());
1506+
// Test get sizes from Deaccessioned Dataset with no files (Guest user)
1507+
datasetDownloadSizeResponse = UtilIT.findDatasetDownloadSize(datasetId2, null, null, Boolean.TRUE, "Archival");
1508+
datasetDownloadSizeResponse.prettyPrint();
1509+
datasetDownloadSizeResponse.then().assertThat()
1510+
.statusCode(FORBIDDEN.getStatusCode())
1511+
.body("message", equalTo(BundleUtil.getStringFromBundle("datasets.api.version.files.invalid.auth")));
1512+
1513+
// Test get files count from Deaccessioned Dataset with no files (Auth user)
1514+
datasetFilesCountResponse = UtilIT.findDatasetFilesCount(datasetId2, apiToken, null, Boolean.TRUE);
1515+
datasetFilesCountResponse.prettyPrint();
1516+
datasetFilesCountResponse.then().assertThat()
1517+
.body("data.total", equalTo(0))
1518+
.statusCode(OK.getStatusCode());
1519+
// Test get files count from Deaccessioned Dataset with no files (Guest user)
1520+
datasetFilesCountResponse = UtilIT.findDatasetFilesCount(datasetId2, null, null, Boolean.TRUE);
1521+
datasetFilesCountResponse.prettyPrint();
1522+
datasetFilesCountResponse.then().assertThat()
1523+
.statusCode(FORBIDDEN.getStatusCode())
1524+
.body("message", equalTo(BundleUtil.getStringFromBundle("datasets.api.version.files.invalid.auth")));
1525+
}
1526+
14501527
@Test
14511528
public void GetFileVersionDifferences() {
14521529
// Create superuser and regular user

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3697,7 +3697,54 @@ static Response findDatasetDownloadSize(String datasetId, String version, Strin
36973697
.header(API_TOKEN_HTTP_HEADER, apiToken)
36983698
.get("/api/datasets/" + datasetId + "/versions/" + version + "/downloadsize");
36993699
}
3700-
3700+
3701+
static Response findDatasetDownloadSize(String datasetId, String apiToken, String version, Boolean includeDeaccessioned, String mode) {
3702+
String id = datasetId;
3703+
if (version == null) {
3704+
version = ":latest-published";
3705+
}
3706+
RequestSpecification requestSpecification = given();
3707+
3708+
if (datasetId.startsWith("doi:")) {
3709+
id = ":persistentId";
3710+
requestSpecification.queryParam("persistentId", datasetId);
3711+
}
3712+
if (includeDeaccessioned != null) {
3713+
requestSpecification.queryParam("includeDeaccessioned", includeDeaccessioned);
3714+
}
3715+
if (mode != null) {
3716+
requestSpecification.queryParam("mode", mode);
3717+
}
3718+
3719+
if (apiToken != null) {
3720+
requestSpecification.header(UtilIT.API_TOKEN_HTTP_HEADER, apiToken);
3721+
}
3722+
return requestSpecification
3723+
.get("/api/datasets/" + id + "/versions/" + version + "/downloadsize");
3724+
}
3725+
3726+
static Response findDatasetFilesCount(String datasetId, String apiToken, String version, Boolean includeDeaccessioned) {
3727+
String id = datasetId;
3728+
if (version == null) {
3729+
version = ":latest-published";
3730+
}
3731+
RequestSpecification requestSpecification = given();
3732+
3733+
if (datasetId.startsWith("doi:")) {
3734+
id = ":persistentId";
3735+
requestSpecification.queryParam("persistentId", datasetId);
3736+
}
3737+
if (includeDeaccessioned != null) {
3738+
requestSpecification.queryParam("includeDeaccessioned", includeDeaccessioned);
3739+
}
3740+
3741+
if (apiToken != null) {
3742+
requestSpecification.header(UtilIT.API_TOKEN_HTTP_HEADER, apiToken);
3743+
}
3744+
return requestSpecification
3745+
.get("/api/datasets/" + id + "/versions/" + version + "/files/counts");
3746+
}
3747+
37013748
static Response addBannerMessage(String pathToJsonFile) {
37023749
String jsonIn = getDatasetJson(pathToJsonFile);
37033750

0 commit comments

Comments
 (0)