/*
 * 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:
//     05/28/2008-1.0M8 Andrei Ilitchev.
//       - New file introduced for bug 224964: Provide support for Proxy Authentication through JPA.
package org.eclipse.persistence.testing.tests.proxyauthentication.thin;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import oracle.jdbc.OracleConnection;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.testing.framework.oracle.SessionExchanger;

/**
 * Initializes and holds user names and properties used by for thin and jpa ProxyAuthentication tests.
 */
public class ProxyAuthenticationUsersAndProperties {
    // specify connectionUser in a System property PA_CONNECTION_USER, otherwise connectionUserDefault is used.
    public static final String PA_CONNECTION_USER = "pa.connection.user";
    public static String connectionUserDefault = "PA_CONN";

    // specify connectionPassword in a System property PA_CONNECTION_PASSWORD, otherwise connectionPasswordDefault is used.
    public static final String PA_CONNECTION_PASSWORD = "pa.connection.password";
    public static String connectionPasswordDefault = "PA_CONN";

    // specify proxyUser in a System property PA_PROXYUSER, otherwise proxyUserDefault is used.
    public static final String PA_PROXYUSER = "pa.proxyuser";
    public static String proxyUserDefault = "PA_PROXY";

    // specify proxyUser in a System property PA_PROXYUSERPWD, otherwise proxyUserPasswordDefault is used.
    public static final String PA_PROXYUSERPWD = "pa.proxyuser.password";
    public static String proxyUserPasswordDefault = "PA_PROXY";

    // specify proxyUser2 in a System property PA_PROXYUSER2, otherwise proxyUser2Default is used.
    public static final String PA_PROXYUSER2 = "pa.proxyuser2";
    public static String proxyUser2Default = "PA_PROXY2";

    // specify proxyUser2 in a System property PA_PROXYUSER2PWD, otherwise proxyUser2PasswordDefault is used.
    public static final String PA_PROXYUSER2PWD = "pa.proxyuser2.password";
    public static String proxyUser2PasswordDefault = "PA_PROXY2";

    /** to setup Proxy Authentication users in Oracle db, need to execute in sqlPlus or EnterpriseManager
     * (sql in the following example uses default names):
    1 - Connect as sysdba
    connect sys/password as sysdba

    2 - Create connectionUser:
    create user PA_CONN identified by PA_CONN
    grant connect to PA_CONN

    3 - Create proxyUsers:
    create user PA_PROXY identified by PA_PROXY
    grant connect to PA_PROXY

    create user PA_PROXY2 identified by PA_PROXY2
    grant connect to PA_PROXY2

    4. Grant proxyUsers connection through connUser
    alter user PA_PROXY grant connect through PA_CONN
    alter user PA_PROXY2 grant connect through PA_CONN
    */

    public static String connectionUser;
    public static String connectionPassword;
    public static String proxyUser;
    public static String proxyUserPassword;
    public static String proxyUser2;
    public static String proxyUser2Password;

    public static Properties connectionProperties;
    public static Map proxyProperties;
    public static Map proxyProperties2;
    public static Map cancelProxyProperties;

    public static String getProperty(String property, String defaultValue) {
        String propertyValue = System.getProperty(property);

        if (propertyValue == null || propertyValue.equals("")) {
            return defaultValue;
        } else {
            return propertyValue;
        }
    }

    /*
     * Create all user names and properties.
     */
    public static void initialize() {
        // obtain user and password that should be used to connect to the db.
        connectionUser = getProperty(PA_CONNECTION_USER, connectionUserDefault);
        connectionPassword = getProperty(PA_CONNECTION_PASSWORD, connectionPasswordDefault);
        // connectionProperties used to connect to the db to test the users
        connectionProperties = new Properties();
        connectionProperties.setProperty("user", connectionUser);
        connectionProperties.setProperty("password", connectionPassword);

        // obtain proxyuser, put into proxyProperties.
        // proxyProperties could be used either by ServerSession or ClientSession (EMFactory or EntityManager).
        proxyUser = getProperty(PA_PROXYUSER, proxyUserDefault);
        proxyUserPassword = getProperty(PA_PROXYUSERPWD, proxyUserPasswordDefault);
        proxyProperties = new HashMap(3);
        proxyProperties.put(PersistenceUnitProperties.ORACLE_PROXY_TYPE, OracleConnection.PROXYTYPE_USER_NAME);
        proxyProperties.put(OracleConnection.PROXY_USER_NAME, proxyUser);
        proxyProperties.put(OracleConnection.PROXY_USER_PASSWORD, proxyUserPassword);

        // obtain proxyuser2, put into proxyProperties2.
        // proxyProperties2 could be used by ClientSession (EntityManager) to override proxyProperties used by ServerSession (EMFactory).
        proxyUser2 = getProperty(PA_PROXYUSER2, proxyUser2Default);
        proxyUser2Password = getProperty(PA_PROXYUSER2PWD, proxyUser2PasswordDefault);
        proxyProperties2 = new HashMap(3);
        proxyProperties2.put(PersistenceUnitProperties.ORACLE_PROXY_TYPE, OracleConnection.PROXYTYPE_USER_NAME);
        proxyProperties2.put(OracleConnection.PROXY_USER_NAME, proxyUser2);
        proxyProperties2.put(OracleConnection.PROXY_USER_PASSWORD, proxyUser2Password);

        // cancelProxyProperties could be used by ClientSession (EntityManager) to NOT to use proxyProperties used by ServerSession (EMFactory).
        cancelProxyProperties = new HashMap(1);
        cancelProxyProperties.put(PersistenceUnitProperties.ORACLE_PROXY_TYPE, "");
    }

