This commit is contained in:
Jesang Yoon 2016-03-15 10:58:44 +09:00
commit 35a6679bac
14 changed files with 383 additions and 129 deletions

1
.gitignore vendored
View file

@ -21,6 +21,7 @@ conf/zeppelin-site.xml
conf/keystore
conf/truststore
conf/interpreter.json
conf/notebook-authorization.json
# other generated files
spark/dependency-reduced-pom.xml

View file

@ -477,6 +477,7 @@
<exclude>**/licenses/**</exclude>
<exclude>**/zeppelin-distribution/src/bin_license/**</exclude>
<exclude>conf/interpreter.json</exclude>
<exclude>conf/notebook-authorization.json</exclude>
<exclude>conf/zeppelin-env.sh</exclude>
<exclude>spark-*-bin*/**</exclude>

View file

@ -18,11 +18,7 @@
package org.apache.zeppelin.rest;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@ -39,6 +35,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.notebook.Note;
import org.apache.zeppelin.notebook.Notebook;
import org.apache.zeppelin.notebook.NotebookAuthorization;
import org.apache.zeppelin.notebook.Paragraph;
import org.apache.zeppelin.rest.message.CronRequest;
import org.apache.zeppelin.rest.message.InterpreterSettingListForNoteBind;
@ -69,6 +66,7 @@ public class NotebookRestApi {
private Notebook notebook;
private NotebookServer notebookServer;
private SearchService notebookIndex;
private NotebookAuthorization notebookAuthorization;
public NotebookRestApi() {}
@ -76,24 +74,25 @@ public class NotebookRestApi {
this.notebook = notebook;
this.notebookServer = notebookServer;
this.notebookIndex = search;
this.notebookAuthorization = notebook.getNotebookAuthorization();
}
/**
* list note owners
* get note authorization information
*/
@GET
@Path("{noteId}/permissions")
public Response getNotePermissions(@PathParam("noteId") String noteId) {
Note note = notebook.getNote(noteId);
HashMap<String, HashSet> permissionsMap = new HashMap<String, HashSet>();
permissionsMap.put("owners", note.getOwners());
permissionsMap.put("readers", note.getReaders());
permissionsMap.put("writers", note.getWriters());
HashMap<String, Set<String>> permissionsMap = new HashMap();
permissionsMap.put("owners", notebookAuthorization.getOwners(noteId));
permissionsMap.put("readers", notebookAuthorization.getReaders(noteId));
permissionsMap.put("writers", notebookAuthorization.getWriters(noteId));
return new JsonResponse<>(Status.OK, "", permissionsMap).build();
}
String ownerPermissionError(HashSet<String> current,
HashSet<String> allowed) throws IOException {
String ownerPermissionError(Set<String> current,
Set<String> allowed) throws IOException {
LOG.info("Cannot change permissions. Connection owners {}. Allowed owners {}",
current.toString(), allowed.toString());
return "Insufficient privileges to change permissions.\n\n" +
@ -102,7 +101,7 @@ public class NotebookRestApi {
}
/**
* Set note owners
* set note authorization information
*/
@PUT
@Path("{noteId}/permissions")
@ -124,15 +123,17 @@ public class NotebookRestApi {
HashSet<String> userAndRoles = new HashSet<String>();
userAndRoles.add(principal);
userAndRoles.addAll(roles);
if (!note.isOwner(userAndRoles)) {
if (!notebookAuthorization.isOwner(noteId, userAndRoles)) {
return new JsonResponse<>(Status.FORBIDDEN, ownerPermissionError(userAndRoles,
note.getOwners())).build();
notebookAuthorization.getOwners(noteId))).build();
}
note.setOwners(permMap.get("owners"));
note.setReaders(permMap.get("readers"));
note.setWriters(permMap.get("writers"));
LOG.debug("After set permissions {} {} {}", note.getOwners(), note.getReaders(),
note.getWriters());
notebookAuthorization.setOwners(noteId, permMap.get("owners"));
notebookAuthorization.setReaders(noteId, permMap.get("readers"));
notebookAuthorization.setWriters(noteId, permMap.get("writers"));
LOG.debug("After set permissions {} {} {}",
notebookAuthorization.getOwners(noteId),
notebookAuthorization.getReaders(noteId),
notebookAuthorization.getWriters(noteId));
note.persist();
notebookServer.broadcastNote(note);
return new JsonResponse<>(Status.OK).build();

View file

@ -33,6 +33,7 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
import org.apache.zeppelin.dep.DependencyResolver;
import org.apache.zeppelin.interpreter.InterpreterFactory;
import org.apache.zeppelin.notebook.Notebook;
import org.apache.zeppelin.notebook.NotebookAuthorization;
import org.apache.zeppelin.notebook.repo.NotebookRepo;
import org.apache.zeppelin.notebook.repo.NotebookRepoSync;
import org.apache.zeppelin.rest.*;
@ -71,6 +72,7 @@ public class ZeppelinServer extends Application {
private InterpreterFactory replFactory;
private NotebookRepo notebookRepo;
private SearchService notebookIndex;
private NotebookAuthorization notebookAuthorization;
private DependencyResolver depResolver;
public ZeppelinServer() throws Exception {
@ -83,9 +85,10 @@ public class ZeppelinServer extends Application {
notebookWsServer, depResolver);
this.notebookRepo = new NotebookRepoSync(conf);
this.notebookIndex = new LuceneSearch();
this.notebookAuthorization = new NotebookAuthorization(conf);
notebook = new Notebook(conf,
notebookRepo, schedulerFactory, replFactory, notebookWsServer, notebookIndex);
notebookRepo, schedulerFactory, replFactory, notebookWsServer,
notebookIndex, notebookAuthorization);
}
public static void main(String[] args) throws InterruptedException {

View file

@ -371,8 +371,8 @@ public class NotebookServer extends WebSocketServlet implements
broadcastAll(new Message(OP.NOTES_INFO).put("notes", notesInfo));
}
void permissionError(NotebookSocket conn, String op, HashSet<String> current,
HashSet<String> allowed) throws IOException {
void permissionError(NotebookSocket conn, String op, Set<String> current,
Set<String> allowed) throws IOException {
LOG.info("Cannot {}. Connection readers {}. Allowed readers {}",
op, current, allowed);
conn.send(serializeMessage(new Message(OP.AUTH_INFO).put("info",
@ -395,9 +395,10 @@ public class NotebookServer extends WebSocketServlet implements
}
Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (note != null) {
if (!note.isReader(userAndRoles)) {
permissionError(conn, "read", userAndRoles, note.getReaders());
if (!notebookAuthorization.isReader(noteId, userAndRoles)) {
permissionError(conn, "read", userAndRoles, notebookAuthorization.getReaders(noteId));
broadcastNoteList();
return;
}
@ -417,8 +418,9 @@ public class NotebookServer extends WebSocketServlet implements
}
if (note != null) {
if (!note.isReader(userAndRoles)) {
permissionError(conn, "read", userAndRoles, note.getReaders());
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isReader(noteId, userAndRoles)) {
permissionError(conn, "read", userAndRoles, notebookAuthorization.getReaders(noteId));
broadcastNoteList();
return;
}
@ -502,9 +504,9 @@ public class NotebookServer extends WebSocketServlet implements
}
Note note = notebook.getNote(noteId);
if (!note.isOwner(userAndRoles)) {
permissionError(conn, "remove", userAndRoles, note.getOwners());
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isOwner(noteId, userAndRoles)) {
permissionError(conn, "remove", userAndRoles, notebookAuthorization.getOwners(noteId));
return;
}
@ -524,10 +526,11 @@ public class NotebookServer extends WebSocketServlet implements
.get("params");
Map<String, Object> config = (Map<String, Object>) fromMessage
.get("config");
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -572,11 +575,11 @@ public class NotebookServer extends WebSocketServlet implements
if (paragraphId == null) {
return;
}
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -594,11 +597,11 @@ public class NotebookServer extends WebSocketServlet implements
if (paragraphId == null) {
return;
}
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -722,10 +725,11 @@ public class NotebookServer extends WebSocketServlet implements
final int newIndex = (int) Double.parseDouble(fromMessage.get("index")
.toString());
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -738,10 +742,11 @@ public class NotebookServer extends WebSocketServlet implements
Notebook notebook, Message fromMessage) throws IOException {
final int index = (int) Double.parseDouble(fromMessage.get("index")
.toString());
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -757,10 +762,11 @@ public class NotebookServer extends WebSocketServlet implements
return;
}
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}
@ -775,10 +781,11 @@ public class NotebookServer extends WebSocketServlet implements
return;
}
final Note note = notebook.getNote(getOpenNoteId(conn));
if (!note.isWriter(userAndRoles)) {
permissionError(conn, "write", userAndRoles, note.getWriters());
String noteId = getOpenNoteId(conn);
final Note note = notebook.getNote(noteId);
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
permissionError(conn, "write", userAndRoles, notebookAuthorization.getWriters(noteId));
return;
}

View file

@ -106,8 +106,8 @@ public class WebDriverManager {
}
String url;
if (System.getProperty("url") != null) {
url = System.getProperty("url");
if (System.getenv("url") != null) {
url = System.getenv("url");
} else {
url = "http://localhost:8080";
}

View file

@ -342,6 +342,10 @@ public class ZeppelinConfiguration extends XMLConfiguration {
return getRelativeDir(String.format("%s/interpreter.json", getConfDir()));
}
public String getNotebookAuthorizationPath() {
return getRelativeDir(String.format("%s/notebook-authorization.json", getConfDir()));
}
public String getInterpreterRemoteRunnerPath() {
return getRelativeDir(ConfVars.ZEPPELIN_INTERPRETER_REMOTE_RUNNER);
}

View file

@ -59,9 +59,6 @@ public class Note implements Serializable, JobListener {
private String name = "";
private String id;
private HashSet<String> owners = new HashSet<String>();
private HashSet<String> readers = new HashSet<String>();
private HashSet<String> writers = new HashSet<String>();
@SuppressWarnings("rawtypes")
Map<String, List<AngularObject>> angularObjects = new HashMap<>();
@ -118,51 +115,6 @@ public class Note implements Serializable, JobListener {
this.name = name;
}
public HashSet<String> getOwners() {
return (new HashSet<String>(owners));
}
public void setOwners(HashSet<String> owners) {
this.owners = new HashSet<String>(owners);
}
public HashSet<String> getReaders() {
return (new HashSet<String>(readers));
}
public void setReaders(HashSet<String> readers) {
this.readers = new HashSet<String>(readers);
}
public HashSet<String> getWriters() {
return (new HashSet<String>(writers));
}
public void setWriters(HashSet<String> writers) {
this.writers = new HashSet<String>(writers);
}
public boolean isOwner(HashSet<String> entities) {
return isMember(entities, this.owners);
}
public boolean isWriter(HashSet<String> entities) {
return isMember(entities, this.writers) || isMember(entities, this.owners);
}
public boolean isReader(HashSet<String> entities) {
return isMember(entities, this.readers) ||
isMember(entities, this.owners) ||
isMember(entities, this.writers);
}
// return true if b is empty or if (a intersection b) is non-empty
private boolean isMember(HashSet<String> a, HashSet<String> b) {
Set<String> intersection = new HashSet<String>(b);
intersection.retainAll(a);
return (b.isEmpty() || (intersection.size() > 0));
}
public NoteInterpreterLoader getNoteReplLoader() {
return replLoader;
}

View file

@ -76,6 +76,7 @@ public class Notebook {
private JobListenerFactory jobListenerFactory;
private NotebookRepo notebookRepo;
private SearchService notebookIndex;
private NotebookAuthorization notebookAuthorization;
/**
* Main constructor \w manual Dependency Injection
@ -86,6 +87,7 @@ public class Notebook {
* @param replFactory
* @param jobListenerFactory
* @param notebookIndex - (nullable) for indexing all notebooks on creating.
* @param notebookAuthorization
*
* @throws IOException
* @throws SchedulerException
@ -93,13 +95,15 @@ public class Notebook {
public Notebook(ZeppelinConfiguration conf, NotebookRepo notebookRepo,
SchedulerFactory schedulerFactory,
InterpreterFactory replFactory, JobListenerFactory jobListenerFactory,
SearchService notebookIndex) throws IOException, SchedulerException {
SearchService notebookIndex,
NotebookAuthorization notebookAuthorization) throws IOException, SchedulerException {
this.conf = conf;
this.notebookRepo = notebookRepo;
this.schedulerFactory = schedulerFactory;
this.replFactory = replFactory;
this.jobListenerFactory = jobListenerFactory;
this.notebookIndex = notebookIndex;
this.notebookAuthorization = notebookAuthorization;
quertzSchedFact = new org.quartz.impl.StdSchedulerFactory();
quartzSched = quertzSchedFact.getScheduler();
quartzSched.start();
@ -281,6 +285,7 @@ public class Notebook {
}
replFactory.removeNoteInterpreterSettingBinding(id);
notebookIndex.deleteIndexDocs(note);
notebookAuthorization.removeNote(id);
// remove from all interpreter instance's angular object registry
for (InterpreterSetting settings : replFactory.get()) {
@ -575,6 +580,10 @@ public class Notebook {
return replFactory;
}
public NotebookAuthorization getNotebookAuthorization() {
return notebookAuthorization;
}
public ZeppelinConfiguration getConf() {
return conf;
}

View file

@ -0,0 +1,231 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zeppelin.notebook;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
/**
* Contains authorization information for notes
*/
public class NotebookAuthorization {
private static final Logger LOG = LoggerFactory.getLogger(NotebookAuthorization.class);
/*
* { "note1": { "owners": ["u1"], "readers": ["u1", "u2"], "writers": ["u1"] }, "note2": ... } }
*/
private Map<String, Map<String, Set<String>>> authInfo = new HashMap<>();
private ZeppelinConfiguration conf;
private Gson gson;
private String filePath;
public NotebookAuthorization(ZeppelinConfiguration conf) {
this.conf = conf;
filePath = conf.getNotebookAuthorizationPath();
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
gson = builder.create();
try {
loadFromFile();
} catch (IOException e) {
LOG.error("Error loading NotebookAuthorization");
e.printStackTrace();
}
}
private void loadFromFile() throws IOException {
File settingFile = new File(filePath);
LOG.info(settingFile.getAbsolutePath());
if (!settingFile.exists()) {
// nothing to read
return;
}
FileInputStream fis = new FileInputStream(settingFile);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
isr.close();
fis.close();
String json = sb.toString();
NotebookAuthorizationInfoSaving info = gson.fromJson(json,
NotebookAuthorizationInfoSaving.class);
this.authInfo = info.authInfo;
}
private void saveToFile() {
String jsonString;
synchronized (authInfo) {
NotebookAuthorizationInfoSaving info = new NotebookAuthorizationInfoSaving();
info.authInfo = authInfo;
jsonString = gson.toJson(info);
}
try {
File settingFile = new File(filePath);
if (!settingFile.exists()) {
settingFile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(settingFile, false);
OutputStreamWriter out = new OutputStreamWriter(fos);
out.append(jsonString);
out.close();
fos.close();
} catch (IOException e) {
LOG.error("Error saving notebook authorization file: " + e.getMessage());
}
}
public void setOwners(String noteId, Set<String> entities) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
if (noteAuthInfo == null) {
noteAuthInfo = new LinkedHashMap();
noteAuthInfo.put("owners", new LinkedHashSet(entities));
noteAuthInfo.put("readers", new LinkedHashSet());
noteAuthInfo.put("writers", new LinkedHashSet());
authInfo.put(noteId, noteAuthInfo);
} else {
Set<String> existingEntities = noteAuthInfo.get("owners");
if (existingEntities == null) {
noteAuthInfo.put("owners", new LinkedHashSet(entities));
} else {
existingEntities.addAll(entities);
}
}
saveToFile();
}
public void setReaders(String noteId, Set<String> entities) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
if (noteAuthInfo == null) {
noteAuthInfo = new LinkedHashMap();
noteAuthInfo.put("owners", new LinkedHashSet());
noteAuthInfo.put("readers", new LinkedHashSet(entities));
noteAuthInfo.put("writers", new LinkedHashSet());
authInfo.put(noteId, noteAuthInfo);
} else {
Set<String> existingEntities = noteAuthInfo.get("readers");
if (existingEntities == null) {
noteAuthInfo.put("readers", new LinkedHashSet(entities));
} else {
existingEntities.addAll(entities);
}
}
saveToFile();
}
public void setWriters(String noteId, Set<String> entities) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
if (noteAuthInfo == null) {
noteAuthInfo = new LinkedHashMap();
noteAuthInfo.put("owners", new LinkedHashSet());
noteAuthInfo.put("readers", new LinkedHashSet());
noteAuthInfo.put("writers", new LinkedHashSet(entities));
authInfo.put(noteId, noteAuthInfo);
} else {
Set<String> existingEntities = noteAuthInfo.get("writers");
if (existingEntities == null) {
noteAuthInfo.put("writers", new LinkedHashSet(entities));
} else {
existingEntities.addAll(entities);
}
}
saveToFile();
}
public Set<String> getOwners(String noteId) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
} else {
entities = noteAuthInfo.get("owners");
if (entities == null) {
entities = new HashSet<String>();
}
}
return entities;
}
public Set<String> getReaders(String noteId) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
} else {
entities = noteAuthInfo.get("readers");
if (entities == null) {
entities = new HashSet<String>();
}
}
return entities;
}
public Set<String> getWriters(String noteId) {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
} else {
entities = noteAuthInfo.get("writers");
if (entities == null) {
entities = new HashSet<String>();
}
}
return entities;
}
public boolean isOwner(String noteId, Set<String> entities) {
return isMember(entities, getOwners(noteId));
}
public boolean isWriter(String noteId, Set<String> entities) {
return isMember(entities, getWriters(noteId)) || isMember(entities, getOwners(noteId));
}
public boolean isReader(String noteId, Set<String> entities) {
return isMember(entities, getReaders(noteId)) ||
isMember(entities, getOwners(noteId)) ||
isMember(entities, getWriters(noteId));
}
// return true if b is empty or if (a intersection b) is non-empty
private boolean isMember(Set<String> a, Set<String> b) {
Set<String> intersection = new HashSet<String>(b);
intersection.retainAll(a);
return (b.isEmpty() || (intersection.size() > 0));
}
public void removeNote(String noteId) {
authInfo.remove(noteId);
saveToFile();
}
}

View file

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zeppelin.notebook;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Only used for saving NotebookAuthorization info
*/
public class NotebookAuthorizationInfoSaving {
public Map<String, Map<String, Set<String>>> authInfo;
}

View file

@ -87,7 +87,8 @@ public class NotebookTest implements JobListenerFactory{
SearchService search = mock(SearchService.class);
notebookRepo = new VFSNotebookRepo(conf);
notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search);
NotebookAuthorization notebookAuthorization = new NotebookAuthorization(conf);
notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search, notebookAuthorization);
}
@After
@ -171,7 +172,7 @@ public class NotebookTest implements JobListenerFactory{
Notebook notebook2 = new Notebook(
conf, notebookRepo, schedulerFactory,
new InterpreterFactory(conf, null, null, null, depResolver), this, null);
new InterpreterFactory(conf, null, null, null, depResolver), this, null, null);
assertEquals(1, notebook2.getAllNotes().size());
}
@ -422,23 +423,36 @@ public class NotebookTest implements JobListenerFactory{
public void testPermissions() throws IOException {
// create a note and a paragraph
Note note = notebook.createNote();
NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
// empty owners, readers and writers means note is public
assertEquals(note.isOwner(new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(note.isReader(new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(note.isWriter(new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(notebookAuthorization.isOwner(note.id(),
new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(notebookAuthorization.isReader(note.id(),
new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(notebookAuthorization.isWriter(note.id(),
new HashSet<String>(Arrays.asList("user2"))), true);
note.setOwners(new HashSet<String>(Arrays.asList("user1")));
note.setReaders(new HashSet<String>(Arrays.asList("user1", "user2")));
note.setWriters(new HashSet<String>(Arrays.asList("user1")));
notebookAuthorization.setOwners(note.id(),
new HashSet<String>(Arrays.asList("user1")));
notebookAuthorization.setReaders(note.id(),
new HashSet<String>(Arrays.asList("user1", "user2")));
notebookAuthorization.setWriters(note.id(),
new HashSet<String>(Arrays.asList("user1")));
assertEquals(note.isOwner(new HashSet<String>(Arrays.asList("user2"))), false);
assertEquals(note.isOwner(new HashSet<String>(Arrays.asList("user1"))), true);
assertEquals(notebookAuthorization.isOwner(note.id(),
new HashSet<String>(Arrays.asList("user2"))), false);
assertEquals(notebookAuthorization.isOwner(note.id(),
new HashSet<String>(Arrays.asList("user1"))), true);
assertEquals(note.isReader(new HashSet<String>(Arrays.asList("user3"))), false);
assertEquals(note.isReader(new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(notebookAuthorization.isReader(note.id(),
new HashSet<String>(Arrays.asList("user3"))), false);
assertEquals(notebookAuthorization.isReader(note.id(),
new HashSet<String>(Arrays.asList("user2"))), true);
assertEquals(note.isWriter(new HashSet<String>(Arrays.asList("user2"))), false);
assertEquals(note.isWriter(new HashSet<String>(Arrays.asList("user1"))), true);
assertEquals(notebookAuthorization.isWriter(note.id(),
new HashSet<String>(Arrays.asList("user2"))), false);
assertEquals(notebookAuthorization.isWriter(note.id(),
new HashSet<String>(Arrays.asList("user1"))), true);
notebook.removeNote(note.id());
}

View file

@ -62,6 +62,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
private InterpreterFactory factory;
private DependencyResolver depResolver;
private SearchService search;
private NotebookAuthorization notebookAuthorization;
private static final Logger LOG = LoggerFactory.getLogger(NotebookRepoSyncTest.class);
@Before
@ -95,7 +96,8 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
search = mock(SearchService.class);
notebookRepoSync = new NotebookRepoSync(conf);
notebookSync = new Notebook(conf, notebookRepoSync, schedulerFactory, factory, this, search);
notebookAuthorization = new NotebookAuthorization(conf);
notebookSync = new Notebook(conf, notebookRepoSync, schedulerFactory, factory, this, search, notebookAuthorization);
}
@After
@ -220,7 +222,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
ZeppelinConfiguration vConf = ZeppelinConfiguration.create();
NotebookRepoSync vRepoSync = new NotebookRepoSync(vConf);
Notebook vNotebookSync = new Notebook(vConf, vRepoSync, schedulerFactory, factory, this, search);
Notebook vNotebookSync = new Notebook(vConf, vRepoSync, schedulerFactory, factory, this, search, null);
// one git versioned storage initialized
assertThat(vRepoSync.getRepoCount()).isEqualTo(1);

View file

@ -80,7 +80,7 @@ public class VFSNotebookRepoTest implements JobListenerFactory {
SearchService search = mock(SearchService.class);
notebookRepo = new VFSNotebookRepo(conf);
notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search);
notebook = new Notebook(conf, notebookRepo, schedulerFactory, factory, this, search, null);
}
@After