package com.atlassian.bitbucket.auth;

import com.atlassian.bitbucket.scm.BaseWeightedModuleDescriptor;
import com.atlassian.bitbucket.user.ApplicationUser;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;


/**
 * Implementations may also implement {@link HttpLogoutHandler}, in which case they'll get a callback when the user
 * logs out.
 * <p>
 * Implementations should be stateless and thread-safe, as a single instance will be used to service all authentication
 * requests.
 */
public interface HttpAuthenticationHandler {


    /**
     * Invoked by the system on requests that have an authenticated user. Implementations that need to check whether an
     * external (SSO) session is still valid should implement that logic here.
     * <p>
     * This method is called for every incoming request after the user initially authenticated. Implementors should make
     * the implementation of this method as lightweight as possible.
     * <p>
     * @throws AuthenticationException if the current authentication is no longer valid and the
     *         user must re-authenticate.
     *
     * @param authenticationContext the authentication context that provides the authenticated user, request details, etc.
     */
    void validateAuthentication(@Nonnull HttpAuthenticationContext authenticationContext);

    /**
     * Invoked by the system when authentication is attempted over HTTP. Implementations must
     * <ul>
     *     <li>
     *         return the {@link ApplicationUser} instance of the authenticated user if the user is authenticated
     *         successfully
     *     </li>
     *     <li>
     *         return {@code null} if the handler does not know how to authenticate the user from the request (for
     *         instance when an expected SSO cookie is not present). By returning {@code null}, other
     *         {@link HttpAuthenticationHandler handlers} will be attempted.
     *     </li>
     *     <li>
     *         throw an {@link AuthenticationException} if the provided authentication
     *         details are invalid (e.g. invalid username / password, cookie, etc.). In this case, no other
     *         {@link HttpAuthenticationHandler handlers} will be attempted.
     *     </li>
     * </ul>
     * All registered {@link HttpAuthenticationHandler handlers} will be invoked in
     * {@link BaseWeightedModuleDescriptor weight order} until a handler successfully
     * authenticates the {@link ApplicationUser user}, or throws an {@link AuthenticationException}.
     *
     * @param authenticationContext the authentication context that provides username, password, request details, etc.
     * @return the authenticated user on success, {@code null} when the handler opts out of authentication.
     * @throws AuthenticationException when authentication fails.
     */
    @Nullable
    ApplicationUser authenticate(@Nonnull HttpAuthenticationContext authenticationContext);
}
