Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
3f9ada4
Refactor: Notifications.getAllNotificationsForUser high level clean up
GPortas Jul 30, 2025
fc1ad89
Refactor: moved response payload generation logic from getAllNotifica…
GPortas Jul 30, 2025
95a53d4
Refactor: using same Bundle string on common responses in Notificatio…
GPortas Jul 30, 2025
63a7753
Stash: inAppNotificationFormat option in getAllNotificationsForUser WIP
GPortas Jul 30, 2025
c65a20f
Removed: MailServiceBean from Notifications
GPortas Jul 30, 2025
7abb5fa
Removed: unused method getReasonsForReturn
GPortas Jul 30, 2025
b4313ae
Added: InAppNotificationsJsonPrinter for adding the necessary fields …
GPortas Jul 30, 2025
a3ce057
Stash: replicating JSF notifications data in InAppNotificationsJsonPr…
GPortas Jul 31, 2025
345a0af
Added: ASSIGNROLE Dataverse notification to InAppNotificationsJsonPri…
GPortas Jul 31, 2025
acff848
Added: InAppNotificationsJsonPrinter logic for ASSIGNROLE, REVOKEROLE…
GPortas Aug 2, 2025
503b20e
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 2, 2025
12ef731
Refactor: new method addCreateAccountFields extracted in InAppNotific…
GPortas Aug 2, 2025
5d6e00a
Added: addFieldsByType logic for REQUESTFILEACCESS and REQUESTEDFILEA…
GPortas Aug 2, 2025
e199bf1
Added: addFieldsByType logic for GRANTFILEACCESS and REJECTFILEACCESS…
GPortas Aug 2, 2025
edfdac2
Added: addFieldsByType logic for DATASETCREATED to InAppNotifications…
GPortas Aug 2, 2025
a247df0
Added: tweaks and fixes to InAppNotificationsJsonPrinter
GPortas Aug 2, 2025
83e32fc
Added: notifications and tweaks to InAppNotificationsJsonPrinter
GPortas Aug 2, 2025
c8f93ff
Refactor: InAppNotificationsJsonPrinter
GPortas Aug 2, 2025
aa6ba8c
Stash: InAppNotificationsJsonPrinterTest WIP
GPortas Aug 4, 2025
fb61d37
Fixed: InAppNotificationsJsonPrinterTest
GPortas Aug 5, 2025
1fcad70
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 5, 2025
15ee5b1
Fixed: JsonPrinter new dependencies injection
GPortas Aug 6, 2025
052f886
Changed: enhanced CreateNewDatasetCommand to allow self notifications…
GPortas Aug 7, 2025
7d341d7
Added: sending notification when a dataset is created through the /da…
GPortas Aug 7, 2025
3f101d3
Added: NotificationsIT case when SendNotificationOnDatasetCreation se…
GPortas Aug 7, 2025
a5e1a08
Added: user notification sent when running addDataverse endpoint
GPortas Aug 8, 2025
b57d8a4
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 8, 2025
d99324d
Added: NotificationsIT test cases for inAppNotificationFormat query p…
GPortas Aug 8, 2025
974cd1a
Added: missing assertions to NotificationsIT
GPortas Aug 8, 2025
2b8d600
Added: docs for #11648
GPortas Aug 8, 2025
57f3d99
Added: doc format tweak
GPortas Aug 8, 2025
e4b921e
Added: docs for #11648
GPortas Aug 8, 2025
9a5b3d0
Added: API section param to notifications payload
GPortas Aug 11, 2025
183ce1c
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 11, 2025
af54086
Added: disabling SendNotificationOnDatasetCreation after IT test
GPortas Aug 11, 2025
56b2207
Fixed: NPE exception on notifications API when a dataverse has no owner
GPortas Aug 11, 2025
5fda593
Added: tweak to notifications API docs
GPortas Aug 11, 2025
daa4e3f
Fixed: CREATEDS not returning expected fields
GPortas Aug 12, 2025
21ab283
Added: guide section param to INGESTCOMPLETED notif payload
GPortas Aug 12, 2025
e76a366
Added: sending new objectDeleted field when the object of the notific…
GPortas Aug 12, 2025
e1ec2f8
Update doc/release-notes/11648-notifications-api-extension.md
GPortas Aug 12, 2025
99514ab
Fixed: InReviewWorkflowIT
GPortas Aug 12, 2025
e83ceb8
Merge branch '11648-notifications-api-extension' of github.com:IQSS/d…
GPortas Aug 12, 2025
ddd29ab
Refactor: always using getRequestAuthenticatedUserOrDie in Notificati…
GPortas Aug 12, 2025
3f4cc64
Refactor: use enum toString instead of hardcoded strings in Notificat…
GPortas Aug 12, 2025
4b98088
Refactor: use enum toString instead of hardcoded strings in InReviewW…
GPortas Aug 12, 2025
18e78c7
Removed: unused throws in test
GPortas Aug 12, 2025
d3126f0
Changed: using BeforeAll and AfterAll in NotificationsIT with disable…
GPortas Aug 12, 2025
5618740
Refactor: renamed CreateNewDatasetCommand variable
GPortas Aug 13, 2025
03c3a8a
Added: installationName param to CREATEACC notification In-App payload
GPortas Aug 14, 2025
dd3a695
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 14, 2025
ee3f605
Removed: 'v' prefix from guides version number in InApp notifications…
GPortas Aug 14, 2025
3966a3c
Fixed: updated unit test for InApp notifications
GPortas Aug 14, 2025
e6f4221
Added: javadocs for CreateDataverseCommand.onSuccess method
GPortas Aug 14, 2025
db953d0
Added: explanatory comment to PermissionServiceBean.getEffectiveRoleA…
GPortas Aug 14, 2025
f1dea35
Removed: language path param from guides URL in returned InApp notifi…
GPortas Aug 14, 2025
c38aeac
Changed: installationBrandName param relying on BrandingUtils
GPortas Aug 14, 2025
e1b4551
Removed: method for removing 'v' from guides viersion in InAppNotific…
GPortas Aug 15, 2025
877e428
Merge branch 'develop' of github.com:IQSS/dataverse into 11648-notifi…
GPortas Aug 15, 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
7 changes: 7 additions & 0 deletions doc/release-notes/11648-notifications-api-extension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# getAllNotificationsForUser API extension

