/*
 * Copyright (c) 2007, 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 com.sun.s1asdev.security.jmac.httpservletform;

import java.util.Map;
import java.security.Principal;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import jakarta.security.auth.message.AuthException;
import jakarta.security.auth.message.AuthStatus;
import jakarta.security.auth.message.MessageInfo;
import jakarta.security.auth.message.MessagePolicy;
import jakarta.security.auth.message.callback.CallerPrincipalCallback;
import jakarta.security.auth.message.callback.PasswordValidationCallback;
import jakarta.security.auth.message.module.ServerAuthModule;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


public class HttpServletFormTestAuthModule implements ServerAuthModule {
    private static final String SAVED_REQUEST = "Saved_Request";
    private static final String SAVED_SUBJECT = "Saved_Subject";
    private CallbackHandler handler = null;
    private String pc = null;

    public void initialize(MessagePolicy requestPolicy,
               MessagePolicy responsePolicy,
               CallbackHandler handler,
               Map options)
               throws AuthException {
        this.handler = handler;
        if (options != null) {
            this.pc = (String)options.get("jakarta.security.jacc.PolicyContext");
        }
    }

    public Class[] getSupportedMessageTypes() {
        return new Class[] { HttpServletRequest.class, HttpServletResponse.class };
    }

    public AuthStatus validateRequest(MessageInfo messageInfo,
                               Subject clientSubject,
                               Subject serviceSubject) throws AuthException {

        String username = null;
        String password = null;
        HttpServletRequest request =
            (HttpServletRequest)messageInfo.getRequestMessage();
        HttpServletResponse response =
            (HttpServletResponse)messageInfo.getResponseMessage();

        if (!isMandatory(messageInfo) &&
                !request.getRequestURI().endsWith("/j_security_check")) {
            return AuthStatus.SUCCESS;
        }

        try {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Subject savedClientSubject = (Subject) session.getAttribute(SAVED_SUBJECT);
                if (savedClientSubject != null) {
                    System.out.println("already has saved subject");
                    // just copy principals for testing
                    clientSubject.getPrincipals().addAll(
                            savedClientSubject.getPrincipals());
                    request.setAttribute("MY_NAME", getClass().getName());
                    request.setAttribute("PC", pc);
                    return AuthStatus.SUCCESS;
                }
            }

            username = request.getParameter("j_username");
            password = request.getParameter("j_password");

            if (username == null || password == null) {
                System.out.println("forward to login form");
                if (session == null) {
                    session = request.getSession(true);
                }
                session.setAttribute(SAVED_REQUEST, new SavedRequest(request));
                RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
                rd.forward(request, response);
                System.out.println("Form: SEND_CONTINUE");
                return AuthStatus.SEND_CONTINUE;
            }

            char[] pwd = new char[password.length()];
            password.getChars(0, password.length(), pwd, 0);
            PasswordValidationCallback pwdCallback =
                new PasswordValidationCallback(clientSubject, username, pwd);
            CallerPrincipalCallback cpCallback =
                new CallerPrincipalCallback(clientSubject, username);
            System.out.println("Subject before invoking callbacks: " + clientSubject);
            handler.handle(new Callback[] { pwdCallback, cpCallback });
            System.out.println("Subject after invoking callbacks: " + clientSubject);

            if (pwdCallback.getResult()) {
                System.out.println("login success: " + username + ", " + password);
                SavedRequest sreq = null;
                if (session != null) {
                    sreq = (SavedRequest) session.getAttribute(SAVED_REQUEST);
                    // for testing only as Subject is not Serializable
                    session.setAttribute(SAVED_SUBJECT, clientSubject);
                }
                if (sreq != null) {
                    StringBuffer sb = new StringBuffer(sreq.getRequestURI());
                    if (sreq.getQueryString() != null) {
                        sb.append('?');
                        sb.append(sreq.getQueryString());
                    }
                    response.sendRedirect(
                           response.encodeRedirectURL(sb.toString()));
                    return AuthStatus.SEND_CONTINUE;
                } else {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    return AuthStatus.SEND_FAILURE;
                }
            } else {
                System.out.println("login fails: " + username + ", " + password);
                RequestDispatcher rd = request.getRequestDispatcher("error.html");
                rd.forward(request, response);
                return AuthStatus.SEND_FAILURE;
            }
        } catch(Throwable t) {
            System.out.println("login fails: " + username + ", " + password);
            t.printStackTrace();
            RequestDispatcher rd = request.getRequestDispatcher("error.html");
            try {
                rd.forward(request, response);
            } catch(Exception ex) {
                AuthException ae = new AuthException();
                ae.initCause(ex);
                throw ae;
            }
            return AuthStatus.SEND_FAILURE;
        }
    }

    public AuthStatus secureResponse(MessageInfo messageInfo,
            Subject serviceSubject) throws AuthException {
        return AuthStatus.SUCCESS;
    }

    public void cleanSubject(MessageInfo messageInfo, Subject subject)
        throws AuthException {
    }


    private boolean isMandatory(MessageInfo messageInfo) {
        return Boolean.valueOf((String)messageInfo.getMap().get(
            "jakarta.security.auth.message.MessagePolicy.isMandatory"));
    }
}
