/*
 * 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.cassandra.auth;


import java.nio.charset.StandardCharsets;

import com.google.common.collect.Iterables;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.datastax.driver.core.Authenticator;
import com.datastax.driver.core.PlainTextAuthProvider;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.AuthenticationException;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.schema.KeyspaceParams;

import static org.apache.cassandra.auth.CassandraRoleManager.*;
import static org.apache.cassandra.auth.PasswordAuthenticator.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mindrot.jbcrypt.BCrypt.hashpw;
import static org.mindrot.jbcrypt.BCrypt.gensalt;

public class PasswordAuthenticatorTest extends CQLTester
{

    private static PasswordAuthenticator authenticator = new PasswordAuthenticator();

    @Test
    public void testCheckpw()
    {
        // Valid and correct
        assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(getGensaltLogRounds()))));
        assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(4))));
        assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(12))));

        // Valid but incorrect hashes
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect0", gensalt(4))));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect1", gensalt(10))));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect2", gensalt(12))));

        // Invalid hash values, the jBCrypt library implementation
        // throws an exception which we catch and treat as a failure
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, ""));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "0"));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD,
                            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"));

        // Format is structurally right, but actually invalid
        // bad salt version
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$5x$10$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        // invalid number of rounds, multiple salt versions but it's the rounds that are incorrect
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2$02$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2a$02$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2$99$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2a$99$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        // unpadded rounds
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2$6$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
        assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2a$6$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234"));
    }

    @Test(expected = ConfigurationException.class)
    public void testInvalidUpperBoundHashingRoundsValue()
    {
        executeSaltRoundsPropertyTest(31);
    }

    @Test(expected = ConfigurationException.class)
    public void testInvalidLowerBoundHashingRoundsValue()
    {
        executeSaltRoundsPropertyTest(3);
    }

    private void executeSaltRoundsPropertyTest(Integer rounds)
    {
        String oldProperty = System.getProperty(GENSALT_LOG2_ROUNDS_PROPERTY);
        try
        {
            System.setProperty(GENSALT_LOG2_ROUNDS_PROPERTY, rounds.toString());
            getGensaltLogRounds();
            Assert.fail("Property " + GENSALT_LOG2_ROUNDS_PROPERTY + " must be in interval [4,30]");
        }
        finally
        {
            if (oldProperty != null)
                System.setProperty(GENSALT_LOG2_ROUNDS_PROPERTY, oldProperty);
            else
                System.clearProperty(GENSALT_LOG2_ROUNDS_PROPERTY);
        }
    }


    @Test(expected = AuthenticationException.class)
    public void testEmptyUsername()
    {
        testDecodeIllegalUserAndPwd("", "pwd");
    }

    @Test(expected = AuthenticationException.class)
    public void testEmptyPassword()
    {
        testDecodeIllegalUserAndPwd("user", "");
    }

    @Test(expected = AuthenticationException.class)
    public void testNULUsername0()
    {
        byte[] user = {'u', 's', PasswordAuthenticator.NUL, 'e', 'r'};
        testDecodeIllegalUserAndPwd(new String(user, StandardCharsets.UTF_8), "pwd");
    }

    @Test(expected = AuthenticationException.class)
    public void testNULUsername1()
    {
        testDecodeIllegalUserAndPwd(new String(new byte[4]), "pwd");
    }

    @Test(expected = AuthenticationException.class)
    public void testNULPassword0()
    {
        byte[] pwd = {'p', 'w', PasswordAuthenticator.NUL, 'd'};
        testDecodeIllegalUserAndPwd("user", new String(pwd, StandardCharsets.UTF_8));
    }

    @Test(expected = AuthenticationException.class)
    public void testNULPassword1()
    {
        testDecodeIllegalUserAndPwd("user", new String(new byte[4]));
    }

    private void testDecodeIllegalUserAndPwd(String username, String password)
    {
        SaslNegotiator negotiator = authenticator.newSaslNegotiator(null);
        Authenticator clientAuthenticator = (new PlainTextAuthProvider(username, password))
                                            .newAuthenticator(null, null);

        negotiator.evaluateResponse(clientAuthenticator.initialResponse());
        negotiator.getAuthenticatedUser();
    }

    @BeforeClass
    public static void setUp()
    {
        SchemaLoader.createKeyspace(AuthKeyspace.NAME,
                                    KeyspaceParams.simple(1),
                                    Iterables.toArray(AuthKeyspace.metadata().tables, CFMetaData.class));
        authenticator.setup();
    }

    @AfterClass
    public static void tearDown()
    {
        schemaChange("DROP KEYSPACE " + AuthKeyspace.NAME);
    }
}