- Extended endpoint getAllNotificationsForUser(``/notifications/all``), which now supports an optional query parameter ``inAppNotificationFormat`` which, if sent as ``true``, retrieves the fields needed to build the in-app notifications for the Notifications section of the Dataverse UI, omitting fields related to email notifications. See also #11648 and #11696.

# Notifications triggered by API endpoints

The addDataset and addDataverse API endpoints now trigger user notifications upon successful execution. See also #1342 and #11696.
29 changes: 29 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6001,6 +6001,35 @@ The expected OK (200) response looks something like this:
}
...

This endpoint supports an optional query parameter ``inAppNotificationFormat`` which, if sent as ``true``, retrieves the fields needed to build the in-app notifications for the Notifications section of the Dataverse UI, omitting fields related to email notifications.
Comment thread
GPortas marked this conversation as resolved.

.. code-block:: bash

curl -H "X-Dataverse-key:$API_TOKEN" "$SERVER_URL/api/notifications/all?inAppNotificationFormat=true"

The expected OK (200) response looks something like this:

.. code-block:: text

{
"status": "OK",
"data": {
"notifications": [
{
"id": 79,
"type": "CREATEACC",
"displayAsRead": false,
"sentTimestamp": "2025-08-08T08:00:16Z",
"installationBrandName": "Your Installation Name",
"userGuidesBaseUrl": "https://guides.dataverse.org",
"userGuidesVersion": "6.7.1",
"userGuidesSectionPath": "user/index.html"
}
]
}
}
...

