/*
 * Copyright (c) 1998, 2021 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.
     *
     */
    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.
     *
     */
    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;
    }
}
