You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by bz...@apache.org on 2016/05/03 09:40:09 UTC
incubator-zeppelin git commit: [ZEPPELIN-705]Search should aware
notebook permission
Repository: incubator-zeppelin
Updated Branches:
refs/heads/master f0a7caa68 -> 2d85f3a95
[ZEPPELIN-705]Search should aware notebook permission
### What is this PR for?
Make search aware of notebook permissions and allow only those search results for which user has read permission.
### What type of PR is it?
Bug Fix
### Todos
NA
### What is the Jira issue?
[ZEPPELIN-705]( https://issues.apache.org/jira/browse/ZEPPELIN-705?jql=project%20%3D%20ZEPPELIN%20AND%20status%20in%20(Open%2C%20Resolved)%20AND%20resolution%20%3D%20Unresolved%20AND%20fixVersion%20%3D%200.6.0%20ORDER%20BY%20due%20ASC%2C%20priority%20DESC%2C%20created%20ASC)
### How should this be tested?
### Screenshots (if appropriate)
### Questions:
* Does the licenses files need update?No
* Is there breaking changes for older versions?No
* Does this needs documentation?No
Author: Ravi Ranjan <ra...@gmail.com>
Closes #833 from ravicodder/ZEPPELIN-705 and squashes the following commits:
a4a9999 [Ravi Ranjan] Make test more Readable
c42573e [Ravi Ranjan] Add check to see search searching all allowed notebook
7a624d0 [Ravi Ranjan] Add rest API test
2fe33e5 [Ravi Ranjan] search should aware notebook permissions
Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/2d85f3a9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/2d85f3a9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/2d85f3a9
Branch: refs/heads/master
Commit: 2d85f3a9571c6fe59ffd1795c023adbe232ad511
Parents: f0a7caa
Author: Ravi Ranjan <ra...@gmail.com>
Authored: Tue Apr 26 10:57:37 2016 +0530
Committer: Alexander Bezzubov <bz...@apache.org>
Committed: Tue May 3 16:39:54 2016 +0900
----------------------------------------------------------------------
.../apache/zeppelin/rest/NotebookRestApi.java | 19 +++++-
.../zeppelin/rest/ZeppelinRestApiTest.java | 66 ++++++++++++++++++++
2 files changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/2d85f3a9/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
index 482ea78..89e84ee 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
@@ -665,14 +665,29 @@ public class NotebookRestApi {
}
/**
- * Search for a Notes
+ * Search for a Notes with permissions
*/
@GET
@Path("search")
public Response search(@QueryParam("q") String queryTerm) {
LOG.info("Searching notebooks for: {}", queryTerm);
+ String principal = SecurityUtils.getPrincipal();
+ HashSet<String> roles = SecurityUtils.getRoles();
+ HashSet<String> userAndRoles = new HashSet<String>();
+ userAndRoles.add(principal);
+ userAndRoles.addAll(roles);
List<Map<String, String>> notebooksFound = notebookIndex.query(queryTerm);
- LOG.info("{} notbooks found", notebooksFound.size());
+ for (int i = 0; i < notebooksFound.size(); i++) {
+ String[] Id = notebooksFound.get(i).get("id").split("/", 2);
+ String noteId = Id[0];
+ if (!notebookAuthorization.isOwner(noteId, userAndRoles) &&
+ !notebookAuthorization.isReader(noteId, userAndRoles) &&
+ !notebookAuthorization.isWriter(noteId, userAndRoles)) {
+ notebooksFound.remove(i);
+ i--;
+ }
+ }
+ LOG.info("{} notebooks found", notebooksFound.size());
return new JsonResponse<>(Status.OK, notebooksFound).build();
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/2d85f3a9/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index 3c7c7d0..2f2a36b 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -18,6 +18,7 @@
package org.apache.zeppelin.rest;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -690,5 +691,70 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
ZeppelinServer.notebook.removeNote(note.getId());
}
+
+ @Test
+ public void testSearch() throws IOException {
+ Map<String, String> body;
+
+ GetMethod getSecurityTicket = httpGet("/security/ticket");
+ getSecurityTicket.addRequestHeader("Origin", "http://localhost");
+ Map<String, Object> respSecurityTicket = gson.fromJson(getSecurityTicket.getResponseBodyAsString(),
+ new TypeToken<Map<String, Object>>() {
+ }.getType());
+ body = (Map<String, String>) respSecurityTicket.get("body");
+ String username = body.get("principal");
+ getSecurityTicket.releaseConnection();
+
+ Note note1 = ZeppelinServer.notebook.createNote();
+ String jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 1\"}";
+ PostMethod postNotebookText = httpPost("/notebook/" + note1.getId() + "/paragraph", jsonRequest);
+ postNotebookText.releaseConnection();
+
+ Note note2 = ZeppelinServer.notebook.createNote();
+ jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 2\"}";
+ postNotebookText = httpPost("/notebook/" + note2.getId() + "/paragraph", jsonRequest);
+ postNotebookText.releaseConnection();
+
+ String jsonPermissions = "{\"owners\":[\"" + username + "\"],\"readers\":[\"" + username + "\"],\"writers\":[\"" + username + "\"]}";
+ PutMethod putPermission = httpPut("/notebook/" + note1.getId() + "/permissions", jsonPermissions);
+ putPermission.releaseConnection();
+
+ jsonPermissions = "{\"owners\":[\"admin\"],\"readers\":[\"admin\"],\"writers\":[\"admin\"]}";
+ putPermission = httpPut("/notebook/" + note2.getId() + "/permissions", jsonPermissions);
+ putPermission.releaseConnection();
+
+ GetMethod searchNotebook = httpGet("/notebook/search?q='ThisIsToTestSearchMethodWithPermissions'");
+ searchNotebook.addRequestHeader("Origin", "http://localhost");
+ Map<String, Object> respSearchResult = gson.fromJson(searchNotebook.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");
+ getPermission.addRequestHeader("Origin", "http://localhost");
+ 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");
+
+ if (owners.size() != 0 && readers.size() != 0 && writers.size() != 0) {
+ assertEquals("User has permissions ", true, (owners.contains(username) || readers.contains(username) ||
+ writers.contains(username)));
+ }
+ getPermission.releaseConnection();
+ }
+ searchNotebook.releaseConnection();
+ ZeppelinServer.notebook.removeNote(note1.getId());
+ ZeppelinServer.notebook.removeNote(note2.getId());
+ }
+
}