Get Unread Count
~~~~~~~~~~~~~~~~

Expand Down
40 changes: 31 additions & 9 deletions src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.authorization.users.User;
import edu.harvard.iq.dataverse.engine.command.Command;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;

import java.util.*;
import java.util.logging.Logger;
import jakarta.ejb.EJB;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.util.HashSet;
import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import static edu.harvard.iq.dataverse.engine.command.CommandHelper.CH;
Expand All @@ -34,11 +31,9 @@
import edu.harvard.iq.dataverse.workflow.PendingWorkflowInvocation;
import edu.harvard.iq.dataverse.workflow.WorkflowServiceBean;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;
import jakarta.persistence.Query;
import jakarta.persistence.criteria.CriteriaBuilder;
Expand Down Expand Up @@ -926,6 +921,7 @@ private boolean hasUnrestrictedReleasedFiles(DatasetVersion targetDatasetVersion
public List<Dataverse> findPermittedCollections(DataverseRequest request, AuthenticatedUser user, Permission permission) {
return findPermittedCollections(request, user, 1 << permission.ordinal());
}

public List<Dataverse> findPermittedCollections(DataverseRequest request, AuthenticatedUser user, int permissionBit) {
if (user != null) {
// IP Group - Only check IP if a User is calling for themself
Expand Down Expand Up @@ -963,5 +959,31 @@ public List<Dataverse> findPermittedCollections(DataverseRequest request, Authen
}
return null;
}

/**
* Calculates the complete list of role assignments for a given user on a DvObject.
* This includes roles assigned directly to the user and roles inherited from any groups
* the user is a member of.
* <p>
* This method's logic is based on the private method {@code getRoleStringFromUser}
* in the {@code DataverseUserPage} class, which produces a concatenated string of
* effective user role names required for displaying role-related user notifications.
* The common logic from these two methods may be centralized in the future to
* avoid code duplication.
*
* @param user The authenticated user whose roles are being checked.
* @param dvObject The dataverse object to check for role assignments.
* @return A List containing all effective RoleAssignments for the user. Never null.
*/
public List<RoleAssignment> getEffectiveRoleAssignments(AuthenticatedUser user, DvObject dvObject) {
Stream<RoleAssignment> directAssignments = assignmentsFor(user, dvObject).stream();

Stream<RoleAssignment> groupAssignments = groupService.groupsFor(user, dvObject)
.stream()
.flatMap(group -> assignmentsFor(group, dvObject).stream());

return Stream.concat(directAssignments, groupAssignments)
.collect(Collectors.toList());
}
Comment thread
pdurbin marked this conversation as resolved.
}

6 changes: 3 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public Response addDataverse(@Context ContainerRequestContext crc, String body,
}

AuthenticatedUser u = getRequestAuthenticatedUserOrDie(crc);
newDataverse = execCommand(new CreateDataverseCommand(newDataverse, createDataverseRequest(u), facets, inputLevels, metadataBlocks));
newDataverse = execCommand(new CreateDataverseCommand(newDataverse, createDataverseRequest(u), facets, inputLevels, metadataBlocks, true));
return created("/dataverses/" + newDataverse.getAlias(), json(newDataverse));

} catch (WrappedResponse ww) {
Expand Down Expand Up @@ -407,9 +407,9 @@ public Response createDataset(@Context ContainerRequestContext crc, String jsonB
ds.setIdentifier(null);
ds.setProtocol(null);
ds.setGlobalIdCreateTime(null);
Dataset managedDs = null;
Dataset managedDs;
try {
managedDs = execCommand(new CreateNewDatasetCommand(ds, createDataverseRequest(u), null, validate));
managedDs = execCommand(new CreateNewDatasetCommand(ds, createDataverseRequest(u), validate, true));
} catch (WrappedResponse ww) {
Throwable cause = ww.getCause();
StringBuilder sb = new StringBuilder();
Expand Down
Loading