/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.authenticator;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serial;
import java.io.Serializable;
import java.security.Principal;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import jakarta.servlet.http.HttpServletRequest;

import org.apache.catalina.Session;

/**
 * A class that represents entries in the cache of authenticated users. This is necessary to make it available to
 * <code>AuthenticatorBase</code> subclasses that need it in order to perform reauthentications when SingleSignOn is in
 * use.
 *
 * @author B Stansberry, based on work by Craig R. McClanahan
 *
 * @see SingleSignOn
 * @see AuthenticatorBase#reauthenticateFromSSO
 */
public class SingleSignOnEntry implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    // ------------------------------------------------------ Instance Fields

    private String authType = null;

    private String password = null;

    // Marked as transient so special handling can be applied to serialization
    private transient Principal principal = null;

    private final Map<SingleSignOnSessionKey,SingleSignOnSessionKey> sessionKeys = new ConcurrentHashMap<>();

    private String username = null;

    private boolean canReauthenticate = false;

    // --------------------------------------------------------- Constructors

    /**
     * Creates a new SingleSignOnEntry
     *
     * @param principal the <code>Principal</code> returned by the latest call to <code>Realm.authenticate</code>.
     * @param authType  the type of authenticator used (BASIC, CLIENT_CERT, DIGEST or FORM)
     * @param username  the username (if any) used for the authentication
     * @param password  the password (if any) used for the authentication
     */
    public SingleSignOnEntry(Principal principal, String authType, String username, String password) {

        updateCredentials(principal, authType, username, password);
    }

    // ------------------------------------------------------- Package Methods

    /**
     * Adds a <code>Session</code> to the list of those associated with this SSO.
     *
     * @param sso     The <code>SingleSignOn</code> valve that is managing the SSO session.
     * @param ssoId   The ID of the SSO session.
     * @param session The <code>Session</code> being associated with the SSO.
     */
    public void addSession(SingleSignOn sso, String ssoId, Session session) {
        SingleSignOnSessionKey key = new SingleSignOnSessionKey(session);
        SingleSignOnSessionKey currentKey = sessionKeys.putIfAbsent(key, key);
        if (currentKey == null) {
            // Session not previously added
            session.addSessionListener(sso.getSessionListener(ssoId));
        }
    }

    /**
     * Removes the given <code>Session</code> from the list of those associated with this SSO.
     *
     * @param session the <code>Session</code> to remove.
     */
    public void removeSession(Session session) {
        SingleSignOnSessionKey key = new SingleSignOnSessionKey(session);
        sessionKeys.remove(key);
    }

    /**
     * Returns the HTTP Session identifiers associated with this SSO.
     *
     * @return the identifiers for the HTTP sessions that are currently associated with this SSO entry
     */
    public Set<SingleSignOnSessionKey> findSessions() {
        return sessionKeys.keySet();
    }

    /**
     * Gets the name of the authentication type originally used to authenticate the user associated with the SSO.
     *
     * @return "BASIC", "CLIENT_CERT", "DIGEST", "FORM" or "NONE"
     */
    public String getAuthType() {
        return this.authType;
    }

    /**
     * Gets whether the authentication type associated with the original authentication supports reauthentication.
     *
     * @return <code>true</code> if <code>getAuthType</code> returns "BASIC" or "FORM", <code>false</code> otherwise.
     */
    public boolean getCanReauthenticate() {
        return this.canReauthenticate;
    }

    /**
     * Gets the password credential (if any) associated with the SSO.
     *
     * @return the password credential associated with the SSO, or <code>null</code> if the original authentication type
     *             does not involve a password.
     */
    public String getPassword() {
        return this.password;
    }

    /**
     * Gets the <code>Principal</code> that has been authenticated by the SSO.
     *
     * @return The Principal that was created by the authentication that triggered the creation of the SSO entry
     */
    public Principal getPrincipal() {
        return this.principal;
    }

    /**
     * Gets the username provided by the user as part of the authentication process.
     *
     * @return The username that was authenticated as part of the authentication that triggered the creation of the SSO
     *             entry
     */
    public String getUsername() {
        return this.username;
    }


    /**
     * Updates the SingleSignOnEntry to reflect the latest security information associated with the caller.
     *
     * @param principal the <code>Principal</code> returned by the latest call to <code>Realm.authenticate</code>.
     * @param authType  the type of authenticator used (BASIC, CLIENT_CERT, DIGEST or FORM)
     * @param username  the username (if any) used for the authentication
     * @param password  the password (if any) used for the authentication
     */
    public synchronized void updateCredentials(Principal principal, String authType, String username, String password) {
        this.principal = principal;
        this.authType = authType;
        this.username = username;
        this.password = password;
        this.canReauthenticate =
                (HttpServletRequest.BASIC_AUTH.equals(authType) || HttpServletRequest.FORM_AUTH.equals(authType));
    }


    @Serial
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        if (principal instanceof Serializable) {
            out.writeBoolean(true);
            out.writeObject(principal);
        } else {
            out.writeBoolean(false);
        }
    }

    @Serial
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        boolean hasPrincipal = in.readBoolean();
        if (hasPrincipal) {
            principal = (Principal) in.readObject();
        }
    }
}
