/*
 * Copyright (c) 2006, 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.httpservletchallenge;

import java.util.Base64;
import java.util.Map;
import java.security.AccessController;
import java.security.PrivilegedAction;
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.http.HttpSession;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


public class HttpServletChallengeTestAuthModule implements ServerAuthModule {
    private CallbackHandler handler = null;

    public void initialize(MessagePolicy requestPolicy,
               MessagePolicy responsePolicy,
               CallbackHandler handler,
               Map options)
               throws AuthException {
        this.handler = handler;
    }

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

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

        if (!isMandatory(messageInfo)) {
            return AuthStatus.SUCCESS;
        }

        String username = null;
        String password = null;
        try {

            HttpServletRequest request =
                (HttpServletRequest)messageInfo.getRequestMessage();
            String authorization = request.getHeader("authorization");
            if (authorization != null && authorization.toLowerCase().startsWith("basic ")) {
                authorization = authorization.substring(6).trim();
                byte[] bs = Base64.getDecoder().decode(authorization);
                String decodedString = new String(bs);
                int ind = decodedString.indexOf(':');
                if (ind > 0) {
                    username = decodedString.substring(0, ind);
                    password = decodedString.substring(ind + 1);
                }
            }

            HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();
            if (username == null || password == null) {
                response.setHeader("WWW-Authenticate", "Basic realm=\"default\"");
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                System.out.println("login prompt for username/password");
                return AuthStatus.SEND_CONTINUE;
            }

            HttpSession session = request.getSession(false);
            boolean secondPhase = (session != null && session.getAttribute("FIRST_DONE") != null);
            String loginName = ((secondPhase)? username + "_2" : username);
            char[] pwd = new char[password.length()];
            password.getChars(0, password.length(), pwd, 0);
            Callback[] callbacks;
            PasswordValidationCallback pwdCallback =
                new PasswordValidationCallback(clientSubject, loginName, pwd);
            if (secondPhase) {
                CallerPrincipalCallback cpCallback =
                    new CallerPrincipalCallback(clientSubject, username);
                callbacks = new Callback[] { pwdCallback, cpCallback };
            } else {
                callbacks = new Callback[] { pwdCallback };
            }
            System.out.println("Subject before invoking callbacks: " + clientSubject);
            handler.handle(callbacks);
            System.out.println("Subject after invoking callbacks: " + clientSubject);

            if (pwdCallback.getResult()) {
                System.out.print("login success: " + username + ", " + password);
                if (secondPhase) {
                    System.out.println(" for second level");
                    request.setAttribute("MY_NAME", getClass().getName());
                    messageInfo.getMap().put("jakarta.servlet.http.authType", "MC");
                    return AuthStatus.SUCCESS;
                } else {
                    System.out.println(" for first level");
                    response.setHeader("WWW-Authenticate", "Basic realm=\"default\"");
                    if (session == null) {
                        session = request.getSession(true);
                        session.setAttribute("FIRST_DONE", Boolean.TRUE);
                    }
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    return AuthStatus.SEND_SUCCESS;
                }
            } else {
                System.out.println("login fails: " + username + ", " + password);
                return AuthStatus.SEND_FAILURE;
            }
        } catch(Throwable t) {
            System.out.println("login fails: " + username + ", " + password);
            t.printStackTrace();
            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"));
    }
}
