Github user necouchman commented on a diff in the pull request:

    https://github.com/apache/guacamole-client/pull/336#discussion_r240048911
  
    --- Diff: 
extensions/guacamole-auth-vault/modules/guacamole-auth-vault-base/src/main/java/org/apache/guacamole/auth/vault/user/VaultUserContext.java
 ---
    @@ -0,0 +1,325 @@
    +/*
    + * 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.guacamole.auth.vault.user;
    +
    +import com.google.inject.Inject;
    +import com.google.inject.assistedinject.Assisted;
    +import com.google.inject.assistedinject.AssistedInject;
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.concurrent.ExecutionException;
    +import java.util.concurrent.Future;
    +import org.apache.guacamole.GuacamoleException;
    +import org.apache.guacamole.GuacamoleServerException;
    +import org.apache.guacamole.auth.vault.conf.VaultConfigurationService;
    +import org.apache.guacamole.net.auth.Connection;
    +import org.apache.guacamole.net.auth.ConnectionGroup;
    +import org.apache.guacamole.net.auth.TokenInjectingUserContext;
    +import org.apache.guacamole.net.auth.UserContext;
    +import org.apache.guacamole.auth.vault.secret.VaultSecretService;
    +import org.apache.guacamole.protocol.GuacamoleConfiguration;
    +import org.apache.guacamole.token.GuacamoleTokenUndefinedException;
    +import org.apache.guacamole.token.TokenFilter;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +/**
    + * UserContext implementation which automatically injects tokens 
containing the
    + * values of secrets retrieved from a vault.
    + */
    +public class VaultUserContext extends TokenInjectingUserContext {
    +
    +    /**
    +     * Logger for this class.
    +     */
    +    private final Logger logger = 
LoggerFactory.getLogger(VaultUserContext.class);
    +
    +    /**
    +     * The name of the token which will be replaced with the username of 
the
    +     * current user if specified within the name of a secret. This token
    +     * applies to both connections and connection groups.
    +     */
    +    private static final String USERNAME_TOKEN = "GUAC_USERNAME";
    +
    +    /**
    +     * The name of the token which will be replaced with the name of the
    +     * current connection group if specified within the name of a secret. 
This
    +     * token only applies only to connection groups.
    +     */
    +    private static final String CONNECTION_GROUP_NAME_TOKEN = 
"CONNECTION_GROUP_NAME";
    +
    +    /**
    +     * The name of the token which will be replaced with the identifier of 
the
    +     * current connection group if specified within the name of a secret. 
This
    +     * token only applies only to connection groups.
    +     */
    +    private static final String CONNECTION_GROUP_IDENTIFIER_TOKEN = 
"CONNECTION_GROUP_ID";
    +
    +    /**
    +     * The name of the token which will be replaced with the \"hostname\"
    +     * connection parameter of the current connection if specified within 
the
    +     * name of a secret. This token only applies only to connections.
    +     */
    +    private static final String CONNECTION_HOSTNAME_TOKEN = 
"CONNECTION_HOSTNAME";
    +
    +    /**
    +     * The name of the token which will be replaced with the \"username\"
    +     * connection parameter of the current connection if specified within 
the
    +     * name of a secret. This token only applies only to connections.
    +     */
    +    private static final String CONNECTION_USERNAME_TOKEN = 
"CONNECTION_USERNAME";
    +
    +    /**
    +     * The name of the token which will be replaced with the name of the
    +     * current connection if specified within the name of a secret. This 
token
    +     * only applies only to connections.
    +     */
    +    private static final String CONNECTION_NAME_TOKEN = "CONNECTION_NAME";
    +
    +    /**
    +     * The name of the token which will be replaced with the identifier of 
the
    +     * current connection if specified within the name of a secret. This 
token
    +     * only applies only to connections.
    +     */
    +    private static final String CONNECTION_IDENTIFIER_TOKEN = 
"CONNECTION_ID";
    +
    +    /**
    +     * Service for retrieving configuration information.
    +     */
    +    @Inject
    +    private VaultConfigurationService confService;
    +
    +    /**
    +     * Service for retrieving the values of secrets stored in a vault.
    +     */
    +    @Inject
    +    private VaultSecretService secretService;
    +
    +    /**
    +     * Creates a new VaultUserContext which automatically injects tokens
    +     * containing values of secrets retrieved from a vault. The given
    +     * UserContext is decorated such that connections and connection groups
    +     * will receive additional tokens during the connection process.
    +     *
    +     * Note that this class depends on concrete implementations of the
    +     * following classes to be provided via dependency injection:
    +     *
    +     *     - VaultConfigurationService
    +     *     - VaultSecretService
    +     *
    +     * Bindings providing these concrete implementations will need to be
    +     * provided by subclasses of VaultAuthenticationProviderModule for each
    +     * supported vault.
    +     *
    +     * @param userContext
    +     *     The UserContext instance to decorate.
    +     */
    +    @AssistedInject
    +    public VaultUserContext(@Assisted UserContext userContext) {
    +        super(userContext);
    +    }
    +
    +    /**
    +     * Creates a new TokenFilter instance with token values set for all 
tokens
    +     * which are not specific to connections or connection groups. 
Currently,
    +     * this is only the username token ("GUAC_USERNAME").
    +     *
    +     * @return
    +     *     A new TokenFilter instance with token values set for all tokens
    +     *     which are not specific to connections or connection groups.
    +     */
    +    private TokenFilter createFilter() {
    +        TokenFilter filter = new TokenFilter();
    +        filter.setToken(USERNAME_TOKEN, self().getIdentifier());
    +        return filter;
    +    }
    +
    +    /**
    +     * Initiates asynchronous retrieval of all applicable tokens and
    +     * corresponding values from the vault, using the given TokenFilter to
    +     * filter tokens within the secret names prior to retrieving those 
secrets.
    +     *
    +     * @param tokenMapping
    +     *     The mapping dictating the name of the secret which maps to each
    +     *     parameter token, where the key is the name of the parameter 
token
    +     *     and the value is the name of the secret. The name of the secret
    +     *     may contain its own tokens, which will be substituted using 
values
    +     *     from the given filter.
    +     *
    +     * @param filter
    +     *     The filter to use to substitute values for tokens in the names 
of
    +     *     secrets to be retrieved from the vault.
    +     *
    +     * @return
    +     *     A Map of token name to Future, where each Future represents the
    +     *     pending retrieval operation which will ultimately be completed 
with
    +     *     the value of all secret mapped to that token.
    +     *
    +     * @throws GuacamoleException
    +     *     If the value for any applicable secret cannot be retrieved from 
the
    +     *     vault due to an error.
    +     */
    +    private Map<String, Future<String>> getTokens(Map<String, String> 
tokenMapping,
    +            TokenFilter filter) throws GuacamoleException {
    +
    +        // Populate map with pending secret retrieval operations 
corresponding
    +        // to each mapped token
    +        Map<String, Future<String>> pendingTokens = new 
HashMap<>(tokenMapping.size());
    +        for (Map.Entry<String, String> entry : tokenMapping.entrySet()) {
    +
    +            // Translate secret pattern into secret name, ignoring any
    +            // secrets which cannot be translated
    +            String secretName;
    +            try {
    +                secretName = 
secretService.canonicalize(filter.filterStrict(entry.getValue()));
    +            }
    +            catch (GuacamoleTokenUndefinedException e) {
    +                logger.debug("Secret for token \"{}\" will not be 
retrieved. "
    +                        + "Token \"{}\" within mapped secret name has no "
    +                        + "defined value in the current context.",
    +                        entry.getKey(), e.getTokenName());
    +                continue;
    +            }
    +
    +            // Initiate asynchronous retrieval of the token value
    +            String tokenName = entry.getKey();
    +            Future<String> secret = secretService.getValue(secretName);
    +            pendingTokens.put(tokenName, secret);
    +
    +        }
    +
    +        return pendingTokens;
    +
    +    }
    +
    +    /**
    +     * Waits for all pending secret retrieval operations to complete,
    +     * transforming each Future within the given Map into its contained 
String
    +     * value.
    +     *
    +     * @param pendingTokens
    +     *     A Map of token name to Future, where each Future represents the
    +     *     pending retrieval operation which will ultimately be completed 
with
    +     *     the value of all secret mapped to that token.
    +     *
    --- End diff --
    
    Missing `@return` tag.


---

Reply via email to