/*
* 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.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
/**
* 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);
saveCredentials();
}
public UserCredentials removeUserCredentials(String username) throws IOException {
UserCredentials uc;
uc = credentialsMap.remove(username);
saveCredentials();
return uc;
}
public boolean removeCredentialEntity(String username, String entity) throws IOException {
UserCredentials uc = credentialsMap.get(username);
if (uc != null && uc.existUsernamePassword(entity) == false) {
return false;
}
uc.removeUsernamePassword(entity);
saveCredentials();
return true;
}
public void saveCredentials() throws IOException {
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();
Set<PosixFilePermission> permissions = EnumSet.of(OWNER_READ, OWNER_WRITE);
Files.setPosixFilePermissions(credentialsFile.toPath(), permissions);
}
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);
}
}
}