Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5ee2360
DRAFT using mydata/retrieve API
stevenwinship Jul 23, 2025
2b8d4ee
DRAFT using mydata/retrieve API
stevenwinship Jul 23, 2025
f4d017c
DRAFT using mydata/retrieve API
stevenwinship Jul 23, 2025
2dee3f7
adding new api endpoint
stevenwinship Jul 24, 2025
6004421
update docs
stevenwinship Jul 24, 2025
d3d8358
new endpoint
stevenwinship Jul 28, 2025
ec0bdcf
switch to GetUserPermittedCollectionsCommand
stevenwinship Jul 29, 2025
e4da1b5
fix doc
stevenwinship Jul 29, 2025
d4d2db3
remove unused includes from test
stevenwinship Jul 29, 2025
639923a
remove unused method from test
stevenwinship Jul 29, 2025
9688bc0
adding superuser bypass
stevenwinship Jul 29, 2025
da46343
Merge branch 'develop' into 11525-retrieve-collections-a-user-can-cre…
stevenwinship Jul 29, 2025
ebbb223
adding id to json response
stevenwinship Jul 29, 2025
3ba39fe
Merge branch 'develop' into 11525-retrieve-collections-a-user-can-cre…
stevenwinship Aug 1, 2025
9a87d0f
Merge branch 'develop' into 11525-retrieve-collections-a-user-can-cre…
stevenwinship Aug 25, 2025
2b51bba
Update doc/sphinx-guides/source/api/native-api.rst
stevenwinship Aug 25, 2025
65fb72c
review comments and refactor
stevenwinship Aug 25, 2025
b752b22
review comments and refactor
stevenwinship Aug 25, 2025
785c4a3
adding unit test
stevenwinship Aug 25, 2025
09544db
refactor
stevenwinship Aug 26, 2025
3813f9b
review comments
stevenwinship Aug 26, 2025
a82b90b
review comments
stevenwinship Aug 26, 2025
baf0b00
if api key is present do not use session
stevenwinship Aug 27, 2025
9a977ab
review comments
stevenwinship Aug 29, 2025
9ea5df8
adding debug for testing
stevenwinship Aug 29, 2025
3abf810
adding debug for testing
stevenwinship Aug 29, 2025
174c136
remove debugging
stevenwinship Sep 2, 2025
abc7dc3
Merge branch 'develop' into 11525-retrieve-collections-a-user-can-cre…
stevenwinship Sep 5, 2025
b368b46
change collections to dataverses
stevenwinship Sep 5, 2025
2e449f3
addressing review comment
stevenwinship Sep 5, 2025
c792497
Update src/main/java/edu/harvard/iq/dataverse/engine/command/impl/Get…
stevenwinship Sep 8, 2025
2678e69
Refactor: removed unused logger and applied final keyword in class le…
GPortas Sep 8, 2025
cf7482e
Added: unit tests for GetUserPermittedCollectionsCommand
GPortas Sep 8, 2025
801d8cc
Fixed: incorrect response code in testUserPermittedDataverses IT
GPortas Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.List;
import java.util.logging.Logger;

