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

import java.lang.reflect.Field;
import java.nio.file.Paths;
import java.rmi.server.RMISocketFactory;
import java.util.HashMap;
import java.util.Map;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.*;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import org.apache.cassandra.auth.*;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStoreMBean;
import org.apache.cassandra.utils.JMXServerUtils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class JMXAuthTest extends CQLTester
{
    private static JMXConnectorServer jmxServer;
    private static MBeanServerConnection connection;
    private RoleResource role;
    private String tableName;
    private JMXResource tableMBean;

    @FunctionalInterface
    private interface MBeanAction
    {
        void execute();
    }

    @BeforeClass
    public static void setupClass() throws Exception
    {
        DatabaseDescriptor.daemonInitialization();
        setupAuthorizer();
        setupJMXServer();
    }

    private static void setupAuthorizer()
    {
        try
        {
            IAuthorizer authorizer = new StubAuthorizer();
            Field authorizerField = DatabaseDescriptor.class.getDeclaredField("authorizer");
            authorizerField.setAccessible(true);
            authorizerField.set(null, authorizer);
            DatabaseDescriptor.setPermissionsValidity(0);
        }
        catch (IllegalAccessException | NoSuchFieldException e)
        {
            throw new RuntimeException(e);
        }
    }

    private static void setupJMXServer() throws Exception
    {
        String config = Paths.get(ClassLoader.getSystemResource("auth/cassandra-test-jaas.conf").toURI()).toString();
        System.setProperty("com.sun.management.jmxremote.authenticate", "true");
        System.setProperty("java.security.auth.login.config", config);
        System.setProperty("cassandra.jmx.remote.login.config", "TestLogin");
        System.setProperty("cassandra.jmx.authorizer", NoSuperUserAuthorizationProxy.class.getName());
        jmxServer = JMXServerUtils.createJMXServer(9999, true);
        jmxServer.start();

        JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
        Map<String, Object> env = new HashMap<>();
        env.put("com.sun.jndi.rmi.factory.socket", RMISocketFactory.getDefaultSocketFactory());
        JMXConnector jmxc = JMXConnectorFactory.connect(jmxUrl, env);
        connection = jmxc.getMBeanServerConnection();
    }

    @Before
    public void setup() throws Throwable
    {
        role = RoleResource.role("test_role");
        clearAllPermissions();
        tableName = createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k))");
        tableMBean = JMXResource.mbean(String.format("org.apache.cassandra.db:type=Tables,keyspace=%s,table=%s",
                                                     KEYSPACE, tableName));
    }

    @Test
    public void readAttribute() throws Throwable
    {
        ColumnFamilyStoreMBean proxy = JMX.newMBeanProxy(connection,
                                                         ObjectName.getInstance(tableMBean.getObjectName()),
                                                         ColumnFamilyStoreMBean.class);

        // grant SELECT on a single specific Table mbean
        assertPermissionOnResource(Permission.SELECT, tableMBean, proxy::getTableName);

        // grant SELECT on all Table mbeans in named keyspace
        clearAllPermissions();
        JMXResource allTablesInKeyspace = JMXResource.mbean(String.format("org.apache.cassandra.db:type=Tables,keyspace=%s,*",
                                                                          KEYSPACE));
        assertPermissionOnResource(Permission.SELECT, allTablesInKeyspace, proxy::getTableName);

        // grant SELECT on all Table mbeans
        clearAllPermissions();
        JMXResource allTables = JMXResource.mbean("org.apache.cassandra.db:type=Tables,*");
        assertPermissionOnResource(Permission.SELECT, allTables, proxy::getTableName);

        // grant SELECT ON ALL MBEANS
        clearAllPermissions();
        assertPermissionOnResource(Permission.SELECT, JMXResource.root(), proxy::getTableName);
    }

    @Test
    public void writeAttribute() throws Throwable
    {
        ColumnFamilyStoreMBean proxy = JMX.newMBeanProxy(connection,
                                                         ObjectName.getInstance(tableMBean.getObjectName()),
                                                         ColumnFamilyStoreMBean.class);
        MBeanAction action = () -> proxy.setMinimumCompactionThreshold(4);

        // grant MODIFY on a single specific Table mbean
        assertPermissionOnResource(Permission.MODIFY, tableMBean, action);

        // grant MODIFY on all Table mbeans in named keyspace
        clearAllPermissions();
        JMXResource allTablesInKeyspace = JMXResource.mbean(String.format("org.apache.cassandra.db:type=Tables,keyspace=%s,*",
                                                                          KEYSPACE));
        assertPermissionOnResource(Permission.MODIFY, allTablesInKeyspace, action);

        // grant MODIFY on all Table mbeans
        clearAllPermissions();
        JMXResource allTables = JMXResource.mbean("org.apache.cassandra.db:type=Tables,*");
        assertPermissionOnResource(Permission.MODIFY, allTables, action);

        // grant MODIFY ON ALL MBEANS
        clearAllPermissions();
        assertPermissionOnResource(Permission.MODIFY, JMXResource.root(), action);
    }

    @Test
    public void executeMethod() throws Throwable
    {
        ColumnFamilyStoreMBean proxy = JMX.newMBeanProxy(connection,
                                                         ObjectName.getInstance(tableMBean.getObjectName()),
                                                         ColumnFamilyStoreMBean.class);

        // grant EXECUTE on a single specific Table mbean
        assertPermissionOnResource(Permission.EXECUTE, tableMBean, proxy::estimateKeys);

        // grant EXECUTE on all Table mbeans in named keyspace
        clearAllPermissions();
        JMXResource allTablesInKeyspace = JMXResource.mbean(String.format("org.apache.cassandra.db:type=Tables,keyspace=%s,*",
                                                                          KEYSPACE));
        assertPermissionOnResource(Permission.EXECUTE, allTablesInKeyspace, proxy::estimateKeys);

        // grant EXECUTE on all Table mbeans
        clearAllPermissions();
        JMXResource allTables = JMXResource.mbean("org.apache.cassandra.db:type=Tables,*");
        assertPermissionOnResource(Permission.EXECUTE, allTables, proxy::estimateKeys);

        // grant EXECUTE ON ALL MBEANS
        clearAllPermissions();
        assertPermissionOnResource(Permission.EXECUTE, JMXResource.root(), proxy::estimateKeys);
    }

    private void assertPermissionOnResource(Permission permission,
                                            JMXResource resource,
                                            MBeanAction action)
    {
        assertUnauthorized(action);
        grantPermission(permission, resource, role);
        assertAuthorized(action);
    }

    private void grantPermission(Permission permission, JMXResource resource, RoleResource role)
    {
        DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER,
                                                 ImmutableSet.of(permission),
                                                 resource,
                                                 role);
    }

    private void assertAuthorized(MBeanAction action)
    {
        action.execute();
    }

    private void assertUnauthorized(MBeanAction action)
    {
        try
        {
            action.execute();
            fail("Expected an UnauthorizedException, but none was thrown");
        }
        catch (SecurityException e)
        {
            assertEquals("Access Denied", e.getLocalizedMessage());
        }
    }

    private void clearAllPermissions()
    {
        ((StubAuthorizer) DatabaseDescriptor.getAuthorizer()).clear();
    }

    public static class StubLoginModule implements LoginModule
    {
        private CassandraPrincipal principal;
        private Subject subject;

        public StubLoginModule(){}

        public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
        {
            this.subject = subject;
            principal = new CassandraPrincipal((String)options.get("role_name"));
        }

        public boolean login() throws LoginException
        {
            return true;
        }

        public boolean commit() throws LoginException
        {
            if (!subject.getPrincipals().contains(principal))
                subject.getPrincipals().add(principal);
            return true;
        }

        public boolean abort() throws LoginException
        {
            return true;
        }

        public boolean logout() throws LoginException
        {
            return true;
        }
    }

    // always answers false to isSuperUser and true to isAuthSetup complete - saves us having to initialize
    // a real IRoleManager and StorageService for the test
    public static class NoSuperUserAuthorizationProxy extends AuthorizationProxy
    {
        public NoSuperUserAuthorizationProxy()
        {
            super();
            this.isSuperuser = (role) -> false;
            this.isAuthSetupComplete = () -> true;
        }
    }
}
