Skip to content

Commit 9733e5e

Browse files
Merge branch 'develop' into 11670-notification-of-moved-datasets
2 parents 3e44d76 + 53bff4c commit 9733e5e

File tree

51 files changed

+2471
-122
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2471
-122
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Role Assignment History Tracking
2+
3+
Dataverse can now track the history of role assignments, allowing administrators to see who assigned or revoked roles, when these actions occurred, and which roles were involved. This feature helps with auditing and understanding permission changes over time.
4+
5+
## Key components of this feature:
6+
7+
- **Feature Flag**: The functionality can be enabled/disabled via the `ROLE_ASSIGNMENT_HISTORY` feature flag (default is `off`)
8+
- **UI Integration**: New history panels on permission management pages showing the complete history of role assignments/revocations
9+
- **CSV Export**: Administrators can download the role assignment history for a given collection or dataset (or files in a dataset) as a CSV file directly from the new panels
10+
- **API Access**: New API endpoints provide access to role assignment history in both JSON and CSV formats:
11+
- `/api/dataverses/{identifier}/assignments/history`
12+
- `/api/datasets/{identifier}/assignments/history`
13+
- `/api/datasets/{identifier}/files/assignments/history`
14+
15+
All return JSON by default but will return an internationalized CSV if an `Accept: text/csv` header is adde
16+
17+
For more information, see #11612
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## New Endpoint: `/datasets/{id}/access`
2+
3+
A new endpoint has been implemented to manage dataset terms of access for restricted files.
4+
5+
### Functionality
6+
- Updates the terms of access for a dataset by applying it to the draft version.
7+
- If no draft exists, a new one is automatically created.
8+
9+
### Usage
10+
11+
**Custom Terms of Access** – Provide a JSON body with the `customTermsOfAccess` object.
12+
- All fields are optional **except** if there are restricted files in which case `fileAccessRequest` must be set to true or `termsOfAccess` must be provided.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
### Fixed: Permissions for `/{identifier}/templates` endpoint
2+
3+
The `/{identifier}/templates` endpoint previously required **`editDataverse`** permissions to retrieve the list of dataverse templates.
4+
5+
This has been corrected: the endpoint now requires **`addDataset`** permissions instead.
6+
7+
**Impact:**
8+
- The endpoint now works in scenarios such as the **Create Dataset form** in the SPA UI, without needing unnecessary elevated permissions.
9+
10+
Related issues: #11796

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

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,78 @@ The fully expanded example above (without environment variables) looks like this
14851485
14861486
curl -H "X-Dataverse-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X POST "https://demo.dataverse.org/api/dataverses/1/templates" --upload-file dataverse-template.json
14871487
1488+
1489+
Dataverse Role Assignment History
1490+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1491+
1492+
Get the history of role assignments for a collection. This API call returns a list of role assignments and revocations for the specified dataset.
1493+
1494+
.. code-block:: bash
1495+
1496+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1497+
export SERVER_URL=https://demo.dataverse.org
1498+
export ID=1
1499+
1500+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/dataverses/$ID/assignments/history"
1501+
1502+
The fully expanded example above (without environment variables) looks like this:
1503+
1504+
.. code-block:: bash
1505+
1506+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/dataverses/3/assignments/history"
1507+
1508+
You can also use the collection alias instead of the numeric id:
1509+
1510+
.. code-block:: bash
1511+
1512+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1513+
export SERVER_URL=https://demo.dataverse.org
1514+
export DV_ALIAS=dvAlias
1515+
1516+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/dataverses/$DV_ALIAS/assignments/history"
1517+
1518+
The fully expanded example above (without environment variables) looks like this:
1519+
1520+
.. code-block:: bash
1521+
1522+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/dvAlias/assignments/history"
1523+
1524+
The response is a JSON array of role assignment history entries with the following structure for each entry:
1525+
1526+
.. code-block:: json
1527+
1528+
{
1529+
"definedOn": "1",
1530+
"assigneeIdentifier": "@user1",
1531+
"roleName": "Admin",
1532+
"assignedBy": "@dataverseAdmin",
1533+
"assignedAt": "2023-01-01T12:00:00Z",
1534+
"revokedBy": null,
1535+
"revokedAt": null
1536+
}
1537+
1538+
For revoked assignments, the "revokedBy" and "revokedAt" fields will contain values instead of null.
1539+
1540+
To retrieve the history in CSV format, change the Accept header to "text/csv":
1541+
1542+
.. code-block:: bash
1543+
1544+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1545+
export SERVER_URL=https://demo.dataverse.org
1546+
export ID=3
1547+
1548+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/dataverses/$ID/assignments/history"
1549+
1550+
The fully expanded example above (without environment variables) looks like this:
1551+
1552+
.. code-block:: bash
1553+
1554+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/dataverses/3/assignments/history"
1555+
1556+
The CSV response has column headers mirroring the JSON entries. They are internationalized (when internationalization is configured).
1557+
1558+
Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`).
1559+
14881560
Datasets
14891561
--------
14901562

@@ -2298,6 +2370,46 @@ For these deletes your JSON file must include an exact match of those dataset fi
22982370

22992371
.. _publish-dataset-api:
23002372

2373+
Update Dataset Terms of Access
2374+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2375+
2376+
Updates the terms of access for the restricted files of a dataset by applying it to the draft version, or by creating a draft if none exists.
2377+
2378+
2379+
To define custom terms of access, provide a JSON body with the following properties. All fields within ``customTermsOfAccess`` are optional, except if there are restricted files in your dataset then ``fileAccessRequest`` must be set to true or ``termsOfAccess`` must be provided:
2380+
2381+
.. code-block:: json
2382+
2383+
[
2384+
{
2385+
"customTermsOfAccess": {
2386+
"fileAccessRequest": true,
2387+
"termsOfAccess": "Your terms of access for restricted files",
2388+
"dataAccessPlace": "Your data access place",
2389+
"originalArchive": "Your original archive",
2390+
"availabilityStatus": "Your availability status",
2391+
"contactForAccess": "Your contact for access",
2392+
"sizeOfCollection": "Your size of collection",
2393+
"studyCompletion": "Your study completion"
2394+
}
2395+
}
2396+
]
2397+
2398+
.. code-block:: bash
2399+
2400+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2401+
export SERVER_URL=https://demo.dataverse.org
2402+
export ID=3
2403+
export FILE_PATH=access.json
2404+
2405+
curl -H "X-Dataverse-key:$API_TOKEN" -X PUT "$SERVER_URL/api/datasets/$ID/access" -H "Content-type:application/json" --upload-file $FILE_PATH
2406+
2407+
The fully expanded example above (without environment variables) looks like this:
2408+
2409+
.. code-block:: bash
2410+
2411+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X PUT "https://demo.dataverse.org/api/datasets/3/access" -H "Content-type:application/json" --upload-file access.json
2412+
23012413
Publish a Dataset
23022414
~~~~~~~~~~~~~~~~~
23032415

@@ -4115,6 +4227,135 @@ Upon success, the API will return a JSON response with a success message and the
41154227
The API call will report a 400 (BAD REQUEST) error if any of the files specified do not exist or are not in the latest version of the specified dataset.
41164228
The ``fileIds`` in the JSON payload should be an array of file IDs that you want to delete from the dataset.
41174229
4230+
.. _api-dataset-role-assignment-history:
4231+
4232+
Dataset Role Assignment History
4233+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4234+
4235+
Get the history of role assignments for a dataset. This API call returns a list of role assignments and revocations for the specified dataset.
4236+
4237+
.. code-block:: bash
4238+
4239+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4240+
export SERVER_URL=https://demo.dataverse.org
4241+
export ID=3
4242+
4243+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/$ID/assignments/history"
4244+
4245+
The fully expanded example above (without environment variables) looks like this:
4246+
4247+
.. code-block:: bash
4248+
4249+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/3/assignments/history"
4250+
4251+
You can also use the persistent identifier instead of the numeric id:
4252+
4253+
.. code-block:: bash
4254+
4255+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4256+
export SERVER_URL=https://demo.dataverse.org
4257+
export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/ABCDEF
4258+
4259+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/:persistentId/assignments/history?persistentId=$PERSISTENT_IDENTIFIER"
4260+
4261+
The fully expanded example above (without environment variables) looks like this:
4262+
4263+
.. code-block:: bash
4264+
4265+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/:persistentId/assignments/history?persistentId=doi:10.5072/FK2/ABCDEF"
4266+
4267+
The response is a JSON array of role assignment history entries with the following structure for each entry:
4268+
4269+
.. code-block:: json
4270+
4271+
{
4272+
"definedOn": "3",
4273+
"assigneeIdentifier": "@user1",
4274+
"roleName": "Admin",
4275+
"assignedBy": "@dataverseAdmin",
4276+
"assignedAt": "2023-01-01T12:00:00Z",
4277+
"revokedBy": null,
4278+
"revokedAt": null
4279+
}
4280+
4281+
For revoked assignments, the "revokedBy" and "revokedAt" fields will contain values instead of null.
4282+
4283+
To retrieve the history in CSV format, change the Accept header to "text/csv":
4284+
4285+
.. code-block:: bash
4286+
4287+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4288+
export SERVER_URL=https://demo.dataverse.org
4289+
export ID=3
4290+
4291+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/datasets/$ID/assignments/history"
4292+
4293+
The fully expanded example above (without environment variables) looks like this:
4294+
4295+
.. code-block:: bash
4296+
4297+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/datasets/3/assignments/history"
4298+
4299+
The CSV response has column headers mirroring the JSON entries. They are internationalized (when internationalization is configured).
4300+
4301+
Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`).
4302+
4303+
Dataset Files Role Assignment History
4304+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4305+
4306+
Get the history of role assignments for the files in a dataset. This API call returns a list of role assignments and revocations for all files in the specified dataset.
4307+
4308+
.. code-block:: bash
4309+
4310+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4311+
export SERVER_URL=https://demo.dataverse.org
4312+
export ID=3
4313+
4314+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/$ID/files/assignments/history"
4315+
4316+
The fully expanded example above (without environment variables) looks like this:
4317+
4318+
.. code-block:: bash
4319+
4320+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/3/files/assignments/history"
4321+
4322+
You can also use the persistent identifier instead of the numeric id:
4323+
4324+
.. code-block:: bash
4325+
4326+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4327+
export SERVER_URL=https://demo.dataverse.org
4328+
export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/ABCDEF
4329+
4330+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/:persistentId/files/assignments/history?persistentId=$PERSISTENT_IDENTIFIER"
4331+
4332+
The fully expanded example above (without environment variables) looks like this:
4333+
4334+
.. code-block:: bash
4335+
4336+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/:persistentId/files/assignments/history?persistentId=doi:10.5072/FK2/ABCDEF"
4337+
4338+
The JSON response for this call is the same as for the /api/datasets/{id}/assignments/history call above with the exception that definedOn will be a comma separated list of one or more file ids.
4339+
4340+
To retrieve the history in CSV format, change the Accept header to "text/csv":
4341+
4342+
.. code-block:: bash
4343+
4344+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
4345+
export SERVER_URL=https://demo.dataverse.org
4346+
export ID=3
4347+
4348+
curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/datasets/files/$ID/assignments/history"
4349+
4350+
The fully expanded example above (without environment variables) looks like this:
4351+
4352+
.. code-block:: bash
4353+
4354+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/datasets/3/files/assignments/history"
4355+
4356+
The CSV response for this call is the same as for the /api/datasets/{id}/assignments/history call above with the exception that definedOn will be a comma separated list of one or more file ids.
4357+
4358+
Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`).
41184359
41194360
Files
41204361
-----

doc/sphinx-guides/source/installation/config.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,6 +3821,9 @@ please find all known feature flags below. Any of these flags can be activated u
38213821
* - enable-pid-failure-log
38223822
- Turns on creation of a monthly log file (logs/PIDFailures_<yyyy-MM>.log) showing failed requests for dataset/file PIDs. Can be used directly or with scripts at https://github.com/gdcc/dataverse-recipes/python/pid_reports to alert admins.
38233823
- ``Off``
3824+
* - role-assignment-history
3825+
- Turns on tracking/display of role assignments and revocations for collections, datasets, and files
3826+
- ``Off``
38243827

38253828
**Note:** Feature flags can be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
38263829
``DATAVERSE_FEATURE_XXX`` (e.g. ``DATAVERSE_FEATURE_API_SESSION_AUTH=1``). These environment variables can be set in your shell before starting Payara. If you are using :doc:`Docker for development </container/dev-usage>`, you can set them in the `docker compose <https://docs.docker.com/compose/environment-variables/set-environment-variables/>`_ file.

