/*
 * 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.jackrabbit.oak.security.authentication.token;

import java.io.IOException;
import java.security.Principal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.jcr.Credentials;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;

import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
import org.apache.jackrabbit.oak.api.AuthInfo;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.AbstractLoginModule;
import org.apache.jackrabbit.oak.spi.security.authentication.AuthInfoImpl;
import org.apache.jackrabbit.oak.spi.security.authentication.callback.TokenProviderCallback;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * {@code LoginModule} implementation that is able to handle login request
 * based on {@link TokenCredentials}. In combination with another login module
 * that handles other {@code Credentials} implementation this module will also
 * take care of creating new login tokens and the corresponding credentials
 * upon {@link #commit()}that it will be able to deal with in subsequent
 * login calls.
 *
 * <h2>Login and Commit</h2>
 * <h3>Login</h3>
 * This {@code LoginModule} implementation performs the following tasks upon
 * {@link #login()}.
 *
 * <ol>
 *     <li>Try to retrieve {@link TokenCredentials} credentials (see also
 *     {@link AbstractLoginModule#getCredentials()})</li>
 *     <li>Validates the credentials based on the functionality provided by
 *     {@link TokenAuthentication#authenticate(javax.jcr.Credentials)}</li>
 *     <li>Upon success it retrieves {@code userId} from the {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenInfo}
 *     and calculates the principals associated with that user,</li>
 *     <li>and finally puts the credentials on the shared state.</li>
 * </ol>
 *
 * If no {@code TokenProvider} has been configured {@link #login()} or if
 * no {@code TokenCredentials} can be obtained this module will return {@code false}.
 *
 * <h3>Commit</h3>
 * If login was successfully handled by this module the {@link #commit()} will
 * just populate the subject.<p>
 *
 * If the login was successfully handled by another module in the chain, the
 * {@code TokenLoginModule} will test if the login was associated with a
 * request for login token generation. This mandates that there are credentials
 * present on the shared state that fulfill the requirements defined by
 * {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider#doCreateToken(javax.jcr.Credentials)}.
 *
 * <h3>Example Configurations</h3>
 * The authentication configuration using this {@code LoginModule} could for
 * example look as follows:
 *
 * <h4>TokenLoginModule in combination with another LoginModule</h4>
 * <pre>
 *    jackrabbit.oak {
 *            org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule sufficient;
 *            org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl required;
 *    };
 * </pre>
 * In this case the TokenLoginModule would handle any login issued with
 * {@link TokenCredentials} while the second module would take care any other
 * credentials implementations as long they are supported by the module. In
 * addition the {@link TokenLoginModule} will issue a new token if the login
 * succeeded and the credentials provided by the shared state can be used
 * to issue a new login token (see {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider#doCreateToken(javax.jcr.Credentials)}.
 *
 * <h4>TokenLoginModule as single way to login</h4>
 * <pre>
 *    jackrabbit.oak {
 *            org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule required;
 *    };
 * </pre>
 * If the {@code TokenLoginModule} as single entry in the login configuration
 * the login token must be generated by the application by calling
 * {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider#createToken(Credentials)} or
 * {@link org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider#createToken(String, java.util.Map)}.
 */
public final class TokenLoginModule extends AbstractLoginModule {

    /**
     * logger instance
     */
    private static final Logger log = LoggerFactory.getLogger(TokenLoginModule.class);

    private TokenProvider tokenProvider;

    private TokenCredentials tokenCredentials;
    private TokenInfo tokenInfo;
    private String userId;
    private Principal principal;

    //--------------------------------------------------------< LoginModule >---
    @Override
    public boolean login() throws LoginException {
        tokenProvider = getTokenProvider();
        if (tokenProvider == null) {
            return false;
        }

        Credentials credentials = getCredentials();
        if (credentials instanceof TokenCredentials) {
            TokenCredentials tc = (TokenCredentials) credentials;
            TokenAuthentication authentication = new TokenAuthentication(tokenProvider);
            if (authentication.authenticate(tc)) {
                tokenCredentials = tc;
                tokenInfo = authentication.getTokenInfo();
                userId = authentication.getUserId();
                principal = authentication.getUserPrincipal();

                log.debug("Login: adding login name to shared state.");
                sharedState.put(SHARED_KEY_LOGIN_NAME, userId);
                return true;
            }
        }

        return false;
    }

