Skip to content

Commit

Permalink
implement :SearchApiRequiresToken setting #3900
Browse files Browse the repository at this point in the history
  • Loading branch information
pdurbin committed Jun 21, 2017
1 parent 92a1de9 commit 7c7f68e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
7 changes: 7 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
++++++++++++

Expand Down
23 changes: 18 additions & 5 deletions src/main/java/edu/harvard/iq/dataverse/api/Search.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand All @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
29 changes: 24 additions & 5 deletions src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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";

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 7c7f68e

Please sign in to comment.