/*
 * Copyright (c) 1998, 2020 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.sessions.factories.model.transport.naming;

import java.util.Vector;
import org.eclipse.persistence.internal.security.SecurableObjectHolder;

/**
 * INTERNAL:
 */
public class JNDINamingServiceConfig {
    private String m_url;
    private String m_username;
    private char[] m_encryptedPassword;
    private SecurableObjectHolder m_securableObjectHolder;
    private String m_initialContextFactoryName;
    private Vector m_propertyConfigs;

    public JNDINamingServiceConfig() {
        // Without setting the encryption class name the object holder will
        // default to JCE.
        m_securableObjectHolder = new SecurableObjectHolder();
    }

    public void setURL(String url) {
        m_url = url;
    }

    public String getURL() {
        return m_url;
    }

    public void setUsername(String username) {
        m_username = username;
    }

    public String getUsername() {
        return m_username;
    }

    public void setEncryptionClass(String encryptionClass) {
        m_securableObjectHolder.setEncryptionClassName(encryptionClass);
    }

    public String getEncryptionClass() {
        return m_securableObjectHolder.getEncryptionClassName();
    }

    /**
     * This method will always encrypt the password regardless. Should only
     * ever be called from the Mapping Workbench.
     * It can be called before setting an encryption class, therefore, the
     * securable object initialization remains in the constructor with default
     * to JCE and changes only if an encryption class is set.
     *
     * @param password
     */
    public void setPassword(String password) {
        setEncryptedPassword(password);
    }

    /**
     * This method should never be called from the Mapping Workbench. Instead it
     * is called only at load time of a schema formatted sessions.xml file. It
     * assumes the password is encrypted.
     *
     * @param encryptedPassword
     */
    public void setEncryptedPassword(String encryptedPassword) {
        // Bug 4117441 - Secure programming practices, store password in char[]
        if (encryptedPassword == null) {
            // respect explicit de-referencing of password
            m_encryptedPassword = null;
        } else if (encryptedPassword.length() == 0) {
            m_encryptedPassword = new char[0];
        } else {
            // If the decrypted password is the same as the encrypted one then
            // it was not encrypted so make sure to store the encrypted password.
            if (encryptedPassword.equals(m_securableObjectHolder.getSecurableObject().decryptPassword(encryptedPassword))) {
                m_encryptedPassword = m_securableObjectHolder.getSecurableObject().encryptPassword(encryptedPassword).toCharArray();
            } else {
                m_encryptedPassword = encryptedPassword.toCharArray();
            }
        }
    }

    /**
     * This method will return the decrypted password. This method should
     * only be called by the Mapping Workbench.
     *
     * @return decryptedPassword
     */
    public String getPassword() {
        return m_securableObjectHolder.getSecurableObject().decryptPassword(getEncryptedPassword());
    }

    /**
     * Assume the password has been encrypted and return it.
     *
     * @return encryptedPassword
     */
    public String getEncryptedPassword() {
        // Bug 4117441 - Secure programming practices, create password String from char[]
        if (m_encryptedPassword != null) {
            return new String(m_encryptedPassword);
        } else {
            // respect explicit de-referencing of password
            return null;
        }
    }

    public void setInitialContextFactoryName(String initialContextFactoryName) {
        m_initialContextFactoryName = initialContextFactoryName;
    }

    public String getInitialContextFactoryName() {
        return m_initialContextFactoryName;
    }

    public void setPropertyConfigs(Vector propertyConfigs) {
        m_propertyConfigs = propertyConfigs;
    }

    public Vector getPropertyConfigs() {
        return m_propertyConfigs;
    }
}
