This is an automated email from the ASF dual-hosted git repository. prabhjyotsingh pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new d66065e [ZEPPELIN-4489] remove zeppelin.anonymous.allowed configuration d66065e is described below commit d66065e98bbbec9e6c918ad09dd097ea76a16098 Author: Prabhjyot Singh <prabhjyotsi...@gmail.com> AuthorDate: Mon Dec 16 21:23:08 2019 +0530 [ZEPPELIN-4489] remove zeppelin.anonymous.allowed configuration ### What is this PR for? This is a proposal for removing/disabling `zeppelin.anonymous.allowed` when Shiro is configured. My Proposal in this JIRA is; let us remove this `zeppelin.anonymous.allowed`. So, when Shiro is configured then Zeppelin server runs with all the auth configured, and if the user wants anonymous access then they should not configure Shiro.ini. ### What type of PR is it? [Bug Fix | Improvement] ### What is the Jira issue? * [ZEPPELIN-4489](https://issues.apache.org/jira/browse/ZEPPELIN-4489) ### How should this be tested? * CI should be green. ### Screenshots (if appropriate) ### Questions: * Does the licenses files need update? no * Is there breaking changes for older versions? yes * Does this needs documentation? yes Author: Prabhjyot Singh <prabhjyotsi...@gmail.com> Closes #3554 from prabhjyotsingh/ZEPPELIN-4489 and squashes the following commits: d10d1178d [Prabhjyot Singh] remove commented out unit-test b5653861b [Prabhjyot Singh] update breaking changes notes in upgrading.md cffee7218 [Prabhjyot Singh] ZEPPELIN-4489: remove zeppelin.anonymous.allowed configuration Change-Id: I2dfa02e59d0ce5b366e1d722d2d9a17d52b0cf73 --- conf/zeppelin-site.xml.template | 6 --- docs/setup/operation/configuration.md | 6 --- docs/setup/operation/upgrading.md | 7 +-- docs/setup/security/shiro_authentication.md | 7 +-- docs/usage/rest_api/configuration.md | 1 - .../zeppelin/conf/ZeppelinConfiguration.java | 11 +++-- .../apache/zeppelin/rest/AbstractTestRestApi.java | 7 +-- .../zeppelin/rest/NotebookSecurityRestApiTest.java | 50 ---------------------- .../zeppelin/notebook/repo/NotebookRepoSync.java | 2 +- .../repo/zeppelinhub/security/Authentication.java | 4 +- 10 files changed, 16 insertions(+), 85 deletions(-) diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template index 6a45b0b..225498e 100755 --- a/conf/zeppelin-site.xml.template +++ b/conf/zeppelin-site.xml.template @@ -427,12 +427,6 @@ </property> <property> - <name>zeppelin.anonymous.allowed</name> - <value>true</value> - <description>Anonymous user allowed by default</description> -</property> - -<property> <name>zeppelin.username.force.lowercase</name> <value>false</value> <description>Force convert username case to lower case, useful for Active Directory/LDAP. Default is not to change case</description> diff --git a/docs/setup/operation/configuration.md b/docs/setup/operation/configuration.md index a6a602d..cadbc21 100644 --- a/docs/setup/operation/configuration.md +++ b/docs/setup/operation/configuration.md @@ -108,12 +108,6 @@ If both are defined, then the **environment variables** will take priority. <td>If provided, encrypt passwords on the credentials.json file (passwords will be stored as plain-text otherwise</td> </tr> <tr> - <td>N/A</td> - <td><h6 class="properties">zeppelin.anonymous.allowed</h6></td> - <td>true</td> - <td>The anonymous user is allowed by default.</td> - </tr> - <tr> <td><h6 class="properties">ZEPPELIN_SERVER_CONTEXT_PATH</h6></td> <td><h6 class="properties">zeppelin.server.context.path</h6></td> <td>/</td> diff --git a/docs/setup/operation/upgrading.md b/docs/setup/operation/upgrading.md index 53e644d..6dd4993 100644 --- a/docs/setup/operation/upgrading.md +++ b/docs/setup/operation/upgrading.md @@ -40,10 +40,11 @@ So, copying `notebook` and `conf` directory should be enough. - From 0.9, we change the notes file name structure ([ZEPPELIN-2619](https://issues.apache.org/jira/browse/ZEPPELIN-2619)) and move permissions info from `notebook-authorization.json` into note file itself [ZEPPELIN-3985](https://issues.apache.org/jira/browse/ZEPPELIN-3985). So when you upgrading zeppelin to 0.9, you need to upgrade note file. Here's steps you need to follow: 1. Backup your notes file in case the upgrade fails 2. Call `bin/upgrade-note.sh -d` to upgrade note, `-d` option means to delete the old note file, missing this option will keep the old file. - - From 0.9, Zeppelin server bind `127.0.0.1` by default instead of `0.0.0.0`. Configure `zeppelin.server.addr` property or `ZEPPELIN_ADDR` env variable to change. - + - From 0.9, Zeppelin server bind `127.0.0.1` by default instead of `0.0.0.0`. Configure `zeppelin.server.addr` property or `ZEPPELIN_ADDR` env variable to change. + - From 0.9, we have removed `zeppelin.anonymous.allowed` ([ZEPPELIN-4489](https://issues.apache.org/jira/browse/ZEPPELIN-4489)). So, when you upgrade Zeppelin to 0.9 and if `shiro.ini` file does not exists in conf path then all the Zeppelin-Users runs as anonymous. + ### Upgrading from Zeppelin 0.8.1 (and before) to 0.8.2 (and later) - - From 0.8.2, Zeppelin server bind `127.0.0.1` by default instead of `0.0.0.0`. Configure `zeppelin.server.addr` property or `ZEPPELIN_ADDR` env variable to change. + - From 0.8.2, Zeppelin server bind `127.0.0.1` by default instead of `0.0.0.0`. Configure `zeppelin.server.addr` property or `ZEPPELIN_ADDR` env variable to change. ### Upgrading from Zeppelin 0.7 to 0.8 diff --git a/docs/setup/security/shiro_authentication.md b/docs/setup/security/shiro_authentication.md index d019501..f3864d3 100644 --- a/docs/setup/security/shiro_authentication.md +++ b/docs/setup/security/shiro_authentication.md @@ -44,10 +44,7 @@ cp conf/shiro.ini.template conf/shiro.ini For the further information about `shiro.ini` file format, please refer to [Shiro Configuration](http://shiro.apache.org/configuration.html#Configuration-INISections). -### 2. Secure the Websocket channel -Set to property **zeppelin.anonymous.allowed** to **false** in `conf/zeppelin-site.xml`. If you don't have this file yet, just copy `conf/zeppelin-site.xml.template` to `conf/zeppelin-site.xml`. - -### 3. Start Zeppelin +### 2. Start Zeppelin ```bash bin/zeppelin-daemon.sh start #(or restart) @@ -55,7 +52,7 @@ bin/zeppelin-daemon.sh start #(or restart) Then you can browse Zeppelin at [http://localhost:8080](http://localhost:8080). -### 4. Login +### 3. Login Finally, you can login using one of the below **username/password** combinations. <center><img src="{{BASE_PATH}}/assets/themes/zeppelin/img/docs-img/zeppelin-login.png"></center> diff --git a/docs/usage/rest_api/configuration.md b/docs/usage/rest_api/configuration.md index fb9ee7d..c046d92 100644 --- a/docs/usage/rest_api/configuration.md +++ b/docs/usage/rest_api/configuration.md @@ -81,7 +81,6 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple "zeppelin.notebook.homescreen": "", "zeppelin.notebook.storage": "org.apache.zeppelin.notebook.repo.VFSNotebookRepo", "zeppelin.interpreter.connect.timeout": "30000", - "zeppelin.anonymous.allowed": "true", "zeppelin.server.allowed.origins":"*", "zeppelin.encoding": "UTF-8" } diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java index ad1e0a3..cfedcc2 100644 --- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java +++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java @@ -17,6 +17,7 @@ package org.apache.zeppelin.conf; +import com.google.common.annotations.VisibleForTesting; import java.io.File; import java.io.IOException; import java.net.URL; @@ -25,8 +26,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Predicate; - -import com.google.common.annotations.VisibleForTesting; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.tree.ConfigurationNode; @@ -45,6 +44,8 @@ public class ZeppelinConfiguration extends XMLConfiguration { private static final long serialVersionUID = 4749305895693848035L; private static final Logger LOG = LoggerFactory.getLogger(ZeppelinConfiguration.class); + private Boolean anonymousAllowed; + private static final String HELIUM_PACKAGE_DEFAULT_URL = "https://s3.amazonaws.com/helium-package/helium.json"; private static ZeppelinConfiguration conf; @@ -566,7 +567,10 @@ public class ZeppelinConfiguration extends XMLConfiguration { } public boolean isAnonymousAllowed() { - return getBoolean(ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED); + if (anonymousAllowed == null) { + anonymousAllowed = this.getShiroPath().equals(StringUtils.EMPTY); + } + return anonymousAllowed; } public boolean isUsernameForceLowerCase() { @@ -874,7 +878,6 @@ public class ZeppelinConfiguration extends XMLConfiguration { // Allows a way to specify a ',' separated list of allowed origins for rest and websockets // i.e. http://localhost:8080 ZEPPELIN_ALLOWED_ORIGINS("zeppelin.server.allowed.origins", "*"), - ZEPPELIN_ANONYMOUS_ALLOWED("zeppelin.anonymous.allowed", true), ZEPPELIN_USERNAME_FORCE_LOWERCASE("zeppelin.username.force.lowercase", false), ZEPPELIN_CREDENTIALS_PERSIST("zeppelin.credentials.persist", true), ZEPPELIN_CREDENTIALS_ENCRYPT_KEY("zeppelin.credentials.encryptKey", null), diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java index 0331abf..ca8ff95 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java @@ -215,9 +215,6 @@ public abstract class AbstractTestRestApi { if (withAuth) { isRunningWithAuth = true; - // Set Anonymous session to false. - System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED.getVarName(), - "false"); // Create a shiro env test. shiroIni = new File(confDir, "shiro.ini"); @@ -321,9 +318,7 @@ public abstract class AbstractTestRestApi { LOG.info("Test Zeppelin terminated."); if (isRunningWithAuth) { - isRunningWithAuth = false; - System - .clearProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED.getVarName()); + isRunningWithAuth = shiroIni.exists(); } if (deleteConfDir && !TestUtils.getInstance(Notebook.class).getConf().isRecoveryEnabled()) { diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java index ca3b897..0da1c1d 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookSecurityRestApiTest.java @@ -112,26 +112,6 @@ public class NotebookSecurityRestApiTest extends AbstractTestRestApi { assertNull("Deleted note should be null", deletedNote); } - @Test - public void testThatUserCanSearchNote() throws IOException { - String noteId1 = createNoteForUser("test1", "admin", "password1"); - createParagraphForUser(noteId1, "admin", "password1", "title1", - "ThisIsToTestSearchMethodWithPermissions 1"); - - String noteId2 = createNoteForUser("test2", "user1", "password2"); - createParagraphForUser(noteId1, "admin", "password1", "title2", - "ThisIsToTestSearchMethodWithPermissions 2"); - - //set permission for each note - setPermissionForNote(noteId1, "admin", "password1"); - setPermissionForNote(noteId1, "user1", "password2"); - - searchNoteBasedOnPermission("ThisIsToTestSearchMethodWithPermissions", "admin", "password1"); - - deleteNoteForUser(noteId1, "admin", "password1"); - deleteNoteForUser(noteId2, "user1", "password2"); - } - private void userTryRemoveNote(String noteId, String user, String pwd, Matcher<? super HttpMethodBase> m) throws IOException { DeleteMethod delete = httpDelete(("/notebook/" + noteId), user, pwd); @@ -194,34 +174,4 @@ public class NotebookSecurityRestApiTest extends AbstractTestRestApi { PutMethod put = httpPut(("/notebook/" + noteId + "/permissions"), payload, user, pwd); put.releaseConnection(); } - - private void searchNoteBasedOnPermission(String searchText, String user, String pwd) - throws IOException{ - GetMethod searchNote = httpGet(("/notebook/search?q=" + searchText), user, pwd); - Map<String, Object> respSearchResult = gson.fromJson(searchNote.getResponseBodyAsString(), - new TypeToken<Map<String, Object>>() {}.getType()); - ArrayList searchBody = (ArrayList) respSearchResult.get("body"); - assertEquals("At-least one search results is there", true, searchBody.size() >= 1); - - for (int i = 0; i < searchBody.size(); i++) { - Map<String, String> searchResult = (Map<String, String>) searchBody.get(i); - String userId = searchResult.get("id").split("/", 2)[0]; - - GetMethod getPermission = httpGet(("/notebook/" + userId + "/permissions"), user, pwd); - Map<String, Object> resp = gson.fromJson(getPermission.getResponseBodyAsString(), - new TypeToken<Map<String, Object>>() {}.getType()); - Map<String, ArrayList> permissions = (Map<String, ArrayList>) resp.get("body"); - ArrayList owners = permissions.get("owners"); - ArrayList readers = permissions.get("readers"); - ArrayList writers = permissions.get("writers"); - ArrayList runners = permissions.get("runners"); - - if (owners.size() != 0 && readers.size() != 0 && writers.size() != 0 && runners.size() != 0) { - assertEquals("User has permissions ", true, (owners.contains(user) || - readers.contains(user) || writers.contains(user) || runners.contains(user))); - } - getPermission.releaseConnection(); - } - searchNote.releaseConnection(); - } } diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java index df28ac6..3b69c3e 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java @@ -91,7 +91,7 @@ public class NotebookRepoSync implements NotebookRepoWithVersionControl { } // sync for anonymous mode on start - if (getRepoCount() > 1 && conf.getBoolean(ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED)) { + if (getRepoCount() > 1 && conf.isAnonymousAllowed()) { try { sync(AuthenticationInfo.ANONYMOUS); } catch (IOException e) { diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java index 38d8b50..a53479e 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java @@ -49,7 +49,6 @@ public class Authentication implements Runnable { private static final String CIPHER_MODE = "AES/CBC/PKCS5PADDING"; private static final int ivSize = 16; - private static final String ZEPPELIN_CONF_ANONYMOUS_ALLOWED = "zeppelin.anonymous.allowed"; private static final String ZEPPELINHUB_USER_KEY = "zeppelinhub.user.key"; private String token; private boolean authEnabled; @@ -75,8 +74,7 @@ public class Authentication implements Runnable { client = new HttpClient(connectionManager); this.token = token; - authEnabled = !conf.getBoolean("ZEPPELIN_ALLOW_ANONYMOUS", - ZEPPELIN_CONF_ANONYMOUS_ALLOWED, true); + authEnabled = !conf.isAnonymousAllowed(); userKey = conf.getString("ZEPPELINHUB_USER_KEY", ZEPPELINHUB_USER_KEY, "");