/*
 * Copyright (c) 2013, 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.jacc.test.mr8;

import java.net.*;
import java.io.*;
import java.util.Base64;
import java.util.Enumeration;
import java.util.Hashtable;

import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

public class Client {
        private static SimpleReporterAdapter stat = new SimpleReporterAdapter("appserv-tests");
        private static String testSuite = "Security::JACCMR8";
        private static String contextPath = "/jaccmr8";

        private String host;
        private String port;
        private String username;
        private String password;
        private String rolename;
        private String otheruser;
        private String ejbmode = "None";

        public static void main(String[] args) {
                stat.addDescription(testSuite);
                Client client = new Client(args);
                client.doTests();
                stat.printSummary();
        }

        public Client(String[] args) {
                host = args[0];
                port = args[1];
                username = args[2];
                password = args[3];
                rolename = args[4];
                otheruser = args[5];
                System.out.println("      Host: " + host);
                System.out.println("      Port: " + port);
                System.out.println("  Username: " + username);
                System.out.println("  Rolename: " + rolename);
                System.out.println("Other User: " + otheruser);
        }

        public void doTests() {
                // Use the stateful EJB inside the servlet
                // The stateful EJB uses annotations to protect the EJB
                ejbmode = "stateful";
                testAnyAuthUser();
                testAnyAuthUserOther();
                testAnyAuthUserNone();
                testDenyUncovered();
                testDenyUncoveredOther();
                testDenyUncoveredNone();
                testStar();
                testStarOther();
                testStarNone();
                testServlet();
                testServletOther();
                testServletNone();
                testAuthUser();
                testAuthUserOther();
                testAuthUserNone();

                // Use the stateless EJB inside the servlet
                // The stateless EJB uses the deployment descriptor to protect the EJB
                // Only repeat tests that actually can invoke the servlet
                ejbmode = "stateless";
                testAnyAuthUser();
                testAnyAuthUserOther();
                testStar();
                testAuthUser();
                testServlet();
                testServletOther();
                testServletNone();
        }

        public void testAnyAuthUser() {
                String servlet = "/anyauthuser";
                String description = servlet+"-"+username+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, username, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,true,true,true,true,true,true);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testAnyAuthUserOther() {
                String servlet = "/anyauthuser";
                String description = servlet+"-"+otheruser+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, otheruser, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,false,true,true,false,false,true);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testAnyAuthUserNone() {
                String servlet = "/anyauthuser";
                String description = servlet+"--"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 401, null, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testAuthUser() {
                String servlet = "/authuser";
                String description = servlet+"-"+username+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, username, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,true,true,true,true,true,true);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testAuthUserOther() {
                String servlet = "/authuser";
                String description = servlet+"-"+otheruser+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 403, otheruser, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testAuthUserNone() {
                String servlet = "/authuser";
                String description = servlet+"--"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 401, null, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testStar() {
                String servlet = "/star";
                String description = servlet+"-"+username+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, username, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,true,true,true,true,true,true);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testStarOther() {
                String servlet = "/star";
                String description = servlet+"-"+otheruser+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 403, otheruser, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testStarNone() {
                String servlet = "/star";
                String description = servlet+"--"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 401, null, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testServlet() {
                String servlet = "/servlet";
                String description = servlet+"-"+username+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, username, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,false,false,false,false,false,false);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testServletOther() {
                String servlet = "/servlet";
                String description = servlet+"-"+otheruser+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, otheruser, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,false,false,false,false,false,false);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testServletNone() {
                String servlet = "/servlet";
                String description = servlet+"--"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 200, null, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // Check results in output
                success = checkResults(output,false,false,false,false,false,false);
                if (!success) {
                        System.out.println("Incorrect results:" + description);
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                stat.addStatus(description, stat.PASS);
        }

        public void testDenyUncovered() {
                String servlet = "/denyuncoveredpost";
                String description = servlet+"-"+username+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 403, username, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testDenyUncoveredOther() {
                String servlet = "/denyuncoveredpost";
                String description = servlet+"-"+otheruser+"-"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 403, otheruser, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        public void testDenyUncoveredNone() {
                String servlet = "/denyuncoveredpost";
                String description = servlet+"--"+ejbmode;
                StringBuffer output = new StringBuffer();
                boolean success = doIndividualTest(servlet, 403, null, ejbmode, output);
                if (!success) {
                        stat.addStatus(description, stat.FAIL);
                        return;
                }

                // No results to check!
                stat.addStatus(description, stat.PASS);
        }

        // Validate that all the passed in results are as expected
        // If any value is not as expected the overall results are false
        private boolean checkResults(StringBuffer results,
                        boolean EJBisCallerInRole, boolean EJBisUserInAnyAuthUserRole,
                        boolean EJBInvokeAnyAuthUser, boolean EJBInvokeAuthUser,
                        boolean WEBisUserInRole, boolean WEBisUserInAnyAuthUserRole) {
                int index;
                boolean result = true;

                if (EJBisCallerInRole)
                        index = results.indexOf("EJB isCallerInRole: true");
                else
                        index = results.indexOf("EJB isCallerInRole: false");
                if (index == -1)
                        result = false;

                if (!result) return result;

                if (EJBisUserInAnyAuthUserRole)
                        index = results.indexOf("EJB isUserInAnyAuthUserRole: true");
                else
                        index = results.indexOf("EJB isUserInAnyAuthUserRole: false");
                if (index == -1)
                        result = false;

                if (!result) return result;

                if (WEBisUserInRole)
                        index = results.indexOf("WEB isUserInRole: true");
                else
                        index = results.indexOf("WEB isUserInRole: false");
                if (index == -1)
                        result = false;

                if (!result) return result;

                if (WEBisUserInAnyAuthUserRole)
                        index = results.indexOf("WEB isUserInAnyAuthUserRole: true");
                else
                        index = results.indexOf("WEB isUserInAnyAuthUserRole: false");
                if (index == -1)
                        result = false;

                if (!result) return result;

                index = results.indexOf("EJB Invoke AnyAuthUser: Yes");
                if (EJBInvokeAnyAuthUser)
                        result = (index != -1);
                else
                        result = (index == -1);

                if (!result) return result;

                index = results.indexOf("EJB Invoke AuthUser: Yes");
                if (EJBInvokeAuthUser)
                        result = (index != -1);
                else
                        result = (index == -1);

                return result;
        }

        private boolean doIndividualTest(String servlet, int code, String user, String mode, StringBuffer output) {
                boolean result = false;
                try {
                        int rtncode;
                        String url = "http://" + host + ":" + port + contextPath + servlet;

                        Hashtable ht = new Hashtable();
                        ht.put("mode", URLEncoder.encode(mode,"UTF-8"));
                        ht.put("name", URLEncoder.encode(rolename,"UTF-8"));

                        System.out.println("\nInvoking servlet at " + url);
                        rtncode = invokeServlet(url, ht, user, output);
                        System.out.println("The servlet return code: " + rtncode);
                        if (rtncode != code) {
                                System.out.println("Incorrect return code, expecting: " + code);
                        }
                        else result = true;
                } catch (Exception ex) {
                        System.out.println("Exception: " + ex.toString());
                        //ex.printStackTrace();
                }
                return result;
        }

        private int invokeServlet(String url, Hashtable contentHash, String user, StringBuffer output) throws Exception {
                URL u = new URL(url);
                HttpURLConnection c1 = (HttpURLConnection) u.openConnection();
                c1.setAllowUserInteraction(true);
                if ((user != null) && (user.length() > 0)) {
                        // Add BASIC header for authentication
                        String auth =  user + ":" + password;
                        String authEncoded = Base64.getEncoder().encodeToString(auth.getBytes());
                        c1.setRequestProperty("Authorization", "Basic " + authEncoded);
                }
                c1.setDoOutput(true);
                c1.setUseCaches(false);

                // get the output stream to POST to.
                DataOutputStream out = new DataOutputStream(c1.getOutputStream());
                String content = "";

                // Create a single String value to be POSTED from the parameters passed
                // to us. This is done by making "name"="value" pairs for all the keys
                // in the Hashtable passed to us.
                Enumeration e = contentHash.keys();
                boolean first = true;
                while (e.hasMoreElements()) {
                        // For each key and value pair in the hashtable
                        Object key = e.nextElement();
                        Object value = contentHash.get(key);

                        // If this is not the first key-value pair in the hashtable,
                        // concantenate an "&" sign to the constructed String
                        if (!first)
                                content += "&";

                        // append to a single string. Encode the value portion
                        content += (String) key + "=" + URLEncoder.encode((String) value,"UTF-8");

                        first = false;
                }

                // Write out the bytes of the content string to the stream.
                out.writeBytes(content);
                out.flush();
                out.close();

                // Connect and get the response code and/or output to verify
                c1.connect();
                int code = c1.getResponseCode();
                if (code == HttpURLConnection.HTTP_OK) {
                        InputStream is = null;
                        BufferedReader input = null;
                        String line = null;
                        try {
                                is = c1.getInputStream();
                                input = new BufferedReader(new InputStreamReader(is));
                                while ((line = input.readLine()) != null) {
                                        output.append(line);
                                        System.out.println(line);
                                }
                        }
                        finally {
                                try { if (is != null) is.close(); }
                                catch (Exception exc) {}
                                try { if (input != null) input.close(); }
                                catch (Exception exc) {}
                        }
                }
                return code;
        }
}
