All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.config.support.TranslatedConfigView Maven / Gradle / Ivy

There is a newer version: 8.0.0-JDK17-M7
Show newest version
/*
 * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation.
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.config.support;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import org.glassfish.security.common.RelativePathResolver;
import org.glassfish.hk2.api.ServiceLocator;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.jvnet.hk2.config.ConfigView;

import com.sun.enterprise.security.store.DomainScopedPasswordAliasStore;

/**
 * View that translate configured attributes containing properties like ${foo.bar} into system properties values.
 *
 * @author Jerome Dochez
 */
public class TranslatedConfigView implements ConfigView {

    final static Pattern p = Pattern.compile("([^\\$]*)\\$\\{([^\\}]*)\\}([^\\$]*)");

    private static final String ALIAS_TOKEN = "ALIAS";
    private static int MAX_SUBSTITUTION_DEPTH = 100;

    public static String expandValue(String value) {
        return (String) getTranslatedValue(value);
    }

    public static Object getTranslatedValue(Object value) {
        if (value != null && value instanceof String) {
            String stringValue = value.toString();
            if (stringValue.indexOf('$') == -1) {
                return value;
            }
            if (domainPasswordAliasStore() != null) {
                if (getAlias(stringValue) != null) {
                    try {
                        return getRealPasswordFromAlias(stringValue);
                    } catch (Exception e) {
                        Logger.getAnonymousLogger()
                                .severe(Strings.get("TranslatedConfigView.aliaserror", stringValue, e.getLocalizedMessage()));
                        return stringValue;
                    }
                }
            }

            // Perform system property substitution in the value
            // The loop limit is imposed to prevent infinite looping to values
            // such as a=${a} or a=foo ${b} and b=bar {$a}
            Matcher m = p.matcher(stringValue);
            String origValue = stringValue;
            int i = 0;
            while (m.find() && i < MAX_SUBSTITUTION_DEPTH) {
                String newValue = System.getProperty(m.group(2).trim());
                if (newValue != null) {
                    stringValue = m.replaceFirst(Matcher.quoteReplacement(m.group(1) + newValue + m.group(3)));
                    m.reset(stringValue);
                }
                i++;
            }
            if (i >= MAX_SUBSTITUTION_DEPTH) {
                Logger.getAnonymousLogger().severe(Strings.get("TranslatedConfigView.badprop", i, origValue));
            }
            return stringValue;
        }
        return value;
    }

    final ConfigView masterView;

    TranslatedConfigView(ConfigView master) {
        this.masterView = master;

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return getTranslatedValue(masterView.invoke(proxy, method, args));
    }

    @Override
    public ConfigView getMasterView() {
        return masterView; //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void setMasterView(ConfigView view) {
        // immutable implementation
    }

    @Override
    public  Class getProxyType() {
        return masterView.getProxyType();
    }

    @Override
    public  T getProxy(Class proxyType) {
        return proxyType.cast(Proxy.newProxyInstance(proxyType.getClassLoader(), new Class[] { proxyType }, this));
    }

    static ServiceLocator habitat;

    public static void setHabitat(ServiceLocator h) {
        habitat = h;
    }

    private static DomainScopedPasswordAliasStore domainPasswordAliasStore = null;

    private static DomainScopedPasswordAliasStore domainPasswordAliasStore() {
        domainPasswordAliasStore = AccessController.doPrivileged(new PrivilegedAction() {
            @Override
            public DomainScopedPasswordAliasStore run() {
                return habitat.getService(DomainScopedPasswordAliasStore.class);
            }
        });
        return domainPasswordAliasStore;
    }

    /**
     * check if a given property name matches AS alias pattern ${ALIAS=aliasname}. if so, return the aliasname, otherwise
     * return null.
     *
     * @param propName The property name to resolve. ex. ${ALIAS=aliasname}.
     * @return The aliasname or null.
     */
    static public String getAlias(String propName) {
        String aliasName = null;
        String starter = "${" + ALIAS_TOKEN + "="; //no space is allowed in starter
        String ender = "}";

        propName = propName.trim();
        if (propName.startsWith(starter) && propName.endsWith(ender)) {
            propName = propName.substring(starter.length());
            int lastIdx = propName.length() - 1;
            if (lastIdx > 1) {
                propName = propName.substring(0, lastIdx);
                aliasName = propName.trim();
            }
        }
        return aliasName;
    }

    public static String getRealPasswordFromAlias(final String at)
            throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {

        final String an = getAlias(at);
        final boolean exists = domainPasswordAliasStore.containsKey(an);
        if (!exists) {

            final String msg = String.format("Alias  %s does not exist", an);
            throw new IllegalArgumentException(msg);
        }
        final String real = new String(domainPasswordAliasStore.get(an));
        return (real);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy