//
//  ========================================================================
//  Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.jaas.spi;

import java.io.File;
import java.util.Collections;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;

import org.eclipse.jetty.jaas.JAASLoginService;
import org.eclipse.jetty.jaas.PropertyUserStoreManager;
import org.eclipse.jetty.security.DefaultIdentityService;
import org.eclipse.jetty.security.PropertyUserStore;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

public class PropertyFileLoginModuleTest
{
    @Test
    public void testPropertyFileLoginModule() throws Exception
    {
        //configure for PropertyFileLoginModule
        File loginProperties = MavenTestingUtils.getTestResourceFile("login.properties");

        Configuration testConfig = new Configuration()
        {
            @Override
            public AppConfigurationEntry[] getAppConfigurationEntry(String name)
            { 
                return new AppConfigurationEntry[]{new AppConfigurationEntry(PropertyFileLoginModule.class.getName(), 
                                                                             LoginModuleControlFlag.REQUIRED,
                                                                             Collections.singletonMap("file", loginProperties.getAbsolutePath()))};
            }
        };

        JAASLoginService ls = new JAASLoginService("foo");
        ls.setCallbackHandlerClass("org.eclipse.jetty.jaas.callback.DefaultCallbackHandler");
        ls.setIdentityService(new DefaultIdentityService());
        ls.setConfiguration(testConfig);
        ls.start();

        //test that the manager is created when the JAASLoginService starts
        PropertyUserStoreManager mgr = ls.getBean(PropertyUserStoreManager.class);
        assertThat(mgr, notNullValue());

        //test the PropertyFileLoginModule authentication and authorization
        Request request = new Request(null, null);
        UserIdentity uid = ls.login("fred", "pwd", request);
        assertThat(uid.isUserInRole("role1", null), is(true));
        assertThat(uid.isUserInRole("role2", null), is(true));
        assertThat(uid.isUserInRole("role3", null), is(true));
        assertThat(uid.isUserInRole("role4", null), is(false));

        //Test that the PropertyUserStore is created by the PropertyFileLoginModule
        PropertyUserStore store = mgr.getPropertyUserStore(loginProperties.getAbsolutePath());
        assertThat(store, is(notNullValue()));
        assertThat(store.isRunning(), is(true));
        assertThat(store.isHotReload(), is(false));

        //test that the PropertyUserStoreManager is stopped and all PropertyUserStores stopped
        ls.stop();
        assertThat(mgr.isStopped(), is(true));
        assertThat(mgr.getPropertyUserStore(loginProperties.getAbsolutePath()), is(nullValue()));
        assertThat(store.isStopped(), is(true));
    }
}
