From 7c7f68e1f4ddf80efb4b4a199a472d9e97ca79a2 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 21 Jun 2017 11:15:01 -0400 Subject: [PATCH] implement :SearchApiRequiresToken setting #3900 --- .../source/installation/config.rst | 7 +++++ .../edu/harvard/iq/dataverse/api/Search.java | 23 +++++++++++---- .../settings/SettingsServiceBean.java | 7 ++++- .../harvard/iq/dataverse/api/SearchIT.java | 29 +++++++++++++++---- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/doc/sphinx-guides/source/installation/config.rst b/doc/sphinx-guides/source/installation/config.rst index 72504a18dca..324b50bd7b2 100644 --- a/doc/sphinx-guides/source/installation/config.rst +++ b/doc/sphinx-guides/source/installation/config.rst @@ -498,6 +498,13 @@ The key required to create users via API as documented at :doc:`/api/native-api` ``curl -X PUT -d builtInS3kretKey http://localhost:8080/api/admin/settings/BuiltinUsers.KEY`` +:SearchApiRequiresToken ++++++++++++++++++++++++ + +In Dataverse 4.6.2 and lower, the :doc:`/api/search` required an API token, but this is no longer the case. If you prefer the old behavior of requiring API tokens to use the Search API, set ``:SearchApiRequiresToken`` to ``true``. + +``curl -X PUT -d true http://localhost:8080/api/admin/settings/:SearchApiRequiresToken`` + :SystemEmail ++++++++++++ diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Search.java b/src/main/java/edu/harvard/iq/dataverse/api/Search.java index 987eaea62bf..850818f9640 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Search.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Search.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; import javax.json.Json; @@ -201,13 +202,20 @@ private User getUser() throws WrappedResponse { * see permission documents (all Solr documents, really) and we get a * NPE when trying to determine the DvObject type if their query matches * a permission document. - * - * @todo Check back on https://github.com/IQSS/dataverse/issues/1838 for - * when/if the Search API is opened up to not require a key. */ - AuthenticatedUser authenticatedUser = findAuthenticatedUserOrDie(); + User userToExecuteSearchAs = GuestUser.get(); + try { + AuthenticatedUser authenticatedUser = findAuthenticatedUserOrDie(); + if (authenticatedUser != null) { + userToExecuteSearchAs = authenticatedUser; + } + } catch (WrappedResponse ex) { + if (!tokenLessSearchAllowed()) { + throw ex; + } + } if (nonPublicSearchAllowed()) { - return authenticatedUser; + return userToExecuteSearchAs; } else { return GuestUser.get(); } @@ -218,6 +226,11 @@ public boolean nonPublicSearchAllowed() { return settingsSvc.isTrueForKey(SettingsServiceBean.Key.SearchApiNonPublicAllowed, safeDefaultIfKeyNotFound); } + public boolean tokenLessSearchAllowed() { + boolean outOfBoxBehavior = true; + return settingsSvc.isTrueForKey(SettingsServiceBean.Key.SearchApiRequiresToken, outOfBoxBehavior); + } + private boolean getDataRelatedToMe() { /** * @todo support Data Related To Me: diff --git a/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java index 721390c6f26..cfe974cf7ca 100644 --- a/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/settings/SettingsServiceBean.java @@ -74,7 +74,12 @@ public enum Key { * Search API. See also https://github.com/IQSS/dataverse/issues/1299 */ SearchApiNonPublicAllowed, - + /** + * In Dataverse 4.6.2 and earlier, an API token was required to use the + * Search API. Tokens are no longer required but you can revert to the + * old behavior by setting this to false. + */ + SearchApiRequiresToken, /** * Experimental: Use Solr to power the file listing on the dataset page. */ diff --git a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java index 6b0ee0f7099..7da1a5aa76c 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java @@ -42,6 +42,10 @@ public static void setUpClass() { RestAssured.baseURI = UtilIT.getRestAssuredBaseUri(); + Response makeSureTokenlessSearchIsEnabled = UtilIT.deleteSetting(SettingsServiceBean.Key.SearchApiRequiresToken); + makeSureTokenlessSearchIsEnabled.then().assertThat() + .statusCode(OK.getStatusCode()); + Response removeSearchApiNonPublicAllowed = UtilIT.deleteSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed); removeSearchApiNonPublicAllowed.prettyPrint(); removeSearchApiNonPublicAllowed.then().assertThat() @@ -98,8 +102,8 @@ public void testSearchPermisions() throws InterruptedException { Response shouldNotBeVisibleToTokenLess = UtilIT.search("id:dataset_" + datasetId1 + "_draft", nullToken); shouldNotBeVisibleToTokenLess.prettyPrint(); shouldNotBeVisibleToTokenLess.then().assertThat() - .body("message", CoreMatchers.equalTo("Please provide a key query parameter (?key=XXX) or via the HTTP header X-Dataverse-key")) - .statusCode(UNAUTHORIZED.getStatusCode()); + .body("data.total_count", CoreMatchers.is(0)) + .statusCode(OK.getStatusCode()); String roleToAssign = "admin"; @@ -130,12 +134,27 @@ public void testSearchPermisions() throws InterruptedException { disableNonPublicSearch.then().assertThat() .statusCode(OK.getStatusCode()); - Response evenPublishedDatasetsAreNotVisibleByTokenless = UtilIT.search("id:dataset_" + datasetId1 + "_draft", nullToken); - evenPublishedDatasetsAreNotVisibleByTokenless.prettyPrint(); - evenPublishedDatasetsAreNotVisibleByTokenless.then().assertThat() + Response publishedPublicDataShouldBeVisibleToTokenless = UtilIT.search("id:dataset_" + datasetId1, nullToken); + publishedPublicDataShouldBeVisibleToTokenless.prettyPrint(); + publishedPublicDataShouldBeVisibleToTokenless.then().assertThat() + .body("data.total_count", CoreMatchers.is(1)) + .body("data.count_in_response", CoreMatchers.is(1)) + .body("data.items[0].name", CoreMatchers.is("Darwin's Finches")) + .statusCode(OK.getStatusCode()); + + Response disableTokenlessSearch = UtilIT.setSetting(SettingsServiceBean.Key.SearchApiRequiresToken, "false"); + disableTokenlessSearch.then().assertThat() + .statusCode(OK.getStatusCode()); + + Response dataverse462behaviorOfTokensBeingRequired = UtilIT.search("id:dataset_" + datasetId1, nullToken); + dataverse462behaviorOfTokensBeingRequired.prettyPrint(); + dataverse462behaviorOfTokensBeingRequired.then().assertThat() .body("message", CoreMatchers.equalTo("Please provide a key query parameter (?key=XXX) or via the HTTP header X-Dataverse-key")) .statusCode(UNAUTHORIZED.getStatusCode()); + Response reEnableTokenlessSearch = UtilIT.deleteSetting(SettingsServiceBean.Key.SearchApiRequiresToken); + reEnableTokenlessSearch.then().assertThat() + .statusCode(OK.getStatusCode()); } @Test