import edu.harvard.iq.dataverse.settings.FeatureFlags;
import edu.harvard.iq.dataverse.util.json.JsonPrinter;
import jakarta.ejb.EJB;
import jakarta.inject.Inject;
Expand Down Expand Up @@ -126,9 +127,9 @@ private String getJSONErrorString(String jsonMsg, String optionalLoggerMsg){

private void verifyAuth (ContainerRequestContext crc, String userIdentifier) throws WrappedResponse {
// Handle calls from JSF where the User is in the session
boolean requiresApiKey = getRequestApiKey() != null;
User requestUser = getRequestUser(crc);
if (!requiresApiKey && session != null && session.getUser() != null && requestUser instanceof GuestUser) {
boolean checkSession = !FeatureFlags.API_SESSION_AUTH.enabled() && (requestUser instanceof GuestUser);
if (checkSession && session != null && session.getUser() != null) {
searchUser = authUser = (AuthenticatedUser) session.getUser();
if (!authUser.isAuthenticated()) {
throw new WrappedResponse(authenticatedUserRequired());
Expand Down Expand Up @@ -160,13 +161,13 @@ public String retrieveMyDataAsJsonString(
@QueryParam("userIdentifier") String userIdentifier,
@QueryParam("filter_validities") Boolean filterValidities,
@QueryParam("dataset_valid") List<Boolean> datasetValidities) {
boolean OTHER_USER = false;
boolean otherUser;

String noMsgResultsFound = BundleUtil.getStringFromBundle("dataretrieverAPI.noMsgResultsFound");

try {
verifyAuth(crc, userIdentifier);
OTHER_USER = !authUser.equals(searchUser);
otherUser = !authUser.equals(searchUser);
} catch (WrappedResponse wr) {
return this.getJSONErrorString((new JSONObject(wr.getResponse().getEntity().toString())).getString("message"), null);
}
Expand Down Expand Up @@ -299,7 +300,7 @@ public String retrieveMyDataAsJsonString(
//jsonData.add("total_dvobject_counts", getTotalCountsFromSolrAsJSON(searchUser, this.myDataFinder));


if (OTHER_USER){
if (otherUser){
jsonData.add("other_user", searchUser.getIdentifier());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ public void testRetrieveMyDataCollections() throws InterruptedException {
.body("message", startsWith("No user found for:"))
.statusCode(NOT_FOUND.getStatusCode());

// Unknown user gets the list of Dataverses/Collections it has access to
retrieveMyCollectionListResponse = UtilIT.retrieveMyCollectionList("badtoken", null);
retrieveMyCollectionListResponse.prettyPrint();
retrieveMyCollectionListResponse.then().assertThat()
.body("status", equalTo("ERROR"))
.body("message", equalTo(ApiKeyAuthMechanism.RESPONSE_MESSAGE_BAD_API_KEY))
.statusCode(UNAUTHORIZED.getStatusCode());

// Clean up
dataverses.forEach(dv -> {
Response deleteDataverseResponse = UtilIT.deleteDataverse(dv, superUserApiToken);
Expand Down
119 changes: 116 additions & 3 deletions src/test/java/edu/harvard/iq/dataverse/util/json/JsonPrinterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.util.*;
import java.util.stream.Collectors;

import edu.harvard.iq.dataverse.util.template.TemplateBuilder;

import jakarta.json.*;

import edu.harvard.iq.dataverse.util.BundleUtil;
Expand Down Expand Up @@ -481,7 +483,7 @@ public void testDatasetWithNondefaultType() {
@Test
public void testJsonArrayDataverseCollections() {
List<Dataverse> collections = new ArrayList<>();
for (long i=0; i < 10; i++) {
for (long i = 0; i < 10; i++) {
Dataverse dv = new Dataverse();
dv.setAlias("alias" + i);
dv.setName("Alias" + i);
Expand All @@ -491,16 +493,127 @@ public void testJsonArrayDataverseCollections() {
JsonObjectBuilder job = JsonPrinter.jsonArray(collections);
JsonObject result = job.build();
assertNotNull(result);
System.out.println(result);
assertEquals(10, result.getInt("count"));
JsonArray items = result.getJsonArray("items");
JsonObject item6 = items.getJsonObject(6);
System.out.println(item6);
assertEquals(6, item6.getInt("id"));
assertEquals("Alias6", item6.getString("name"));
assertEquals("alias6", item6.getString("alias"));
}

@Test
public void testJsonTermsOfUseAndAccess() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why these additions, which don't correspond to this PR, are being added here. It's strange.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't add them. I think it was a glitch in the merge from develop. Those lines were already there

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

// Setup a test TermsOfUseAndAccess
TermsOfUseAndAccess termsOfUseAndAccess = new TermsOfUseAndAccess();
termsOfUseAndAccess.setId(1L);
termsOfUseAndAccess.setTermsOfUse("Test Terms of Use");
termsOfUseAndAccess.setTermsOfAccess("Test Terms of Access");
termsOfUseAndAccess.setConfidentialityDeclaration("Test Confidentiality Declaration");
termsOfUseAndAccess.setSpecialPermissions("Test Special Permissions");
termsOfUseAndAccess.setRestrictions("Test Restrictions");
termsOfUseAndAccess.setCitationRequirements("Test Citation Requirements");
termsOfUseAndAccess.setDepositorRequirements("Test Depositor Requirements");
termsOfUseAndAccess.setConditions("Test Conditions");
termsOfUseAndAccess.setDisclaimer("Test Disclaimer");
termsOfUseAndAccess.setDataAccessPlace("Test Data Access Place");
termsOfUseAndAccess.setOriginalArchive("Test Original Archive");
termsOfUseAndAccess.setAvailabilityStatus("Test Availability Status");
termsOfUseAndAccess.setSizeOfCollection("Test Size of Collection");
termsOfUseAndAccess.setStudyCompletion("Test Study Completion");
termsOfUseAndAccess.setContactForAccess("Test Contact for Access");
termsOfUseAndAccess.setFileAccessRequest(true);

JsonObjectBuilder job = JsonPrinter.jsonTermsOfUseAndAccess(termsOfUseAndAccess);
assertNotNull(job);
JsonObject jsonObject = job.build();

// Assert all fields are present and correct
assertEquals(termsOfUseAndAccess.getId().longValue(), jsonObject.getJsonNumber("id").longValue());
assertEquals(termsOfUseAndAccess.getTermsOfUse(), jsonObject.getString("termsOfUse"));
assertEquals(termsOfUseAndAccess.getTermsOfAccess(), jsonObject.getString("termsOfAccess"));
assertEquals(termsOfUseAndAccess.getConfidentialityDeclaration(), jsonObject.getString("confidentialityDeclaration"));
assertEquals(termsOfUseAndAccess.getSpecialPermissions(), jsonObject.getString("specialPermissions"));
assertEquals(termsOfUseAndAccess.getRestrictions(), jsonObject.getString("restrictions"));
assertEquals(termsOfUseAndAccess.getCitationRequirements(), jsonObject.getString("citationRequirements"));
assertEquals(termsOfUseAndAccess.getDepositorRequirements(), jsonObject.getString("depositorRequirements"));
assertEquals(termsOfUseAndAccess.getConditions(), jsonObject.getString("conditions"));
assertEquals(termsOfUseAndAccess.getDisclaimer(), jsonObject.getString("disclaimer"));
assertEquals(termsOfUseAndAccess.getDataAccessPlace(), jsonObject.getString("dataAccessPlace"));
assertEquals(termsOfUseAndAccess.getOriginalArchive(), jsonObject.getString("originalArchive"));
assertEquals(termsOfUseAndAccess.getAvailabilityStatus(), jsonObject.getString("availabilityStatus"));
assertEquals(termsOfUseAndAccess.getSizeOfCollection(), jsonObject.getString("sizeOfCollection"));
assertEquals(termsOfUseAndAccess.getStudyCompletion(), jsonObject.getString("studyCompletion"));
assertEquals(termsOfUseAndAccess.getContactForAccess(), jsonObject.getString("contactForAccess"));
assertEquals(termsOfUseAndAccess.isFileAccessRequest(), jsonObject.getBoolean("fileAccessRequest"));

// Assert license is null
assertNull(jsonObject.getJsonObject("license"));

// Test with a license
long testLicenseId = 1L;
termsOfUseAndAccess.setLicense(createLicense(testLicenseId));
job = JsonPrinter.jsonTermsOfUseAndAccess(termsOfUseAndAccess);
assertNotNull(job);
jsonObject = job.build();
assertFalse(jsonObject.isNull("license"));
assertEquals(testLicenseId, jsonObject.getJsonObject("license").getJsonNumber("id").longValue());
}

@Test
public void testJsonTemplate() {
// Setup a test Template
Template template = TemplateBuilder.aTemplate().build();
JsonObjectBuilder job = JsonPrinter.jsonTemplate(template);
assertNotNull(job);
JsonObject jsonObject = job.build();

// Assert all fields are present and correct, skipping the ID since it is not set.
assertEquals(template.getName(), jsonObject.getString("name"));
assertEquals(template.isIsDefaultForDataverse(), jsonObject.getBoolean("isDefault"));
assertEquals(template.getUsageCount().longValue(), jsonObject.getJsonNumber("usageCount").longValue());
assertEquals(template.getCreateTime().toString(), jsonObject.getString("createTime"));
assertEquals(template.getCreateDate(), jsonObject.getString("createDate"));
assertEquals(template.getDataverse().getAlias(), jsonObject.getString("dataverseAlias"));

// Verify termsOfUseAndAccess field by checking a sub-field
JsonObject termsJson = jsonObject.getJsonObject("termsOfUseAndAccess");
assertNotNull(termsJson);
assertEquals(template.getTermsOfUseAndAccess().getTermsOfUse(), termsJson.getString("termsOfUse"));

// Verify datasetFields field is an empty JSON object
JsonObject datasetFieldsJson = jsonObject.getJsonObject("datasetFields");
assertNotNull(datasetFieldsJson);
assertTrue(datasetFieldsJson.isEmpty());

// Verify instructions map properties are correct regardless of order
JsonArray instructionsJson = jsonObject.getJsonArray("instructions");
assertEquals(2, instructionsJson.size());

Map<String, String> instructionsMap = instructionsJson.stream()
.map(jsonValue -> (JsonObject) jsonValue)
.collect(Collectors.toMap(
obj -> obj.getString("instructionField"),
obj -> obj.getString("instructionText")
));

assertEquals("Enter the author's name here.", instructionsMap.get("author"));
assertEquals("Provide a title for the dataset.", instructionsMap.get("title"));
}

private License createLicense(long id) {
License license = new License();
license.setId(id);
license.setName("Test License " + id);
license.setShortDescription("Short description for license " + id);
try {
license.setUri(new java.net.URI("http://test.org/" + id));
} catch (java.net.URISyntaxException e) {
e.printStackTrace();
}
license.setActive(true);
return license;
}

private Dataverse createDataverse(long id) {
Dataverse dataverse = new Dataverse();
dataverse.setId(id);
Expand Down