package org.apache.archiva.web.security;
/*
 * 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.
 */

import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
import org.apache.archiva.redback.authentication.AbstractAuthenticator;
import org.apache.archiva.redback.authentication.AuthenticationConstants;
import org.apache.archiva.redback.authentication.AuthenticationDataSource;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationFailureCause;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.Authenticator;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.policy.PasswordEncoder;
import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Olivier Lamy
 * @since 1.4-M4
 */
@Service("authenticator#archiva")
public class ArchivaUserManagerAuthenticator
    extends AbstractAuthenticator
    implements Authenticator
{
    private Logger log = LoggerFactory.getLogger( getClass() );

    @Inject
    private UserSecurityPolicy securityPolicy;

    @Inject
    private ApplicationContext applicationContext;

    @Inject
    private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;

    private List<UserManager> userManagers;

    private boolean valid = false;

    @PostConstruct
    @Override
    public void initialize()
        throws AuthenticationException
    {
        try
        {
            List<String> userManagerImpls =
                redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls();

            userManagers = new ArrayList<>( userManagerImpls.size() );

            for ( String beanId : userManagerImpls )
            {
                userManagers.add( applicationContext.getBean( "userManager#" + beanId, UserManager.class ) );
            }
            valid=true;
        }
        catch ( RepositoryAdminException e )
        {
            log.error("Error during repository initialization "+e.getMessage(),e);
            // throw new AuthenticationException( e.getMessage(), e );
        }
    }


    @Override
    public AuthenticationResult authenticate( AuthenticationDataSource ds )
        throws AuthenticationException, AccountLockedException, MustChangePasswordException
    {
        boolean authenticationSuccess = false;
        String username = null;
        Exception resultException = null;
        PasswordBasedAuthenticationDataSource source = (PasswordBasedAuthenticationDataSource) ds;
        List<AuthenticationFailureCause> authnResultErrors = new ArrayList<>();

        for ( UserManager userManager : userManagers )
        {
            try
            {
                log.debug( "Authenticate: {} with userManager: {}", source, userManager.getId() );
                User user = userManager.findUser( source.getUsername() );
                username = user.getUsername();

                if ( user.isLocked() )
                {
                    //throw new AccountLockedException( "Account " + source.getUsername() + " is locked.", user );
                    AccountLockedException e =
                        new AccountLockedException( "Account " + source.getUsername() + " is locked.", user );
                    log.warn( "{}", e.getMessage() );
                    resultException = e;
                    authnResultErrors.add(
                        new AuthenticationFailureCause( AuthenticationConstants.AUTHN_LOCKED_USER_EXCEPTION,
                                                        e.getMessage() ) );
                }

                if ( user.isPasswordChangeRequired() && source.isEnforcePasswordChange() )
                {
                    //throw new MustChangePasswordException( "Password expired.", user );
                    MustChangePasswordException e = new MustChangePasswordException( "Password expired.", user );
                    log.warn( "{}", e.getMessage() );
                    resultException = e;
                    authnResultErrors.add(
                        new AuthenticationFailureCause( AuthenticationConstants.AUTHN_MUST_CHANGE_PASSWORD_EXCEPTION,
                                                        e.getMessage() ) );
                }

                PasswordEncoder encoder = securityPolicy.getPasswordEncoder();
                log.debug( "PasswordEncoder: {}", encoder.getClass().getName() );

                boolean isPasswordValid = encoder.isPasswordValid( user.getEncodedPassword(), source.getPassword() );
                if ( isPasswordValid )
                {
                    log.debug( "User {} provided a valid password", source.getUsername() );

                    try
                    {
                        securityPolicy.extensionPasswordExpiration( user );

                        authenticationSuccess = true;

                        //REDBACK-151 do not make unnessesary updates to the user object
                        if ( user.getCountFailedLoginAttempts() > 0 )
                        {
                            user.setCountFailedLoginAttempts( 0 );
                            if ( !userManager.isReadOnly() )
                            {
                                userManager.updateUser( user );
                            }
                        }

                        return new AuthenticationResult( true, source.getUsername(), null );
                    }
                    catch ( MustChangePasswordException e )
                    {
                        user.setPasswordChangeRequired( true );
                        //throw e;
                        resultException = e;
                        authnResultErrors.add( new AuthenticationFailureCause(
                            AuthenticationConstants.AUTHN_MUST_CHANGE_PASSWORD_EXCEPTION, e.getMessage() ).user( user ) );
                    }
                }
                else
                {
                    log.warn( "Password is Invalid for user {} and userManager '{}'.", source.getUsername(),
                              userManager.getId() );
                    authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER,
                                                                           "Password is Invalid for user "
                                                                               + source.getUsername() + "." ).user( user ) );

                    try
                    {

                        securityPolicy.extensionExcessiveLoginAttempts( user );

                    }
                    finally
                    {
                        if ( !userManager.isReadOnly() )
                        {
                            userManager.updateUser( user );
                        }
                    }

                    //return new AuthenticationResult( false, source.getUsername(), null, authnResultExceptionsMap );
                }
            }
            catch ( UserNotFoundException e )
            {
                log.warn( "Login for user {} and userManager {} failed. user not found.", source.getUsername(),
                          userManager.getId() );
                resultException = e;
                authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER,
                                                                       "Login for user " + source.getUsername()
                                                                           + " failed. user not found." ) );
            }
            catch ( Exception e )
            {
                log.warn( "Login for user {} and userManager {} failed, message: {}", source.getUsername(),
                          userManager.getId(), e.getMessage() );
                resultException = e;
                authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION,
                                                                       "Login for user " + source.getUsername()
                                                                           + " failed, message: " + e.getMessage() ) );
            }
        }
        return new AuthenticationResult( authenticationSuccess, username, resultException, authnResultErrors );
    }

    @Override
    public boolean supportsDataSource( AuthenticationDataSource source )
    {
        return ( source instanceof PasswordBasedAuthenticationDataSource );
    }

    @Override
    public String getId()
    {
        return "ArchivaUserManagerAuthenticator";
    }

    public boolean isValid() {
        return valid;
    }
}
