From 25cf3ff5c54fe8d3ee767688e39ff1527d7ce0d0 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Wed, 27 Mar 2024 18:29:53 -0300 Subject: [PATCH 01/21] 9887: Adding new endpoint to make superuser call idempotent --- .../edu/harvard/iq/dataverse/api/Admin.java | 32 +++++++++++++++---- .../edu/harvard/iq/dataverse/api/AdminIT.java | 14 +++++++- .../edu/harvard/iq/dataverse/api/RolesIT.java | 2 +- .../edu/harvard/iq/dataverse/api/UtilIT.java | 5 +++ 4 files changed, 44 insertions(+), 9 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 d098c2fe16a..86b4f5ee679 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1035,15 +1035,33 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") .setInfo(identifier); try { - AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); - if (user.isDeactivated()) { - return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); - } + final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); + return changeSuperUserStatus(user, !user.isSuperuser()); + } catch (Exception e) { + alr.setActionResult(ActionLogRecord.Result.InternalError); + alr.setInfo(alr.getInfo() + "// " + e.getMessage()); + return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); + } finally { + actionLogSvc.log(alr); + } + } - user.setSuperuser(!user.isSuperuser()); + private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperuser) { + if (user.isDeactivated()) { + return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); + } + user.setSuperuser(isSuperuser); + return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") + + " as a superuser."); + } - return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") - + " as a superuser."); + @Path("superuser/{identifier}") + @PUT + public Response changeSuperUserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { + ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") + .setInfo(identifier + ":" + isSuperUser); + try { + return changeSuperUserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index b9bf09cfe68..bb5c2ba34bd 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; - +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.util.Map; import java.util.UUID; import java.util.logging.Logger; @@ -895,4 +896,15 @@ private String createTestNonSuperuserApiToken() { createUserResponse.then().assertThat().statusCode(OK.getStatusCode()); return UtilIT.getApiTokenFromResponse(createUserResponse); } + + @ParameterizedTest + @ValueSource(booleans={true,false}) + public void testChangeSuperUserStatus(Boolean status) { + Response createUser = UtilIT.createRandomUser(); + createUser.then().assertThat().statusCode(OK.getStatusCode()); + String username = UtilIT.getUsernameFromResponse(createUser); + Response toggleSuperuser = UtilIT.changeSuperUserStatus(username, status); + toggleSuperuser.then().assertThat() + .statusCode(OK.getStatusCode()); + } } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java index 8b5ac917dea..d15fda3a1a1 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java @@ -18,7 +18,7 @@ */ public class RolesIT { - private static final Logger logger = Logger.getLogger(AdminIT.class.getCanonicalName()); + private static final Logger logger = Logger.getLogger(RolesIT.class.getCanonicalName()); @BeforeAll public static void setUp() { diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index 080ca0c43e9..9a409ba97fb 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1525,6 +1525,11 @@ static Response makeSuperUser(String username) { return response; } + static Response changeSuperUserStatus(String username, Boolean isSuperUser) { + Response response = given().body(isSuperUser).put("/api/admin/superuser/" + username); + return response; + } + static Response reindexDataset(String persistentId) { Response response = given() .get("/api/admin/index/dataset?persistentId=" + persistentId); From 16ed8cc2255195c88375aa1e380c846f60d8706d Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Thu, 28 Mar 2024 19:11:27 -0300 Subject: [PATCH 02/21] 9887: Adding documentation and deprecation tag --- .../9887-new-superuser-status-endpoint.md | 1 + doc/sphinx-guides/source/api/native-api.rst | 23 ++++++++++++++++++- .../edu/harvard/iq/dataverse/api/Admin.java | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 doc/release-notes/9887-new-superuser-status-endpoint.md diff --git a/doc/release-notes/9887-new-superuser-status-endpoint.md b/doc/release-notes/9887-new-superuser-status-endpoint.md new file mode 100644 index 00000000000..4069d3cc04b --- /dev/null +++ b/doc/release-notes/9887-new-superuser-status-endpoint.md @@ -0,0 +1 @@ +Adding a new endpoint to make supersuser status change calls idempotent. Also Deprecating and renaming the old API. \ No newline at end of file diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 144e3ac8e5e..7fed31c5438 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5306,13 +5306,34 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. -Make User a SuperUser +Toggle User superuser powers ~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: POST http://$SERVER/api/admin/superuser/$identifier +.. note:: this endpoint is deprecated. Use the change superuser status endpoint + +.. _change-superuser-status: + +Change superuser status +~~~~~~~~~~~~~~~~~~~~~ +Changes a user superuser power status with a boolean value + +.. code-block:: bash + + export SERVER_URL=http://localhost:8080 + export USERNAME=jdoe + export IS_SUPERUSER=true + curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" --data "$IS_SUPERUSER" + +The fully expanded example above (without environment variables) looks like this: + +.. code-block:: bash + + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" --data "true" + .. _delete-a-user: Delete a User 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 86b4f5ee679..95dd8899978 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1030,6 +1030,7 @@ public Response deleteRole(@Context ContainerRequestContext crc, @PathParam("id" } @Path("superuser/{identifier}") + @Deprecated @POST public Response toggleSuperuser(@PathParam("identifier") String identifier) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") From 5570bec5a2559e5607073cb4b01ac1c104016c58 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Thu, 28 Mar 2024 19:20:16 -0300 Subject: [PATCH 03/21] 9887: Fixing documentation --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 7fed31c5438..eec5c17a52d 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5307,7 +5307,7 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. Toggle User superuser powers -~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: @@ -5318,7 +5318,7 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou .. _change-superuser-status: Change superuser status -~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~ Changes a user superuser power status with a boolean value .. code-block:: bash From e1bed704e0ff256f3d4ea8547f038ebe38e080cb Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:51:30 -0300 Subject: [PATCH 04/21] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index eec5c17a52d..48d49ed40ba 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5306,8 +5306,8 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. -Toggle User superuser powers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Toggle Superuser Status +~~~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: From e5aca34e452bd8ce1f8c8e5769d96e7b8883b214 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:51:44 -0300 Subject: [PATCH 05/21] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/native-api.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 48d49ed40ba..5205cccea5f 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5317,9 +5317,10 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou .. _change-superuser-status: -Change superuser status -~~~~~~~~~~~~~~~~~~~~~~~ -Changes a user superuser power status with a boolean value +Set Superuser Status +~~~~~~~~~~~~~~~~~~~~ + +Specify the superuser status of a user with a boolean value. .. code-block:: bash From 4444c0a4d9b757f6f6a4a5ef5e85e455c5ba98fc Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:52:25 -0300 Subject: [PATCH 06/21] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- 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 5205cccea5f..8808c0b5400 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5313,7 +5313,7 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou POST http://$SERVER/api/admin/superuser/$identifier -.. note:: this endpoint is deprecated. Use the change superuser status endpoint +.. note:: This endpoint is deprecated. Use the set superuser status endpoint instead. .. _change-superuser-status: From 7008b350c28b67cafa8d2db8954532a1426e8971 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:52:57 -0300 Subject: [PATCH 07/21] Update doc/release-notes/9887-new-superuser-status-endpoint.md Co-authored-by: Philip Durbin --- doc/release-notes/9887-new-superuser-status-endpoint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/9887-new-superuser-status-endpoint.md b/doc/release-notes/9887-new-superuser-status-endpoint.md index 4069d3cc04b..01b1f539f7a 100644 --- a/doc/release-notes/9887-new-superuser-status-endpoint.md +++ b/doc/release-notes/9887-new-superuser-status-endpoint.md @@ -1 +1 @@ -Adding a new endpoint to make supersuser status change calls idempotent. Also Deprecating and renaming the old API. \ No newline at end of file +The existing API endpoint for toggling the superuser status of a user has been deprecated in favor of a new API endpoint that allows you to explicitly and idempotently set the status as true or false. For details, see [the guides](https://dataverse-guide--10440.org.readthedocs.build/en/10440/api/native-api.html), #9887 and #10440. \ No newline at end of file From 532e7f0e738544413219d730f7763f5c59230623 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 14:12:22 -0300 Subject: [PATCH 08/21] 9887: code review --- doc/sphinx-guides/source/api/changelog.rst | 5 +++++ doc/sphinx-guides/source/api/native-api.rst | 2 +- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 8 ++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/sphinx-guides/source/api/changelog.rst b/doc/sphinx-guides/source/api/changelog.rst index 025a2069d6e..5e55ff46235 100644 --- a/doc/sphinx-guides/source/api/changelog.rst +++ b/doc/sphinx-guides/source/api/changelog.rst @@ -7,6 +7,11 @@ This API changelog is experimental and we would love feedback on its usefulness. :local: :depth: 1 +v6.3 +---- + +- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT,which we can specifically set the superuser status in the body. + v6.2 ---- diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 8808c0b5400..f51eaf31da5 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5333,7 +5333,7 @@ The fully expanded example above (without environment variables) looks like this .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" --data "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d "true" .. _delete-a-user: 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 95dd8899978..1e463a7e19d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1037,7 +1037,7 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { .setInfo(identifier); try { final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); - return changeSuperUserStatus(user, !user.isSuperuser()); + return setSuperuserStatus(user, !user.isSuperuser()); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); @@ -1047,7 +1047,7 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { } } - private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperuser) { + private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) { if (user.isDeactivated()) { return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); } @@ -1058,11 +1058,11 @@ private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperus @Path("superuser/{identifier}") @PUT - public Response changeSuperUserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { + public Response setSuperuserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") .setInfo(identifier + ":" + isSuperUser); try { - return changeSuperUserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); + return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); From 74f6c4ac8802dadf9355ad9c4af5d3560255a5b2 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 15:19:13 -0300 Subject: [PATCH 09/21] Update doc/sphinx-guides/source/api/changelog.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/changelog.rst b/doc/sphinx-guides/source/api/changelog.rst index 5e55ff46235..4c2d332857b 100644 --- a/doc/sphinx-guides/source/api/changelog.rst +++ b/doc/sphinx-guides/source/api/changelog.rst @@ -10,7 +10,7 @@ This API changelog is experimental and we would love feedback on its usefulness. v6.3 ---- -- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT,which we can specifically set the superuser status in the body. +- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT, which we can specifically set the superuser status in the body. v6.2 ---- From 9577295f50df9094291cedfeb66af37fe6c0db2d Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 16:45:14 -0300 Subject: [PATCH 10/21] 9887: code review --- src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java | 2 +- src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index bb5c2ba34bd..32c417a4fae 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -899,7 +899,7 @@ private String createTestNonSuperuserApiToken() { @ParameterizedTest @ValueSource(booleans={true,false}) - public void testChangeSuperUserStatus(Boolean status) { + public void testSetSuperUserStatus(Boolean status) { Response createUser = UtilIT.createRandomUser(); createUser.then().assertThat().statusCode(OK.getStatusCode()); String username = UtilIT.getUsernameFromResponse(createUser); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index 9a409ba97fb..ab0cb4c2426 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1520,6 +1520,7 @@ static Response getMetadataBlockFromDatasetVersion(String persistentId, String v .get("/api/datasets/:persistentId/versions/" + DS_VERSION_LATEST_PUBLISHED + "/metadata/citation?persistentId=" + persistentId); } + @Deprecated static Response makeSuperUser(String username) { Response response = given().post("/api/admin/superuser/" + username); return response; From 12fe4cd002b19309fd92f43a214ba4049c2688e4 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 17:10:39 -0300 Subject: [PATCH 11/21] 9887: renaming function --- src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java | 2 +- src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index 32c417a4fae..44f062e8254 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -903,7 +903,7 @@ public void testSetSuperUserStatus(Boolean status) { Response createUser = UtilIT.createRandomUser(); createUser.then().assertThat().statusCode(OK.getStatusCode()); String username = UtilIT.getUsernameFromResponse(createUser); - Response toggleSuperuser = UtilIT.changeSuperUserStatus(username, status); + Response toggleSuperuser = UtilIT.setSuperuserStatus(username, status); toggleSuperuser.then().assertThat() .statusCode(OK.getStatusCode()); } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index ab0cb4c2426..dc503a92c0a 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1526,7 +1526,7 @@ static Response makeSuperUser(String username) { return response; } - static Response changeSuperUserStatus(String username, Boolean isSuperUser) { + static Response setSuperuserStatus(String username, Boolean isSuperUser) { Response response = given().body(isSuperUser).put("/api/admin/superuser/" + username); return response; } From 4788c104b6a2c9f94d1b2e1cc016836dd53b2ded Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Thu, 11 Apr 2024 22:13:19 -0300 Subject: [PATCH 12/21] Adding header to documentation --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 52e3948532e..5b2c0586d1c 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5433,13 +5433,13 @@ Specify the superuser status of a user with a boolean value. export SERVER_URL=http://localhost:8080 export USERNAME=jdoe export IS_SUPERUSER=true - curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" --data "$IS_SUPERUSER" + curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" -H "Content-Type: application/json" --data "$IS_SUPERUSER" The fully expanded example above (without environment variables) looks like this: .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -H "Content-Type: application/json" -d "true" .. _delete-a-user: From 0d9e8df20bc7ee2019735c546aab77a2cdf0ebaa Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 12 Apr 2024 11:19:39 -0300 Subject: [PATCH 13/21] Changing header to text/plain --- 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 5b2c0586d1c..958644f7515 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5439,7 +5439,7 @@ The fully expanded example above (without environment variables) looks like this .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -H "Content-Type: application/json" -d "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -H "Content-Type: text/plain" -d "true" .. _delete-a-user: From 6684ae62ee7392386dcce682510caa7d1730e9b2 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 12 Apr 2024 16:15:48 -0300 Subject: [PATCH 14/21] 9887: Changin body to string to allow empty Content-Type --- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 6 ++++-- 1 file changed, 4 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 1e463a7e19d..63249ddc151 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -17,6 +17,7 @@ import edu.harvard.iq.dataverse.DvObjectServiceBean; import edu.harvard.iq.dataverse.api.auth.AuthRequired; import edu.harvard.iq.dataverse.settings.JvmSettings; +import edu.harvard.iq.dataverse.util.StringUtil; import edu.harvard.iq.dataverse.validation.EMailValidator; import edu.harvard.iq.dataverse.EjbDataverseEngine; import edu.harvard.iq.dataverse.Template; @@ -1058,11 +1059,12 @@ private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) @Path("superuser/{identifier}") @PUT - public Response setSuperuserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { + //using string instead of boolean so user doesnt need to add Content type header in their request + public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperUser) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") .setInfo(identifier + ":" + isSuperUser); try { - return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); + return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), StringUtil.isTrue(isSuperUser)); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); From e3ecf8b846f09441961cad9c5b6cb3a60fba994d Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 12 Apr 2024 16:19:21 -0300 Subject: [PATCH 15/21] 9887: changing installation scrpt to sue new endpoint --- scripts/api/setup-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/api/setup-all.sh b/scripts/api/setup-all.sh index 5ddd9a35fdc..b7f962209e4 100755 --- a/scripts/api/setup-all.sh +++ b/scripts/api/setup-all.sh @@ -65,7 +65,7 @@ echo echo "Setting up the admin user (and as superuser)" adminResp=$(curl -s -H "Content-type:application/json" -X POST -d @"$SCRIPT_PATH"/data/user-admin.json "${DATAVERSE_URL}/api/builtin-users?password=$DV_SU_PASSWORD&key=burrito") echo "$adminResp" -curl -X POST "${DATAVERSE_URL}/api/admin/superuser/dataverseAdmin" +curl -X PUT "${DATAVERSE_URL}/api/admin/superuser/dataverseAdmin" -d "true" echo echo "Setting up the root dataverse" From a418b5814b74452bc43cfc9396b3b12c26bc7ccf Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 12 Apr 2024 16:31:28 -0300 Subject: [PATCH 16/21] 9887: Changin doc --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 958644f7515..ae1509c56f3 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5433,13 +5433,13 @@ Specify the superuser status of a user with a boolean value. export SERVER_URL=http://localhost:8080 export USERNAME=jdoe export IS_SUPERUSER=true - curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" -H "Content-Type: application/json" --data "$IS_SUPERUSER" + curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" -d "$IS_SUPERUSER" The fully expanded example above (without environment variables) looks like this: .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -H "Content-Type: text/plain" -d "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d "true" .. _delete-a-user: From 3f89c329bfe572b65901b248b7c639e5f206c975 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 12 Apr 2024 16:34:25 -0300 Subject: [PATCH 17/21] 9887: renaming variable --- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 6 +++--- 1 file changed, 3 insertions(+), 3 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 63249ddc151..e1e86adacc6 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1060,11 +1060,11 @@ private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) @Path("superuser/{identifier}") @PUT //using string instead of boolean so user doesnt need to add Content type header in their request - public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperUser) { + public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperuser) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") - .setInfo(identifier + ":" + isSuperUser); + .setInfo(identifier + ":" + isSuperuser); try { - return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), StringUtil.isTrue(isSuperUser)); + return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), StringUtil.isTrue(isSuperuser)); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); From 95ce8e0c39006451ab5b4fb736ddd84b4c7e9077 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 12 Apr 2024 16:41:11 -0400 Subject: [PATCH 18/21] tweak docs #9887 --- doc/sphinx-guides/source/api/changelog.rst | 2 +- doc/sphinx-guides/source/api/native-api.rst | 26 +++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/doc/sphinx-guides/source/api/changelog.rst b/doc/sphinx-guides/source/api/changelog.rst index abe42ba2e99..db994a629b3 100644 --- a/doc/sphinx-guides/source/api/changelog.rst +++ b/doc/sphinx-guides/source/api/changelog.rst @@ -10,7 +10,7 @@ This API changelog is experimental and we would love feedback on its usefulness. v6.3 ---- -- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT, which we can specifically set the superuser status in the body. +- **/api/admin/superuser/{identifier}**: The POST endpoint that toggles superuser status has been deprecated in favor of a new PUT endpoint that allows you to specify true or false. See :ref:`set-superuser-status`. v6.2 ---- diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index ae1509c56f3..26cca81e0d1 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5415,31 +5415,43 @@ This action changes the identifier of user johnsmith to jsmith. Toggle Superuser Status ~~~~~~~~~~~~~~~~~~~~~~~ -Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: +Toggle the superuser status of a user. - POST http://$SERVER/api/admin/superuser/$identifier +.. note:: This endpoint is deprecated as explained in :doc:`/api/changelog`. Please use the :ref:`set-superuser-status` endpoint instead. -.. note:: This endpoint is deprecated. Use the set superuser status endpoint instead. +.. code-block:: bash + + export SERVER_URL=http://localhost:8080 + export USERNAME=jdoe + curl -X POST "$SERVER_URL/api/admin/superuser/$USERNAME" -.. _change-superuser-status: +The fully expanded example above (without environment variables) looks like this: + +.. code-block:: bash + + curl -X POST "http://localhost:8080/api/admin/superuser/jdoe" + +.. _set-superuser-status: Set Superuser Status ~~~~~~~~~~~~~~~~~~~~ -Specify the superuser status of a user with a boolean value. +Specify the superuser status of a user with a boolean value (``true`` or ``false``). + +.. note:: See :ref:`curl-examples-and-environment-variables` if you are unfamiliar with the use of ``export`` below. .. code-block:: bash export SERVER_URL=http://localhost:8080 export USERNAME=jdoe export IS_SUPERUSER=true - curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" -d "$IS_SUPERUSER" + curl -X PUT "$SERVER_URL/api/admin/superuser/$USERNAME" -d "$IS_SUPERUSER" The fully expanded example above (without environment variables) looks like this: .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d true .. _delete-a-user: From 074498fd13c3112ea024d7ece0ea26def8fdde3e Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 12 Apr 2024 16:45:46 -0400 Subject: [PATCH 19/21] switch BagIT to new "make superuser" API #9887 --- src/test/java/edu/harvard/iq/dataverse/api/BagIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/BagIT.java b/src/test/java/edu/harvard/iq/dataverse/api/BagIT.java index 28f7fa28328..c80e321b228 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/BagIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/BagIT.java @@ -53,8 +53,8 @@ public void testBagItExport() throws IOException { createUser.then().assertThat().statusCode(OK.getStatusCode()); String username = UtilIT.getUsernameFromResponse(createUser); String apiToken = UtilIT.getApiTokenFromResponse(createUser); - Response toggleSuperuser = UtilIT.makeSuperUser(username); - toggleSuperuser.then().assertThat() + Response makeSuperuser = UtilIT.setSuperuserStatus(username, true); + makeSuperuser.then().assertThat() .statusCode(OK.getStatusCode()); Response createDataverse = UtilIT.createRandomDataverse(apiToken); From a97b931214f9fce8368e1b7e6a5fcfc8dadcc0a9 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 12 Apr 2024 16:49:54 -0400 Subject: [PATCH 20/21] reformat code (no-op) #9887 --- .../edu/harvard/iq/dataverse/api/Admin.java | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 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 e1e86adacc6..236cadcf128 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1030,49 +1030,49 @@ public Response deleteRole(@Context ContainerRequestContext crc, @PathParam("id" }, getRequestUser(crc)); } - @Path("superuser/{identifier}") - @Deprecated - @POST - public Response toggleSuperuser(@PathParam("identifier") String identifier) { - ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") - .setInfo(identifier); - try { - final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); - return setSuperuserStatus(user, !user.isSuperuser()); - } catch (Exception e) { - alr.setActionResult(ActionLogRecord.Result.InternalError); - alr.setInfo(alr.getInfo() + "// " + e.getMessage()); - return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } finally { - actionLogSvc.log(alr); - } - } + @Path("superuser/{identifier}") + @Deprecated + @POST + public Response toggleSuperuser(@PathParam("identifier") String identifier) { + ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") + .setInfo(identifier); + try { + final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); + return setSuperuserStatus(user, !user.isSuperuser()); + } catch (Exception e) { + alr.setActionResult(ActionLogRecord.Result.InternalError); + alr.setInfo(alr.getInfo() + "// " + e.getMessage()); + return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); + } finally { + actionLogSvc.log(alr); + } + } - private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) { - if (user.isDeactivated()) { - return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); - } - user.setSuperuser(isSuperuser); - return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") - + " as a superuser."); - } + private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) { + if (user.isDeactivated()) { + return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); + } + user.setSuperuser(isSuperuser); + return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") + + " as a superuser."); + } - @Path("superuser/{identifier}") - @PUT - //using string instead of boolean so user doesnt need to add Content type header in their request - public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperuser) { - ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") - .setInfo(identifier + ":" + isSuperuser); - try { + @Path("superuser/{identifier}") + @PUT + //using string instead of boolean so user doesnt need to add Content type header in their request + public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperuser) { + ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") + .setInfo(identifier + ":" + isSuperuser); + try { return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), StringUtil.isTrue(isSuperuser)); - } catch (Exception e) { - alr.setActionResult(ActionLogRecord.Result.InternalError); - alr.setInfo(alr.getInfo() + "// " + e.getMessage()); - return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } finally { - actionLogSvc.log(alr); - } - } + } catch (Exception e) { + alr.setActionResult(ActionLogRecord.Result.InternalError); + alr.setInfo(alr.getInfo() + "// " + e.getMessage()); + return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); + } finally { + actionLogSvc.log(alr); + } + } @GET @Path("validate/datasets") From 80ae69bc4f5d5ea649ad23a7b3aeef8aad3fb544 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 12 Apr 2024 16:52:55 -0400 Subject: [PATCH 21/21] make action log match method name, comment tweak #9887 --- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 4 ++-- 1 file changed, 2 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 236cadcf128..da42a5c8994 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1059,9 +1059,9 @@ private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) @Path("superuser/{identifier}") @PUT - //using string instead of boolean so user doesnt need to add Content type header in their request + // Using string instead of boolean so user doesn't need to add a Content-type header in their request public Response setSuperuserStatus(@PathParam("identifier") String identifier, String isSuperuser) { - ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") + ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "setSuperuserStatus") .setInfo(identifier + ":" + isSuperuser); try { return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), StringUtil.isTrue(isSuperuser));