Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ conf/truststore
conf/interpreter.json
conf/notebook-authorization.json
conf/shiro.ini
conf/credentials.json

# other generated files
spark/dependency-reduced-pom.xml
Expand Down
2 changes: 2 additions & 0 deletions docs/security/interpreter_authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ The interpret method takes the user string as parameter and executes the jdbc ca

In case of Presto, we don't need password if the Presto DB server runs backend code using HDFS authorization for the user.
For databases like Vertica and Mysql we have to store password information for users.

The Credentials tab in the navbar allows users to save credentials for data sources which are passed to interpreters.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@
<exclude>**/zeppelin-distribution/src/bin_license/**</exclude>
<exclude>conf/interpreter.json</exclude>
<exclude>conf/notebook-authorization.json</exclude>
<exclude>conf/credentials.json</exclude>
<exclude>conf/zeppelin-env.sh</exclude>
<exclude>spark-*-bin*/**</exclude>
<exclude>.spark-dist/**</exclude>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
public class AuthenticationInfo {
String user;
String ticket;
UserCredentials userCredentials;

public AuthenticationInfo() {}

Expand Down Expand Up @@ -52,4 +53,13 @@ public String getTicket() {
public void setTicket(String ticket) {
this.ticket = ticket;
}

public UserCredentials getUserCredentials() {
return userCredentials;
}

public void setUserCredentials(UserCredentials userCredentials) {
this.userCredentials = userCredentials;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* 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.user;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
* Class defining credentials for data source authorization
*/
public class Credentials {
private static final Logger LOG = LoggerFactory.getLogger(Credentials.class);

private Map<String, UserCredentials> credentialsMap;
private Gson gson;
private Boolean credentialsPersist = true;
File credentialsFile;

public Credentials(Boolean credentialsPersist, String credentialsPath) {
this.credentialsPersist = credentialsPersist;
if (credentialsPath != null) {
credentialsFile = new File(credentialsPath);
}
credentialsMap = new HashMap<>();
if (credentialsPersist) {
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
gson = builder.create();
loadFromFile();
}
}

public UserCredentials getUserCredentials(String username) {
UserCredentials uc = credentialsMap.get(username);
if (uc == null) {
uc = new UserCredentials();
}
return uc;
}

public void putUserCredentials(String username, UserCredentials uc) throws IOException {
credentialsMap.put(username, uc);
if (credentialsPersist) {
saveToFile();
}
}

private void loadFromFile() {
LOG.info(credentialsFile.getAbsolutePath());
if (!credentialsFile.exists()) {
// nothing to read
return;
}

try {
FileInputStream fis = new FileInputStream(credentialsFile);
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();
CredentialsInfoSaving info = gson.fromJson(json, CredentialsInfoSaving.class);
this.credentialsMap = info.credentialsMap;
} catch (IOException e) {
LOG.error("Error loading credentials file", e);
e.printStackTrace();
}
}

private void saveToFile() throws IOException {
String jsonString;

synchronized (credentialsMap) {
CredentialsInfoSaving info = new CredentialsInfoSaving();
info.credentialsMap = credentialsMap;
jsonString = gson.toJson(info);
}

try {
if (!credentialsFile.exists()) {
credentialsFile.createNewFile();
}

FileOutputStream fos = new FileOutputStream(credentialsFile, false);
OutputStreamWriter out = new OutputStreamWriter(fos);
out.append(jsonString);
out.close();
fos.close();
} catch (IOException e) {
LOG.error("Error saving credentials file", e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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.user;

import java.util.Map;

/**
* Helper class to save credentials
*/
public class CredentialsInfoSaving {
public Map<String, UserCredentials> credentialsMap;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.user;

import java.util.HashMap;
import java.util.Map;

/**
* User Credentials POJO
*/
public class UserCredentials {
private Map<String, UsernamePassword> userCredentials;

public UserCredentials() {
this.userCredentials = new HashMap<>();
}

public UsernamePassword getUsernamePassword(String entity) {
return userCredentials.get(entity);
}

public void putUsernamePassword(String entity, UsernamePassword up) {
userCredentials.put(entity, up);
}

@Override
public String toString() {
return "UserCredentials{" +
"userCredentials=" + userCredentials +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.user;

/**
* Username and Password POJO
*/
public class UsernamePassword {
private String username;
private String password;

public UsernamePassword(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "UsernamePassword{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.user;

import static org.junit.Assert.*;

import org.junit.Test;

import java.io.IOException;

public class CredentialsTest {

@Test
public void testDefaultProperty() throws IOException {
Credentials credentials = new Credentials(false, null);
UserCredentials userCredentials = new UserCredentials();
UsernamePassword up1 = new UsernamePassword("user2", "password");
userCredentials.putUsernamePassword("hive(vertica)", up1);
credentials.putUserCredentials("user1", userCredentials);
UserCredentials uc2 = credentials.getUserCredentials("user1");
UsernamePassword up2 = uc2.getUsernamePassword("hive(vertica)");
assertEquals(up1.getUsername(), up2.getUsername());
assertEquals(up1.getPassword(), up2.getPassword());
}
}
Loading