/*
 * 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.qpid.server.security.auth.sasl.crammd5;

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.xml.bind.DatatypeConverter;

import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.database.HashedUser;
import org.apache.qpid.server.security.auth.sasl.PasswordSource;
import org.apache.qpid.server.security.auth.sasl.SaslUtil;
import org.apache.qpid.test.utils.QpidTestCase;

public class CramMd5NegotiatorTest extends QpidTestCase
{
    private static final String TEST_FQDN = "example.com";
    private static final String VALID_USERNAME = "testUser";
    private static final char[] VALID_USERPASSWORD = "testPassword".toCharArray();
    private static final String INVALID_USERPASSWORD = "invalidPassword";
    private static final String INVALID_USERNAME = "invalidUser" ;

    private AbstractCramMd5Negotiator _negotiator;
    private PasswordSource _passwordSource;
    private PasswordCredentialManagingAuthenticationProvider<?> _authenticationProvider;

    @Override
    public void setUp() throws Exception
    {
        super.setUp();
        _passwordSource = mock(PasswordSource.class);
        when(_passwordSource.getPassword(eq(VALID_USERNAME))).thenReturn(VALID_USERPASSWORD);
        _authenticationProvider = mock(PasswordCredentialManagingAuthenticationProvider.class);
    }

    @Override
    public void tearDown() throws Exception
    {
        super.tearDown();
        if (_negotiator != null)
        {
            _negotiator.dispose();
        }
    }

    public void testHandleResponseCramMD5ValidCredentials() throws Exception
    {
        _negotiator = new CramMd5Negotiator(_authenticationProvider, TEST_FQDN, _passwordSource);
        doHandleResponseWithValidCredentials(CramMd5Negotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5InvalidPassword() throws Exception
    {
        _negotiator = new CramMd5Negotiator(_authenticationProvider, TEST_FQDN, _passwordSource);
        doHandleResponseWithInvalidPassword(CramMd5Negotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5InvalidUsername() throws Exception
    {
        _negotiator = new CramMd5Negotiator(_authenticationProvider, TEST_FQDN, _passwordSource);
        doHandleResponseWithInvalidUsername(CramMd5Negotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HashedValidCredentials() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithValidCredentials(CramMd5HashedNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HashedInvalidPassword() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidPassword(CramMd5HashedNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HashedInvalidUsername() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidUsername(CramMd5HashedNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HexValidCredentials() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithValidCredentials(CramMd5HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HexInvalidPassword() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidPassword(CramMd5HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5HexInvalidUsername() throws Exception
    {
        hashPassword();

        _negotiator = new CramMd5HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidUsername(CramMd5HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HexValidCredentials() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithValidCredentials(CramMd5Base64HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HexInvalidPassword() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidPassword(CramMd5Base64HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HexInvalidUsername() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HexNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidUsername(CramMd5Base64HexNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HashedValidCredentials() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithValidCredentials(CramMd5Base64HashedNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HashedInvalidPassword() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidPassword(CramMd5Base64HashedNegotiator.MECHANISM);
    }

    public void testHandleResponseCramMD5Base64HashedInvalidUsername() throws Exception
    {
        base64Password();

        _negotiator = new CramMd5Base64HashedNegotiator(_authenticationProvider, TEST_FQDN, _passwordSource);

        doHandleResponseWithInvalidUsername(CramMd5Base64HashedNegotiator.MECHANISM);
    }

    private void doHandleResponseWithValidCredentials(final String mechanism) throws Exception
    {
        AuthenticationResult firstResult = _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected first result status", AuthenticationResult.AuthenticationStatus.CONTINUE, firstResult.getStatus());
        assertNotNull("Unexpected first result challenge", firstResult.getChallenge());

        byte[] responseBytes = SaslUtil.generateCramMD5ClientResponse(mechanism, VALID_USERNAME, new String(VALID_USERPASSWORD), firstResult.getChallenge());

        AuthenticationResult secondResult = _negotiator.handleResponse(responseBytes);

        assertEquals("Unexpected second result status", AuthenticationResult.AuthenticationStatus.SUCCESS, secondResult.getStatus());
        assertNull("Unexpected second result challenge", secondResult.getChallenge());
        assertEquals("Unexpected second result main principal", VALID_USERNAME, secondResult.getMainPrincipal().getName());

        verify(_passwordSource).getPassword(eq(VALID_USERNAME));

        AuthenticationResult thirdResult =  _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected third result status", AuthenticationResult.AuthenticationStatus.ERROR, thirdResult.getStatus());
    }

    private void doHandleResponseWithInvalidPassword(final String mechanism) throws Exception
    {
        AuthenticationResult firstResult = _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected first result status", AuthenticationResult.AuthenticationStatus.CONTINUE, firstResult.getStatus());
        assertNotNull("Unexpected first result challenge", firstResult.getChallenge());

        byte[] responseBytes = SaslUtil.generateCramMD5ClientResponse(mechanism, VALID_USERNAME, INVALID_USERPASSWORD, firstResult.getChallenge());

        AuthenticationResult secondResult = _negotiator.handleResponse(responseBytes);

        assertEquals("Unexpected second result status", AuthenticationResult.AuthenticationStatus.ERROR, secondResult.getStatus());
        assertNull("Unexpected second result challenge", secondResult.getChallenge());
        assertNull("Unexpected second result main principal",  secondResult.getMainPrincipal());

        verify(_passwordSource).getPassword(eq(VALID_USERNAME));

        AuthenticationResult thirdResult =  _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected third result status", AuthenticationResult.AuthenticationStatus.ERROR, thirdResult.getStatus());
    }

    private void doHandleResponseWithInvalidUsername(final String mechanism) throws Exception
    {
        AuthenticationResult firstResult = _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected first result status", AuthenticationResult.AuthenticationStatus.CONTINUE, firstResult.getStatus());
        assertNotNull("Unexpected first result challenge", firstResult.getChallenge());

        byte[] responseBytes = SaslUtil.generateCramMD5ClientResponse(mechanism, INVALID_USERNAME, new String(VALID_USERPASSWORD), firstResult.getChallenge());

        AuthenticationResult secondResult = _negotiator.handleResponse(responseBytes);

        assertEquals("Unexpected second result status", AuthenticationResult.AuthenticationStatus.ERROR, secondResult.getStatus());
        assertNull("Unexpected second result challenge", secondResult.getChallenge());
        assertNull("Unexpected second result main principal",  secondResult.getMainPrincipal());

        verify(_passwordSource).getPassword(eq(INVALID_USERNAME));

        AuthenticationResult thirdResult =  _negotiator.handleResponse(new byte[0]);
        assertEquals("Unexpected third result status", AuthenticationResult.AuthenticationStatus.ERROR, thirdResult.getStatus());
    }

    private void hashPassword()
    {
        HashedUser hashedUser = new HashedUser(VALID_USERNAME, VALID_USERPASSWORD, _authenticationProvider);
        char[] password = hashedUser.getPassword();
        when(_passwordSource.getPassword(eq(VALID_USERNAME))).thenReturn(password);
    }

    private void base64Password() throws NoSuchAlgorithmException
    {
        byte[] data = new String(VALID_USERPASSWORD).getBytes(StandardCharsets.UTF_8);
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(data);
        char[] password = DatatypeConverter.printBase64Binary(md.digest()).toCharArray();
        when(_passwordSource.getPassword(eq(VALID_USERNAME))).thenReturn(password);
    }

}