From 694e510301286b3a30fa9234288c7c6795a013a4 Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Mon, 26 Sep 2022 18:03:37 +0200 Subject: [PATCH 01/11] allow slash in check permissions api request --- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index ef08444af69..5e80f88d6eb 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -58,6 +58,7 @@ import java.io.InputStream; import java.io.StringReader; +import java.net.URLDecoder; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; @@ -1317,7 +1318,7 @@ public Response convertUserFromBcryptToSha1(String json) { } - @Path("permissions/{dvo}") + @Path("permissions/{dvo:.+}") @GET public Response findPermissonsOn(@PathParam("dvo") String dvo) { try { From d57e749ed7ba945175f0dab263d8b469f8a5586f Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Tue, 27 Sep 2022 10:07:07 +0200 Subject: [PATCH 02/11] added findDatasetOrDie lookup method in find permissions api --- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 5e80f88d6eb..137403e0e89 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1318,13 +1318,16 @@ public Response convertUserFromBcryptToSha1(String json) { } - @Path("permissions/{dvo:.+}") + @Path("permissions/{dvo}") @GET public Response findPermissonsOn(@PathParam("dvo") String dvo) { try { DvObject dvObj = findDvo(dvo); if (dvObj == null) { - return notFound("DvObject " + dvo + " not found"); + dvObj = findDatasetOrDie(dvo); + if (dvObj == null) { + return notFound("DvObject " + dvo + " not found"); + } } try { User aUser = findUserOrDie(); From 850f4c67c8937166beacca96d8eb5644de14a01f Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Wed, 28 Sep 2022 11:10:23 +0200 Subject: [PATCH 03/11] added a note on listing permissions on a dataset using a persistentId --- doc/sphinx-guides/source/api/native-api.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 93e1c36f179..be9e625fa7c 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -3808,6 +3808,17 @@ List permissions a user (based on API Token used) has on a Dataverse collection The ``$identifier`` can be a Dataverse collection alias or database id or a dataset persistent ID or database id. +.. note:: Datasets can be selected using persistent identifiers. This is done by passing the constant ``:persistentId`` where the numeric id of the dataset is expected, and then passing the actual persistent id as a query parameter with the name ``persistentId``. + +Example: List permissions a user (based on API Token used) has on a dataset whose DOI is *10.5072/FK2/J8SJZB*: + +.. code-block:: bash + + export SERVER_URL=https://demo.dataverse.org + export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/J8SJZB + + curl -H "X-Dataverse-key:$API_TOKEN" $SERVER_URL/api/admin/permissions/:persistentId?persistentId=$PERSISTENT_IDENTIFIER + Show Role Assignee ~~~~~~~~~~~~~~~~~~ From 9430e27d5973f281103caace950188a6784730f3 Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Tue, 19 Sep 2023 10:55:03 +0200 Subject: [PATCH 04/11] findPermissionsOn improvements --- .../iq/dataverse/api/AbstractApiBean.java | 19 +++++++++++------- .../edu/harvard/iq/dataverse/api/Admin.java | 20 +++++++------------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java index 0a0861fa1c9..4b27d479552 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java @@ -71,6 +71,7 @@ import jakarta.persistence.NoResultException; import jakarta.persistence.PersistenceContext; import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.core.*; import jakarta.ws.rs.core.Response.ResponseBuilder; @@ -526,16 +527,20 @@ protected DvObject findDvo( Long id ) { * with that alias. If that fails, tries to get a {@link Dataset} with that global id. * @param id a value identifying the DvObject, either numeric of textual. * @return A DvObject, or {@code null} + * @throws WrappedResponse */ - protected DvObject findDvo( String id ) { - if ( isNumeric(id) ) { - return findDvo( Long.valueOf(id)) ; + @NotNull + protected DvObject findDvo(@NotNull final String id) throws WrappedResponse { + DvObject d = null; + if (isNumeric(id)) { + d = findDvo(Long.valueOf(id)); } else { - Dataverse d = dataverseSvc.findByAlias(id); - return ( d != null ) ? - d : datasetSvc.findByGlobalId(id); - + d = dataverseSvc.findByAlias(id); + } + if (d == null) { + return findDatasetOrDie(id); } + return d; } protected T failIfNull( T t, String errorMessage ) throws WrappedResponse { diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 968e6f197e8..199410bf547 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -64,7 +64,6 @@ import java.io.InputStream; import java.io.StringReader; -import java.net.URLDecoder; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; @@ -1331,22 +1330,17 @@ public Response convertUserFromBcryptToSha1(String json) { @Path("permissions/{dvo}") @AuthRequired @GET - public Response findPermissonsOn(@Context ContainerRequestContext crc, @PathParam("dvo") String dvo) { + public Response findPermissonsOn(@Context final ContainerRequestContext crc, @PathParam("dvo") final String dvo) { try { - DvObject dvObj = findDvo(dvo); - if (dvObj == null) { - dvObj = findDatasetOrDie(dvo); - if (dvObj == null) { - return notFound("DvObject " + dvo + " not found"); - } - } - User aUser = getRequestUser(crc); - JsonObjectBuilder bld = Json.createObjectBuilder(); + final DvObject dvObj = findDvo(dvo); + final User aUser = getRequestUser(crc); + final JsonObjectBuilder bld = Json.createObjectBuilder(); bld.add("user", aUser.getIdentifier()); bld.add("permissions", json(permissionSvc.permissionsFor(createDataverseRequest(aUser), dvObj))); return ok(bld); - - } catch (Exception e) { + } catch (WrappedResponse r) { + return r.getResponse(); + } catch (Exception e) { logger.log(Level.SEVERE, "Error while testing permissions", e); return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); } From 9adfe84a8dd0b5674b2efe7406c7755ebbfb4b49 Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Tue, 19 Sep 2023 10:58:47 +0200 Subject: [PATCH 05/11] code format -> removed tabs, etc. --- .../iq/dataverse/api/AbstractApiBean.java | 11 ++++--- .../edu/harvard/iq/dataverse/api/Admin.java | 32 +++++++++---------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java index 4b27d479552..4e0b8fccae8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java @@ -523,14 +523,17 @@ protected DvObject findDvo( Long id ) { /** * Tries to find a DvObject. If the passed id can be interpreted as a number, - * it tries to get the DvObject by its id. Else, it tries to get a {@link Dataverse} - * with that alias. If that fails, tries to get a {@link Dataset} with that global id. + * it tries to get the DvObject by its id. Else, it tries to get a + * {@link Dataverse} + * with that alias. If that fails, tries to get a {@link Dataset} with that + * global id. + * * @param id a value identifying the DvObject, either numeric of textual. * @return A DvObject, or {@code null} * @throws WrappedResponse */ @NotNull - protected DvObject findDvo(@NotNull final String id) throws WrappedResponse { + protected DvObject findDvo(@NotNull final String id) throws WrappedResponse { DvObject d = null; if (isNumeric(id)) { d = findDvo(Long.valueOf(id)); @@ -541,7 +544,7 @@ protected DvObject findDvo(@NotNull final String id) throws WrappedResponse { return findDatasetOrDie(id); } return d; - } + } protected T failIfNull( T t, String errorMessage ) throws WrappedResponse { if ( t != null ) return t; diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 199410bf547..848cb950b7d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1327,24 +1327,24 @@ public Response convertUserFromBcryptToSha1(String json) { } - @Path("permissions/{dvo}") - @AuthRequired - @GET - public Response findPermissonsOn(@Context final ContainerRequestContext crc, @PathParam("dvo") final String dvo) { - try { - final DvObject dvObj = findDvo(dvo); - final User aUser = getRequestUser(crc); - final JsonObjectBuilder bld = Json.createObjectBuilder(); - bld.add("user", aUser.getIdentifier()); - bld.add("permissions", json(permissionSvc.permissionsFor(createDataverseRequest(aUser), dvObj))); - return ok(bld); - } catch (WrappedResponse r) { + @Path("permissions/{dvo}") + @AuthRequired + @GET + public Response findPermissonsOn(@Context final ContainerRequestContext crc, @PathParam("dvo") final String dvo) { + try { + final DvObject dvObj = findDvo(dvo); + final User aUser = getRequestUser(crc); + final JsonObjectBuilder bld = Json.createObjectBuilder(); + bld.add("user", aUser.getIdentifier()); + bld.add("permissions", json(permissionSvc.permissionsFor(createDataverseRequest(aUser), dvObj))); + return ok(bld); + } catch (WrappedResponse r) { return r.getResponse(); } catch (Exception e) { - logger.log(Level.SEVERE, "Error while testing permissions", e); - return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } + logger.log(Level.SEVERE, "Error while testing permissions", e); + return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); + } + } @Path("assignee/{idtf}") @GET From d31596addb40e5245083350879c940f6e48921fb Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Tue, 19 Sep 2023 11:01:20 +0200 Subject: [PATCH 06/11] removed newline --- .../java/edu/harvard/iq/dataverse/api/AbstractApiBean.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java index 4e0b8fccae8..105efd6b740 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java @@ -523,8 +523,7 @@ protected DvObject findDvo( Long id ) { /** * Tries to find a DvObject. If the passed id can be interpreted as a number, - * it tries to get the DvObject by its id. Else, it tries to get a - * {@link Dataverse} + * it tries to get the DvObject by its id. Else, it tries to get a {@link Dataverse} * with that alias. If that fails, tries to get a {@link Dataset} with that * global id. * From fad1c825fc2d1305c16437b4cb366dedef79c455 Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Tue, 19 Sep 2023 11:02:01 +0200 Subject: [PATCH 07/11] removed added newlines --- .../java/edu/harvard/iq/dataverse/api/AbstractApiBean.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java index 105efd6b740..b548a7168fa 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java @@ -524,9 +524,7 @@ protected DvObject findDvo( Long id ) { /** * Tries to find a DvObject. If the passed id can be interpreted as a number, * it tries to get the DvObject by its id. Else, it tries to get a {@link Dataverse} - * with that alias. If that fails, tries to get a {@link Dataset} with that - * global id. - * + * with that alias. If that fails, tries to get a {@link Dataset} with that global id. * @param id a value identifying the DvObject, either numeric of textual. * @return A DvObject, or {@code null} * @throws WrappedResponse From 4857a888a784ffd0a568588d2ec2b71a8fe73702 Mon Sep 17 00:00:00 2001 From: Steven Winship <39765413+stevenwinship@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:15:50 -0400 Subject: [PATCH 08/11] added isReleased to GET Dataverse reponse --- .../java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java | 1 + src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) 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 a0278d1a60f..38dab63384f 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 @@ -292,6 +292,7 @@ public static JsonObjectBuilder json(Dataverse dv, Boolean hideEmail, Boolean re if (dv.getFilePIDsEnabled() != null) { bld.add("filePIDsEnabled", dv.getFilePIDsEnabled()); } + bld.add("isReleased", dv.isReleased()); return bld; } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java index d7f7ff39cbd..0311bfde07e 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java @@ -413,12 +413,13 @@ public void testMoveDataverse() { Response superuserResponse = UtilIT.makeSuperUser(username); Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken); - createDataverseResponse.prettyPrint(); + assertTrue(createDataverseResponse.prettyPrint().contains("isReleased\": false")); String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse); Integer dataverseId = UtilIT.getDataverseIdFromResponse(createDataverseResponse); Response publishDataverse = UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken);//.publishDataverseViaSword(dataverseAlias, apiToken); assertEquals(200, publishDataverse.getStatusCode()); + assertTrue(publishDataverse.prettyPrint().contains("isReleased\": true")); Response createDataverseResponse2 = UtilIT.createRandomDataverse(apiToken); createDataverseResponse2.prettyPrint(); From 19a8c3d35b4bc87e005b403858f232ebb7ccc22c Mon Sep 17 00:00:00 2001 From: Steven Winship <39765413+stevenwinship@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:29:39 -0400 Subject: [PATCH 09/11] add release note --- ...dd-isreleased-to-get-dataverse-response.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/release-notes/10491-add-isreleased-to-get-dataverse-response.md diff --git a/doc/release-notes/10491-add-isreleased-to-get-dataverse-response.md b/doc/release-notes/10491-add-isreleased-to-get-dataverse-response.md new file mode 100644 index 00000000000..5293c7267d0 --- /dev/null +++ b/doc/release-notes/10491-add-isreleased-to-get-dataverse-response.md @@ -0,0 +1,22 @@ +The Dataverse object returned by /api/dataverses has been extended to include "isReleased": {boolean}. +```javascript +{ + "status": "OK", + "data": { + "id": 32, + "alias": "dv6f645bb5", + "name": "dv6f645bb5", + "dataverseContacts": [ + { + "displayOrder": 0, + "contactEmail": "54180268@mailinator.com" + } + ], + "permissionRoot": true, + "dataverseType": "UNCATEGORIZED", + "ownerId": 1, + "creationDate": "2024-04-12T18:05:59Z", + "isReleased": true + } +} +``` \ No newline at end of file From b67c731dadf6a999ae65c3de6696b3b48c206bde Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Fri, 19 Apr 2024 16:32:56 +0200 Subject: [PATCH 10/11] added missing double quotes --- doc/sphinx-guides/source/api/native-api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 3bf45066c77..2cc1ddbe813 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5622,7 +5622,7 @@ Example: List permissions a user (based on API Token used) has on a dataset whos export SERVER_URL=https://demo.dataverse.org export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/J8SJZB - curl -H "X-Dataverse-key:$API_TOKEN" $SERVER_URL/api/admin/permissions/:persistentId?persistentId=$PERSISTENT_IDENTIFIER + curl -H "X-Dataverse-key:$API_TOKEN" "$SERVER_URL/api/admin/permissions/:persistentId?persistentId=$PERSISTENT_IDENTIFIER" Show Role Assignee ~~~~~~~~~~~~~~~~~~ From 4a64ad0efa799a9cfccff5a4a1304e0fc3d8afed Mon Sep 17 00:00:00 2001 From: Juan Pablo Tosca Villanueva <142103991+jp-tosca@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:16:22 -0400 Subject: [PATCH 11/11] Update native-api.rst --- doc/sphinx-guides/source/api/native-api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 67f3a0e17b8..30ff90e0179 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5879,7 +5879,7 @@ Superusers can add a new license by posting a JSON file adapted from this exampl .. code-block:: bash export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - curl -X POST -H 'Content-Type: application/json' -H "X-Dataverse-key:$API_TOKEN" --data-binary @add-license.json "$SERVER_URL/api/licenses" + curl -X POST -H 'Content-Type: application/json' -H "X-Dataverse-key:$API_TOKEN" --upload-file add-license.json "$SERVER_URL/api/licenses" Superusers can change whether an existing license is active (usable for new dataset versions) or inactive (only allowed on already-published versions) specified by the license ``$ID``: