[ 
https://issues.apache.org/jira/browse/KNOX-1687?focusedWorklogId=198901&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-198901
 ]

ASF GitHub Bot logged work on KNOX-1687:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 14/Feb/19 19:59
            Start Date: 14/Feb/19 19:59
    Worklog Time Spent: 10m 
      Work Description: risdenk commented on pull request #52: KNOX-1687 - 
Hashicorp Vault alias credential provider
URL: https://github.com/apache/knox/pull/52#discussion_r256990242
 
 

 ##########
 File path: 
gateway-hashicorp-vault/src/main/java/org/apache/knox/gateway/backend/hashicorp/vault/HashicorpVaultAliasService.java
 ##########
 @@ -0,0 +1,197 @@
+/*
+ * 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.knox.gateway.backend.hashicorp.vault;
+
+import 
org.apache.knox.gateway.backend.hashicorp.vault.authentication.HashicorpVaultClientAuthenticationProvider;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.core.VaultTemplate;
+import org.springframework.vault.core.VaultVersionedKeyValueOperations;
+import org.springframework.vault.support.Versioned;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+public class HashicorpVaultAliasService implements AliasService {
+  static final String VAULT_CONFIG_PREFIX = 
"gateway.alias.remote.hashicorp.vault.";
+  static final String VAULT_ADDRESS_KEY = "address";
+  static final String VAULT_SECRETS_ENGINE_KEY = "secrets.engine";
+
+  private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+  private static final char[] ALPHANUMERIC_CHARS = { 'a', 'b', 'c', 'd', 'e', 
'f', 'g',
+      'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+      'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
+      'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+      '2', '3', '4', '5', '6', '7', '8', '9',};
+
+  // TODO - Need to see what this looks like if someone manually enters values 
into Vault KV
+  private static final String KEY = "data";
+
+  private VaultVersionedKeyValueOperations vault;
+
+  private String getPath(String clusterName) {
+    return clusterName;
+  }
+
+  private String getPath(String clusterName, String alias) {
+    return getPath(clusterName) + '/' + alias;
+  }
+
+  @Override
+  public List<String> getAliasesForCluster(String clusterName) throws 
AliasServiceException {
+    List<String> aliases = vault.list(getPath(clusterName));
+    if(aliases == null) {
+      return Collections.emptyList();
+    }
+
+    // Required to check if list entries are valid since versioned KV does a 
soft delete
+    // Keys are still listed but do not have a value
+    for (Iterator<String> iterator = aliases.iterator(); iterator.hasNext();) {
+      String alias = iterator.next();
+      if (getPasswordFromAliasForCluster(clusterName, alias) == null) {
+        // Remove the current element from the iterator and the list.
+        iterator.remove();
+      }
+    }
+
+    return aliases;
+  }
+
+  @Override
+  public void addAliasForCluster(String clusterName, String alias, String 
value) throws AliasServiceException {
+    vault.put(getPath(clusterName, alias), Collections.singletonMap(KEY, 
value));
+  }
+
+  @Override
+  public void removeAliasForCluster(String clusterName, String alias) throws 
AliasServiceException {
+    // Delete is by default a soft delete with versioned KV in Vault
+    // 
https://learn.hashicorp.com/vault/secrets-management/sm-versioned-kv#step-6-permanently-delete-data
+    // Below is an example of how to programmatically delete all versions
+    /*
+    vaultTemplate.doWithSession(restOperations -> {
+      restOperations.delete('/' + vaultSecretsEngine + "/metadata/" + 
clusterName + '/' + alias);
+      return null;
+    });
+     */
+    vault.delete(getPath(clusterName, alias));
+  }
+
+  @Override
+  public char[] getPasswordFromAliasForCluster(String clusterName, String 
alias) throws AliasServiceException {
+    Versioned<Map<String, Object>> mapVersioned = 
vault.get(getPath(clusterName, alias));
+    if(mapVersioned != null && mapVersioned.hasData()) {
+      Map<String, Object> data = mapVersioned.getData();
+      if(data != null && data.containsKey(KEY)) {
+        return String.valueOf(data.get(KEY)).toCharArray();
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public char[] getPasswordFromAliasForCluster(String clusterName, String 
alias, boolean generate) throws AliasServiceException {
+    if(generate) {
+      getPasswordFromAliasForCluster(clusterName, alias);
+    }
+    return getPasswordFromAliasForCluster(clusterName, alias);
+  }
+
+  @Override
+  public void generateAliasForCluster(String clusterName, String alias) throws 
AliasServiceException {
+    addAliasForCluster(clusterName, alias, generatePassword(16));
+  }
+
+  private static synchronized String generatePassword(int length) {
 
 Review comment:
   Should reuse from DefaultAliasService? Maybe put in a util class?
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Issue Time Tracking
-------------------

    Worklog Id:     (was: 198901)
    Time Spent: 40m  (was: 0.5h)

> Hashicorp Vault alias credential provider
> -----------------------------------------
>
>                 Key: KNOX-1687
>                 URL: https://issues.apache.org/jira/browse/KNOX-1687
>             Project: Apache Knox
>          Issue Type: Improvement
>            Reporter: Kevin Risden
>            Assignee: Kevin Risden
>            Priority: Major
>             Fix For: 1.3.0
>
>         Attachments: KNOX-1687.patch, KNOX-1687.patch
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> Hashicorp Vault alias credential provider - more details to be added
> * https://www.vaultproject.io/
> * https://www.vaultproject.io/api/libraries.html#java



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to