/*
 * 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.nifi.security.krb;

import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.ProcessContext;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;

import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.login.LoginException;
import java.io.File;
import java.nio.file.Path;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class KerberosUserIT {
    private static KDCServer kdc;

    private static KerberosPrincipal principal1;
    private static File principal1KeytabFile;

    private static KerberosPrincipal principal2;
    private static File principal2KeytabFile;

    private static KerberosPrincipal principal3;
    private static final String principal3Password = "changeme";

    @BeforeAll
    public static void setupClass(@TempDir Path tmpDir) throws Exception {
        File kdcFolder = tmpDir.resolve("mini-kdc_").toFile();
        kdcFolder.mkdirs();

        kdc = new KDCServer(kdcFolder);
        kdc.setMaxTicketLifetime("15"); // set ticket lifetime to 15 seconds so we can test relogin
        kdc.start();

        principal1 = new KerberosPrincipal("user1@" + kdc.getRealm());
        principal1KeytabFile = tmpDir.resolve("user1.keytab").toFile();
        kdc.createKeytabPrincipal(principal1KeytabFile, "user1");

        principal2 = new KerberosPrincipal("user2@" + kdc.getRealm());
        principal2KeytabFile = tmpDir.resolve("user2.keytab").toFile();
        kdc.createKeytabPrincipal(principal2KeytabFile, "user2");

        principal3 = new KerberosPrincipal("user3@" + kdc.getRealm());
        kdc.createPasswordPrincipal("user3", principal3Password);
    }

    @Test
    public void testKeytabUserSuccessfulLoginAndLogout() throws LoginException {
        // perform login for user1
        final KerberosUser user1 = new KerberosKeytabUser(principal1.getName(), principal1KeytabFile.getAbsolutePath());
        user1.login();

        // perform login for user2
        final KerberosUser user2 = new KerberosKeytabUser(principal2.getName(), principal2KeytabFile.getAbsolutePath());
        user2.login();

        // verify user1 Subject only has user1 principal
        final Subject user1Subject = ((KerberosKeytabUser) user1).getSubject();
        final Set<Principal> user1SubjectPrincipals = user1Subject.getPrincipals();
        assertEquals(1, user1SubjectPrincipals.size());
        assertEquals(principal1.getName(), user1SubjectPrincipals.iterator().next().getName());

        // verify user2 Subject only has user2 principal
        final Subject user2Subject = ((KerberosKeytabUser) user2).getSubject();
        final Set<Principal> user2SubjectPrincipals = user2Subject.getPrincipals();
        assertEquals(1, user2SubjectPrincipals.size());
        assertEquals(principal2.getName(), user2SubjectPrincipals.iterator().next().getName());

        // call check/relogin and verify neither user performed a relogin
        assertFalse(user1.checkTGTAndRelogin());
        assertFalse(user2.checkTGTAndRelogin());

        // perform logout for both users
        user1.logout();
        user2.logout();

        // verify subjects have no more principals
        assertEquals(0, user1Subject.getPrincipals().size());
        assertEquals(0, user2Subject.getPrincipals().size());
    }

    @Test
    public void testKeytabLoginWithUnknownPrincipal() {
        final String unknownPrincipal = "doesnotexist@" + kdc.getRealm();
        final KerberosUser user1 = new KerberosKeytabUser(unknownPrincipal, principal1KeytabFile.getAbsolutePath());
        assertThrows(Exception.class, () -> user1.login());
    }

    @Test
    public void testPasswordUserSuccessfulLoginAndLogout() throws LoginException {
        // perform login for user
        final KerberosUser user = new KerberosPasswordUser(principal3.getName(), principal3Password);
        user.login();

        // verify user Subject only has user principal
        final Subject userSubject = ((KerberosPasswordUser) user).getSubject();
        final Set<Principal> userSubjectPrincipals = userSubject.getPrincipals();
        assertEquals(1, userSubjectPrincipals.size());
        assertEquals(principal3.getName(), userSubjectPrincipals.iterator().next().getName());

        // call check/relogin and verify neither user performed a relogin
        assertFalse(user.checkTGTAndRelogin());

        // perform logout for both users
        user.logout();

        // verify subjects have no more principals
        assertEquals(0, userSubject.getPrincipals().size());
    }

    @Test
    public void testPasswordUserLoginWithInvalidPassword() {
        // perform login for user
        final KerberosUser user = new KerberosPasswordUser("user3", "NOT THE PASSWORD");
        assertThrows(LoginException.class, () -> user.login());
    }

    @Test
    public void testCheckTGTAndRelogin() throws LoginException, InterruptedException {
        final KerberosUser user1 = new KerberosKeytabUser(principal1.getName(), principal1KeytabFile.getAbsolutePath());
        user1.login();

        // Since we set the lifetime to 15 seconds we should hit a relogin before 15 attempts

        boolean performedRelogin = false;
        for (int i=0; i < 30; i++) {
            Thread.sleep(1000);
            System.out.println("checkTGTAndRelogin #" + i);
            performedRelogin = user1.checkTGTAndRelogin();

            if (performedRelogin) {
                System.out.println("Performed relogin!");
                break;
            }
        }
        assertEquals(true, performedRelogin);

        Subject subject = user1.doAs((PrivilegedAction<Subject>) () -> {
            AccessControlContext context = AccessController.getContext();
            return Subject.getSubject(context);
        });

        // verify only a single KerberosTicket exists in the Subject after relogin
        Set<KerberosTicket> kerberosTickets = subject.getPrivateCredentials(KerberosTicket.class);
        assertEquals(1, kerberosTickets.size());

        // verify the new ticket lifetime is valid for the current time
        KerberosTicket kerberosTicket = kerberosTickets.iterator().next();
        long currentTimeMillis = System.currentTimeMillis();
        long startMilli = kerberosTicket.getStartTime().toInstant().toEpochMilli();
        long endMilli = kerberosTicket.getEndTime().toInstant().toEpochMilli();
        System.out.println("New ticket is valid for " + TimeUnit.MILLISECONDS.toSeconds(endMilli - startMilli) + " seconds");
        assertTrue(startMilli < currentTimeMillis);
        assertTrue(endMilli > currentTimeMillis);
    }

    @Test
    public void testKeytabAction() {
        final KerberosUser user1 = new KerberosKeytabUser(principal1.getName(), principal1KeytabFile.getAbsolutePath());

        final AtomicReference<String> resultHolder = new AtomicReference<>(null);
        final PrivilegedExceptionAction<Void> privilegedAction = () -> {
            resultHolder.set("SUCCESS");
            return null;
        };

        final ProcessContext context = Mockito.mock(ProcessContext.class);
        final ComponentLog logger = Mockito.mock(ComponentLog.class);

        // create the action to test and execute it
        final KerberosAction kerberosAction = new KerberosAction<>(user1, privilegedAction, logger);
        kerberosAction.execute();

        // if the result holder has the string success then we know the action executed
        assertEquals("SUCCESS", resultHolder.get());
    }

}
