/*
 * 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.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 = new sun.misc.BASE64Encoder().encode(auth.getBytes());
                        c1.setRequestProperty("Authorization", "Basic " + authEncoded);
                }
                c1.setDoOutput(true);
                c1.setUseCaches(false);

                // get the output stream to POST to.
                DataOutputStream out;
                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;
        }
}