    /*
     * Verify all the users correctly setup in the database.
     * Returns an empty string in case of success, otherwise returns the error message.
     */
    public static String verify(DatabaseSession dbSession) {
        String errorMsg = "";
        SessionExchanger exchanger = new SessionExchanger();
        DatabaseSession newSession = null;
        try {
            // create a simple database session that uses connectionProperties to connect.
            newSession = exchanger.createNewSession(dbSession, true, false, connectionProperties, null);
        } catch (Exception exception) {
            errorMsg = createErrorMsgConnectionFailed();
            errorMsg += createErrorMsgProxyFailed(true);
            errorMsg += createErrorMsgProxy2Failed(true);
        }

        // errorMsg.length() > 0 case:
        // if couldn't connect to connectionUser directly then there is
        // no point in trying to connect proxyUsers through connectionUser.
        if(errorMsg.length() == 0) {
            // try to open proxy session using proxyUser
            try {
                Properties props = new Properties();
                props.setProperty(OracleConnection.PROXY_USER_NAME, proxyUser);
                props.setProperty(OracleConnection.PROXY_USER_PASSWORD, proxyUserPassword);
                OracleConnection oracleConnection = (oracle.jdbc.OracleConnection)((org.eclipse.persistence.internal.sessions.AbstractSession)newSession).getAccessor().getConnection();
                oracleConnection.openProxySession(OracleConnection.PROXYTYPE_USER_NAME, props);
                // close proxy session
                oracleConnection.close(OracleConnection.PROXY_SESSION);
            } catch (Exception exception) {
                errorMsg += createErrorMsgProxyFailed(false);
            }

            // try to open proxy session using proxyUser2
            try {
                Properties props = new Properties();
                props.setProperty(OracleConnection.PROXY_USER_NAME, proxyUser2);
                props.setProperty(OracleConnection.PROXY_USER_PASSWORD, proxyUser2Password);
                OracleConnection oracleConnection = (oracle.jdbc.OracleConnection)((org.eclipse.persistence.internal.sessions.AbstractSession)newSession).getAccessor().getConnection();
                oracleConnection.openProxySession(OracleConnection.PROXYTYPE_USER_NAME, props);
                // close proxy session
                oracleConnection.close(OracleConnection.PROXY_SESSION);
            } catch (Exception exception) {
                errorMsg += createErrorMsgProxy2Failed(false);
            }
        }

        // kill newSession, reconnect the original session.
        exchanger.returnOriginalSession();

        return errorMsg;
    }

    static String createErrorMsgConnectionFailed() {
        // failed to connect using connectionUser / connectionPassword
        String str1 = "Failed to connect using user = "+ connectionUser + "; password = " +connectionPassword+".\n";
        String str2 = "Specify connectionUser in "+PA_CONNECTION_USER+" and connectionPassword in "+PA_CONNECTION_PASSWORD+" System properties.\n";
        String str3 = "Otherwise default connectionUser "+ connectionUserDefault +" and default connectionPassword "+ connectionPasswordDefault + " used.\n";
        String str4 = "In the db connectionUser should exist (authenticated by connectionPassword) and be authorized to connect:\n";
        String str5 = " create user "+connectionUser+" identified by "+connectionPassword+"\n";
        String str6 = " grant connect to "+connectionUser+"\n";
        return str1 + str2 + str3 + str4 + str5 + str6;
    }

    static String createErrorMsgProxyFailed(boolean connectionHasFailed) {
        // failed to open proxy session using proxyUser
        String str1 = "";
        if(!connectionHasFailed) {
            // printing this because connection was ok, but proxy connection failed.
            str1 = "Failed to open proxy session using proxyUser = "+ proxyUser+" on connection through "+connectionUser+".\n";
        }
        String str2 = "Specify proxyUser in "+PA_PROXYUSER+" System property. Otherwise default proxyUser "+ proxyUserDefault + " is used.\n";
        String str3 = "In the db proxyUser should exist and be authorized to connect both directly and through connectionUser:\n";
        String str4 = " create user "+proxyUser+" identified by "+proxyUser+"\n";
        String str5 = " grant connect to "+proxyUser+"\n";
        String str6 = " grant connect to "+proxyUser+" through "+connectionUser+"\n";
        return str1 + str2 + str3 + str4 + str5 + str6;
    }

    static String createErrorMsgProxy2Failed(boolean connectionHasFailed) {
        // failed to open proxy session using proxyUser2
        String str1 = "";
        if(!connectionHasFailed) {
            // printing this because connection was ok, but proxy connection failed.
            str1 = "Failed to open proxy session using proxyUser2 = "+ proxyUser2+" on connection through "+connectionUser+".\n";
        }
        String str2 = "Specify proxyUser2 in "+PA_PROXYUSER+" System property. Otherwise default proxyUser2 "+ proxyUser2Default + " is used.\n";
        String str3 = "In the db proxyUser2 should exist and be authorized to connect both directly and through connectionUser:\n";
        String str4 = " create user "+proxyUser2+" identified by "+proxyUser2+"\n";
        String str5 = " grant connect to "+proxyUser2+"\n";
        String str6 = " grant connect to "+proxyUser2+" through "+connectionUser+"\n";
        return str1 + str2 + str3 + str4 + str5 + str6;
    }
}
