From b425f76fef93f1bdab6a9286022c2d98131932c7 Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Wed, 22 Oct 2025 17:32:43 +0200 Subject: [PATCH 1/3] feat: let APIs return more info about role assignments --- .../edu/harvard/iq/dataverse/DvObject.java | 2 ++ .../iq/dataverse/util/json/JsonPrinter.java | 33 ++++++++++++++----- .../util/json/JsonPrinterHelper.java | 11 ++++--- .../dataverse/util/json/JsonPrinterTest.java | 17 ++++++++-- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DvObject.java b/src/main/java/edu/harvard/iq/dataverse/DvObject.java index 68ff739a77f..f8d031b8b4a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DvObject.java +++ b/src/main/java/edu/harvard/iq/dataverse/DvObject.java @@ -140,6 +140,8 @@ public String visit(DataFile df) { @Column(insertable = false, updatable = false) private String dtype; + public String getDtype() { return dtype; } + @OneToMany(mappedBy="dvobject",fetch = FetchType.LAZY,cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) private List dataverseFeaturedItems; diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java index 8b0ea201aa3..802bb23d2a1 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java @@ -84,18 +84,23 @@ public class JsonPrinter { @EJB static InAppNotificationsJsonPrinter inAppNotificationsJsonPrinter; + + @EJB + static RoleAssigneeServiceBean roleAssigneeService; public static void injectSettingsService(SettingsServiceBean ssb, DatasetFieldServiceBean dfsb, DataverseFieldTypeInputLevelServiceBean dfils, DatasetServiceBean ds, MailServiceBean ms, - InAppNotificationsJsonPrinter njp) { + InAppNotificationsJsonPrinter njp, + RoleAssigneeServiceBean ras) { settingsService = ssb; datasetFieldService = dfsb; datasetService = ds; mailService = ms; inAppNotificationsJsonPrinter = njp; + roleAssigneeService = ras; } public JsonPrinter() { @@ -150,14 +155,24 @@ public static JsonArrayBuilder jsonRoleAssignments(List roleAssi } public static JsonObjectBuilder json(RoleAssignment ra) { - return jsonObjectBuilder() - .add("id", ra.getId()) - .add("assignee", ra.getAssigneeIdentifier()) - .add("roleId", ra.getRole().getId()) - .add("roleName", ra.getRole().getName()) - .add("_roleAlias", ra.getRole().getAlias()) - .add("privateUrlToken", ra.getPrivateUrlToken()) - .add("definitionPointId", ra.getDefinitionPoint().getId()); + JsonObjectBuilder job = jsonObjectBuilder() + .add("id", ra.getId()) + .add("assignee", ra.getAssigneeIdentifier()) + .add("assigneeName", roleAssigneeService.getRoleAssignee(ra.getAssigneeIdentifier()).getDisplayInfo().getTitle()) + .add("roleId", ra.getRole().getId()) + .add("roleName", ra.getRole().getName()) + .add("roleDescription", ra.getRole().getDescription()) + .add("_roleAlias", ra.getRole().getAlias()) + .add("privateUrlToken", ra.getPrivateUrlToken()) + .add("definitionPointId", ra.getDefinitionPoint().getId()) + .add("definitionPointName", ra.getDefinitionPoint().getDisplayName()) + .add("definitionPointType", ra.getDefinitionPoint().getDtype()); + + if (ra.getDefinitionPoint().getGlobalId() != null) { + job.add("definitionPointGlobalId", ra.getDefinitionPoint().getGlobalId().toString()); + } + + return job; } public static JsonArrayBuilder json(Set permissions) { diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinterHelper.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinterHelper.java index a9a05f1b699..5b75f41ad00 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinterHelper.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinterHelper.java @@ -1,9 +1,6 @@ package edu.harvard.iq.dataverse.util.json; -import edu.harvard.iq.dataverse.DatasetFieldServiceBean; -import edu.harvard.iq.dataverse.DatasetServiceBean; -import edu.harvard.iq.dataverse.DataverseFieldTypeInputLevelServiceBean; -import edu.harvard.iq.dataverse.MailServiceBean; +import edu.harvard.iq.dataverse.*; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import jakarta.annotation.PostConstruct; @@ -37,6 +34,9 @@ public class JsonPrinterHelper { @EJB InAppNotificationsJsonPrinter inAppNotificationsJsonPrinter; + @EJB + RoleAssigneeServiceBean roleAssigneeService; + @PostConstruct public void injectService() { JsonPrinter.injectSettingsService( @@ -45,7 +45,8 @@ public void injectService() { datasetFieldInpuLevelSvc, datasetSvc, mailSvc, - inAppNotificationsJsonPrinter + inAppNotificationsJsonPrinter, + roleAssigneeService ); } } diff --git a/src/test/java/edu/harvard/iq/dataverse/util/json/JsonPrinterTest.java b/src/test/java/edu/harvard/iq/dataverse/util/json/JsonPrinterTest.java index c17529fb6ac..56e4b017fc4 100644 --- a/src/test/java/edu/harvard/iq/dataverse/util/json/JsonPrinterTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/util/json/JsonPrinterTest.java @@ -105,6 +105,7 @@ public void setUp() { @Test public void testJson_RoleAssignment() { + JsonPrinter.injectSettingsService(null, null, null, null, null, null, new MockRoleAssigneeService()); DataverseRole aRole = new DataverseRole(); PrivateUrlUser privateUrlUserIn = new PrivateUrlUser(42); RoleAssignee anAssignee = privateUrlUserIn; @@ -122,6 +123,7 @@ public void testJson_RoleAssignment() { @Test public void testJson_PrivateUrl() { + JsonPrinter.injectSettingsService(null, null, null, null, null, null, new MockRoleAssigneeService()); DataverseRole aRole = new DataverseRole(); PrivateUrlUser privateUrlUserIn = new PrivateUrlUser(42); RoleAssignee anAssignee = privateUrlUserIn; @@ -205,7 +207,7 @@ public void testDatasetContactOutOfBoxNoPrivacy() { datasetContactField.setDatasetFieldCompoundValues(vals); fields.add(datasetContactField); - JsonPrinter.injectSettingsService(null, null, null, null, null, null); + JsonPrinter.injectSettingsService(null, null, null, null, null, null, null); JsonObject jsonObject = JsonPrinter.json(block, fields).build(); assertNotNull(jsonObject); @@ -246,7 +248,7 @@ public void testDatasetContactWithPrivacy() { datasetContactField.setDatasetFieldCompoundValues(vals); fields.add(datasetContactField); - JsonPrinter.injectSettingsService(new MockSettingsSvc(), null, null, null, null, null); + JsonPrinter.injectSettingsService(new MockSettingsSvc(), null, null, null, null, null, null); JsonObject jsonObject = JsonPrinter.json(block, fields).build(); assertNotNull(jsonObject); @@ -296,7 +298,7 @@ public void testDatasetFieldTypesWithChildren() { block.setDatasetFieldTypes(datasetFieldTypes); - JsonPrinter.injectSettingsService(new MockSettingsSvc(), null, null ,null, null, null); + JsonPrinter.injectSettingsService(new MockSettingsSvc(), null, null ,null, null, null, null); JsonObject jsonObject = JsonPrinter.json(block).build(); assertNotNull(jsonObject); @@ -361,6 +363,15 @@ public boolean isTrueForKey(SettingsServiceBean.Key key, boolean defaultValue) { } + private static class MockRoleAssigneeService extends RoleAssigneeServiceBean { + + @Override + public RoleAssignee getRoleAssignee(String identifier) { + return new PrivateUrlUser(42); + } + + } + @Test public void testEnum() throws JsonParseException { JsonArrayBuilder arr = JsonPrinter.enumsToJson(Arrays.asList(Type.REVOKEROLE, Type.ASSIGNROLE)); From 2c1c64b7c471edc4b335f9f421282d16be3f348e Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Wed, 22 Oct 2025 17:46:04 +0200 Subject: [PATCH 2/3] docs: add release note for #11920 --- doc/release-notes/11920-more-ra-info.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/release-notes/11920-more-ra-info.md diff --git a/doc/release-notes/11920-more-ra-info.md b/doc/release-notes/11920-more-ra-info.md new file mode 100644 index 00000000000..7ef12e06fea --- /dev/null +++ b/doc/release-notes/11920-more-ra-info.md @@ -0,0 +1 @@ +All API endpoints that return information about role assignments (such as `/api/dataverses/$ID/assignments`) now include additional fields in their JSON responses: `assigneeName`, `roleDescription`, `definitionPointName`, `definitionPointType`, and `definitionPointGlobalId` (if available). \ No newline at end of file From ae5a7abdbe200662c0b834b7026debc2e472fe30 Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Wed, 22 Oct 2025 17:46:33 +0200 Subject: [PATCH 3/3] fix: fix style error in DvObject.java --- src/main/java/edu/harvard/iq/dataverse/DvObject.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DvObject.java b/src/main/java/edu/harvard/iq/dataverse/DvObject.java index f8d031b8b4a..f9f35cedc80 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DvObject.java +++ b/src/main/java/edu/harvard/iq/dataverse/DvObject.java @@ -140,7 +140,9 @@ public String visit(DataFile df) { @Column(insertable = false, updatable = false) private String dtype; - public String getDtype() { return dtype; } + public String getDtype() { + return dtype; + } @OneToMany(mappedBy="dvobject",fetch = FetchType.LAZY,cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) private List dataverseFeaturedItems;