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());
+  }
+
 }