    @Override
    public boolean commit() throws LoginException {
        if (tokenCredentials != null && userId != null) {
            Set<? extends Principal> principals = (principal != null) ? getPrincipals(principal) : getPrincipals(userId);
            updateSubject(tokenCredentials, getAuthInfo(tokenInfo, principals), principals);
            return true;
        }
        try{
            if (tokenProvider != null && sharedState.containsKey(SHARED_KEY_CREDENTIALS)) {
                Credentials shared = getSharedCredentials();
                if (shared != null && tokenProvider.doCreateToken(shared)) {
                    Root r = getRoot();
                    if (r != null) {
                        r.refresh(); // refresh root, in case the external login module created users
                    }
                    TokenInfo ti = tokenProvider.createToken(shared);
                    if (ti != null) {
                        TokenCredentials tc = new TokenCredentials(ti.getToken());
                        Map<String, String> attributes = ti.getPrivateAttributes();
                        for (String name : attributes.keySet()) {
                            tc.setAttribute(name, attributes.get(name));
                        }
                        attributes = ti.getPublicAttributes();
                        for (String name : attributes.keySet()) {
                            tc.setAttribute(name, attributes.get(name));
                        }
                        sharedState.put(SHARED_KEY_ATTRIBUTES, attributes);
                        updateSubject(tc, null, null);
                    } else {
                        // failed to create token -> fail commit()
                        Object logId = (userId != null) ? userId : sharedState.get(SHARED_KEY_LOGIN_NAME);
                        log.debug("TokenProvider failed to create a login token for user " + logId);
                        throw new LoginException("Failed to create login token for user " + logId);
                    }
                }
            }
        } finally {
            // the login attempt on this module did not succeed: clear state
            clearState();
        }

        return false;
    }

    //------------------------------------------------< AbstractLoginModule >---
    @NotNull
    @Override
    protected Set<Class> getSupportedCredentials() {
        return Collections.<Class>singleton(TokenCredentials.class);
    }

    @Override
    protected void clearState() {
        super.clearState();

        tokenCredentials = null;
        tokenInfo = null;
        userId = null;
    }

    //------------------------------------------------------------< private >---

    /**
     * Retrieve the token provider
     * @return the token provider or {@code null}.
     */
    @Nullable
    private TokenProvider getTokenProvider() {
        TokenProvider provider = null;
        SecurityProvider securityProvider = getSecurityProvider();
        Root root = getRoot();
        if (root != null && securityProvider != null) {
            TokenConfiguration tokenConfig = securityProvider.getConfiguration(TokenConfiguration.class);
            provider = tokenConfig.getTokenProvider(root);
        }
        if (provider == null && callbackHandler != null) {
            try {
                TokenProviderCallback tcCallback = new TokenProviderCallback();
                callbackHandler.handle(new Callback[] {tcCallback});
                provider = tcCallback.getTokenProvider();
            } catch (IOException e) {
                log.warn(e.getMessage());
            } catch (UnsupportedCallbackException e) {
                log.warn(e.getMessage());
            }
        }
        return provider;
    }

    /**
     * Create the {@code AuthInfo} for the specified {@code tokenInfo} as well as
     * userId and principals, that have been set upon {@link #login}.
     *
     * @param tokenInfo The tokenInfo to retrieve attributes from.
     * @return The {@code AuthInfo} resulting from the successful login.
     */
    @Nullable
    private AuthInfo getAuthInfo(@Nullable TokenInfo tokenInfo, @NotNull Set<? extends Principal> principals) {
        if (tokenInfo != null) {
            Map<String, Object> attributes = new HashMap<String, Object>();
            Map<String, String> publicAttributes = tokenInfo.getPublicAttributes();
            for (String attrName : publicAttributes.keySet()) {
                attributes.put(attrName, publicAttributes.get(attrName));
            }
            return new AuthInfoImpl(tokenInfo.getUserId(), attributes, principals);
        } else {
            return null;
        }
    }

    private void updateSubject(@NotNull TokenCredentials tc, @Nullable AuthInfo authInfo,
                               @Nullable Set<? extends Principal> principals) {
        if (!subject.isReadOnly()) {
            subject.getPublicCredentials().add(tc);

            if (principals != null) {
                subject.getPrincipals().addAll(principals);
            }

            if (authInfo != null) {
                setAuthInfo(authInfo, subject);
            }
        }
    }
}