doc/sphinx-guides/source/user/dataverse-management.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,16 @@ Clicking on Permissions will bring you to this page:
119119

120120
|image3|
121121

122-
When you access a Dataverse collection's permissions page, you will see three sections:
122+
When you access a Dataverse collection's permissions page, you will see three or four sections:
123123

124124
**Permissions:** Here you can decide the requirements that determine which types of users can add datasets and sub Dataverse collections to your Dataverse collection, and what permissions they'll be granted when they do so.
125125

126126
**Users/Groups:** Here you can assign roles to specific users or groups, determining which actions they are permitted to take on your Dataverse collection. You can also reference a list of all users who have roles assigned to them for your Dataverse collection and remove their roles if you please.
127127

128128
**Roles:** Here you can reference a full list of roles that can be assigned to users of your Dataverse collection. Each role lists the permissions that it offers.
129129

130+
**Role Assignment History** If enabled, you'll be able to see the history of when roles have been assigned and revoked and by whom.
131+
130132
Please note that even on a newly created Dataverse collection, you may see user and groups have already been granted role(s) if your installation has ``:InheritParentRoleAssignments`` set. For more on this setting, see the :doc:`/installation/config` section of the Installation Guide.
131133

132134
Setting Access Configurations

0 commit comments

Comments
 (0)