AMBARI-24662. Support non-plain text passwords for LDAP authentication (#46)

diff --git a/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/LogSearchLdapAuthConfig.java b/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/LogSearchLdapAuthConfig.java
index 5218062..3423826 100644
--- a/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/LogSearchLdapAuthConfig.java
+++ b/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/LogSearchLdapAuthConfig.java
@@ -58,6 +58,16 @@
   )
   private String ldapManagerPassword;
 
+  @Value("${logsearch.auth.ldap.manager.password.file:}")
+  @LogSearchPropertyDescription(
+    name = "logsearch.auth.ldap.manager.password.file",
+    description = "File that contains password of the LDAP manager user.",
+    examples = {"/my/path/passwordfile"},
+    defaultValue = "",
+    sources = {LOGSEARCH_PROPERTIES_FILE}
+  )
+  private String ldapManagerPasswordFile;
+
   @Value("${logsearch.auth.ldap.base.dn:}")
   @LogSearchPropertyDescription(
     name = "logsearch.auth.ldap.base.dn",
@@ -279,4 +289,12 @@
   public void setReferralMethod(String referralMethod) {
     this.referralMethod = referralMethod;
   }
+
+  public String getLdapManagerPasswordFile() {
+    return ldapManagerPasswordFile;
+  }
+
+  public void setLdapManagerPasswordFile(String ldapManagerPasswordFile) {
+    this.ldapManagerPasswordFile = ldapManagerPasswordFile;
+  }
 }
diff --git a/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java b/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
index d75c304..22754f7 100644
--- a/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
+++ b/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
@@ -21,6 +21,8 @@
 import static javax.ws.rs.core.Response.Status.SERVICE_UNAVAILABLE;
 import static org.apache.ambari.logsearch.common.LogSearchConstants.LOGSEARCH_SESSION_ID;
 
+import java.io.File;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -50,7 +52,10 @@
 import org.apache.ambari.logsearch.web.filters.LogsearchUsernamePasswordAuthenticationFilter;
 import org.apache.ambari.logsearch.web.security.LogsearchAuthenticationProvider;
 import org.apache.ambari.logsearch.web.security.LogsearchLdapAuthenticationProvider;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.ldap.core.support.LdapContextSource;
@@ -66,7 +71,6 @@
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
-import org.springframework.security.web.header.Header;
 import org.springframework.security.web.header.HeaderWriter;
 import org.springframework.security.web.header.writers.HstsHeaderWriter;
 import org.springframework.security.web.header.writers.StaticHeadersWriter;
@@ -83,6 +87,8 @@
 @EnableWebSecurity
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
+  private static final Logger logger = LogManager.getLogger(SecurityConfig.class);
+
   @Inject
   private AuthPropsConfig authPropsConfig;
 
@@ -93,6 +99,9 @@
   private LogSearchHttpConfig logSearchHttpConfig;
 
   @Inject
+  private LogSearchSslConfig logSearchSslConfig;
+
+  @Inject
   private SolrServiceLogPropsConfig solrServiceLogPropsConfig;
 
   @Inject
@@ -178,8 +187,9 @@
       if (StringUtils.isNotBlank(authPropsConfig.getLdapAuthConfig().getLdapManagerDn())) {
         ldapContextSource.setUserDn(authPropsConfig.getLdapAuthConfig().getLdapManagerDn());
       }
-      if (StringUtils.isNotBlank(authPropsConfig.getLdapAuthConfig().getLdapManagerPassword())) {
-        ldapContextSource.setPassword(authPropsConfig.getLdapAuthConfig().getLdapManagerPassword());
+      char[] ldapPassword = getLdapManagerPassword();
+      if (ldapPassword != null) {
+        ldapContextSource.setPassword(new String(ldapPassword));
       }
       ldapContextSource.setReferral(authPropsConfig.getLdapAuthConfig().getReferralMethod());
       ldapContextSource.setAnonymousReadOnly(true);
@@ -364,6 +374,29 @@
     return new AntPathRequestMatcher("/api/v1/shipper/input/**");
   }
 
+  private char[] getLdapManagerPassword() {
+    char[] ldapPassword = null;
+    try {
+      String credentialProviderPath = logSearchSslConfig.getCredentialStoreProviderPath();
+      String ldapPasswordEnv = "LOGSEARCH_LDAP_MANAGER_PASSWORD";
+      if (StringUtils.isNotBlank(credentialProviderPath)) {
+        org.apache.hadoop.conf.Configuration config = new org.apache.hadoop.conf.Configuration();
+        config.set(LogSearchSslConfig.CREDENTIAL_STORE_PROVIDER_PATH, credentialProviderPath);
+        ldapPassword = config.getPassword("logsearch.auth.ldap.manager.password");
+      } else if (StringUtils.isNotBlank(authPropsConfig.getLdapAuthConfig().getLdapManagerPasswordFile())){
+        ldapPassword = FileUtils.readFileToString(new File(
+          authPropsConfig.getLdapAuthConfig().getLdapManagerPasswordFile()), Charset.defaultCharset()).toCharArray();
+      } else if (StringUtils.isNotBlank(System.getenv(ldapPasswordEnv))) {
+        ldapPassword = System.getenv(ldapPasswordEnv).toCharArray();
+      } else if (StringUtils.isNotBlank(authPropsConfig.getLdapAuthConfig().getLdapManagerPassword())) {
+        ldapPassword = authPropsConfig.getLdapAuthConfig().getLdapManagerPassword().toCharArray();
+      }
+    } catch (Exception e) {
+      logger.warn("Error during ldap password initialization. LDAP authentication probably won't work if a manager password will be required.", e);
+    }
+    return ldapPassword;
+  }
+
   private String[] getCookies() {
     List<String> cookies = new ArrayList<>();
     cookies.add(LOGSEARCH_SESSION_ID);