/*
 * 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.cql3.validation.entities;

import java.lang.reflect.Field;
import java.util.*;

import com.google.common.base.Joiner;
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.config.Schema;
import org.apache.cassandra.cql3.Attributes;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.statements.BatchStatement;
import org.apache.cassandra.cql3.statements.ModificationStatement;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.utils.Pair;

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

public class UFAuthTest extends CQLTester
{
    String roleName = "test_role";
    AuthenticatedUser user;
    RoleResource role;
    ClientState clientState;

    @BeforeClass
    public 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);
        }
    }

    @Before
    public void setup() throws Throwable
    {
        ((StubAuthorizer) DatabaseDescriptor.getAuthorizer()).clear();
        setupClientState();
        setupTable("CREATE TABLE %s (k int, v1 int, v2 int, PRIMARY KEY (k, v1))");
    }

    @Test
    public void functionInSelection() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT k, %s FROM %s WHERE k = 1;",
                                   functionCall(functionName),
                                   KEYSPACE + "." + currentTable());
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectPKRestriction() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectClusteringRestriction() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k = 0 AND v1 = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectInRestriction() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k IN (%s, %s)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectMultiColumnInRestriction() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, v1 int, v2 int, v3 int, PRIMARY KEY (k, v1, v2))");
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k=0 AND (v1, v2) IN ((%s, %s))",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectMultiColumnEQRestriction() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, v1 int, v2 int, v3 int, PRIMARY KEY (k, v1, v2))");
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k=0 AND (v1, v2) = (%s, %s)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectMultiColumnSliceRestriction() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, v1 int, v2 int, v3 int, PRIMARY KEY (k, v1, v2))");
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE k=0 AND (v1, v2) < (%s, %s)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectTokenEQRestriction() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE token(k) = token(%s)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInSelectTokenSliceRestriction() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT * FROM %s WHERE token(k) < token(%s)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInPKForInsert() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("INSERT INTO %s (k, v1, v2) VALUES (%s, 0, 0)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInClusteringValuesForInsert() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("INSERT INTO %s (k, v1, v2) VALUES (0, %s, 0)",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInPKForDelete() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("DELETE FROM %s WHERE k = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInClusteringValuesForDelete() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("DELETE FROM %s WHERE k = 0 AND v1 = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void testBatchStatement() throws Throwable
    {
        List<ModificationStatement> statements = new ArrayList<>();
        List<String> functions = new ArrayList<>();
        for (int i = 0; i < 3; i++)
        {
            String functionName = createSimpleFunction();
            ModificationStatement stmt =
            (ModificationStatement) getStatement(String.format("INSERT INTO %s (k, v1, v2) " +
                                                               "VALUES (%s, %s, %s)",
                                                               KEYSPACE + "." + currentTable(),
                                                               i, i, functionCall(functionName)));
            functions.add(functionName);
            statements.add(stmt);
        }
        BatchStatement batch = new BatchStatement(-1, BatchStatement.Type.LOGGED, statements, Attributes.none());
        assertUnauthorized(batch, functions);

        grantExecuteOnFunction(functions.get(0));
        assertUnauthorized(batch, functions.subList(1, functions.size()));

        grantExecuteOnFunction(functions.get(1));
        assertUnauthorized(batch, functions.subList(2, functions.size()));

        grantExecuteOnFunction(functions.get(2));
        batch.checkAccess(clientState);
    }

    @Test
    public void testNestedFunctions() throws Throwable
    {
        String innerFunctionName = createSimpleFunction();
        String outerFunctionName = createFunction("int",
                                                  "CREATE FUNCTION %s(input int) " +
                                                  " CALLED ON NULL INPUT" +
                                                  " RETURNS int" +
                                                  " LANGUAGE java" +
                                                  " AS 'return Integer.valueOf(0);'");
        assertPermissionsOnNestedFunctions(innerFunctionName, outerFunctionName);
    }

    @Test
    public void functionInStaticColumnRestrictionInSelect() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, s int STATIC, v1 int, v2 int, PRIMARY KEY(k, v1))");
        String functionName = createSimpleFunction();
        String cql = String.format("SELECT k FROM %s WHERE k = 0 AND s = %s ALLOW FILTERING",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInRegularCondition() throws Throwable
    {
        String functionName = createSimpleFunction();
        String cql = String.format("UPDATE %s SET v2 = 0 WHERE k = 0 AND v1 = 0 IF v2 = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }
    @Test
    public void functionInStaticColumnCondition() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, s int STATIC, v1 int, v2 int, PRIMARY KEY(k, v1))");
        String functionName = createSimpleFunction();
        String cql = String.format("UPDATE %s SET v2 = 0 WHERE k = 0 AND v1 = 0 IF s = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInCollectionLiteralCondition() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, v1 int, m_val map<int, int>, PRIMARY KEY(k))");
        String functionName = createSimpleFunction();
        String cql = String.format("UPDATE %s SET v1 = 0 WHERE k = 0 IF m_val = {%s : %s}",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void functionInCollectionElementCondition() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, v1 int, m_val map<int, int>, PRIMARY KEY(k))");
        String functionName = createSimpleFunction();
        String cql = String.format("UPDATE %s SET v1 = 0 WHERE k = 0 IF m_val[%s] = %s",
                                   KEYSPACE + "." + currentTable(),
                                   functionCall(functionName),
                                   functionCall(functionName));
        assertPermissionsOnFunction(cql, functionName);
    }

    @Test
    public void systemFunctionsRequireNoExplicitPrivileges() throws Throwable
    {
        // with terminal arguments, so evaluated at prepare time
        String cql = String.format("UPDATE %s SET v2 = 0 WHERE k = blobasint(intasblob(0)) and v1 = 0",
                                   KEYSPACE + "." + currentTable());
        getStatement(cql).checkAccess(clientState);

        // with non-terminal arguments, so evaluated at execution
        String functionName = createSimpleFunction();
        grantExecuteOnFunction(functionName);
        cql = String.format("UPDATE %s SET v2 = 0 WHERE k = blobasint(intasblob(%s)) and v1 = 0",
                            KEYSPACE + "." + currentTable(),
                            functionCall(functionName));
        getStatement(cql).checkAccess(clientState);
    }

    @Test
    public void requireExecutePermissionOnComponentFunctionsWhenDefiningAggregate() throws Throwable
    {
        String sFunc = createSimpleStateFunction();
        String fFunc = createSimpleFinalFunction();
        // aside from the component functions, we need CREATE on the keyspace's functions
        DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER,
                                                 ImmutableSet.of(Permission.CREATE),
                                                 FunctionResource.keyspace(KEYSPACE),
                                                 role);
        String aggDef = String.format(aggregateCql(sFunc, fFunc),
                                      KEYSPACE + ".aggregate_for_permissions_test");

        assertUnauthorized(aggDef, sFunc, "int, int");
        grantExecuteOnFunction(sFunc);

        assertUnauthorized(aggDef, fFunc, "int");
        grantExecuteOnFunction(fFunc);

        getStatement(aggDef).checkAccess(clientState);
    }

    @Test
    public void revokeExecutePermissionsOnAggregateComponents() throws Throwable
    {
        String sFunc = createSimpleStateFunction();
        String fFunc = createSimpleFinalFunction();
        String aggDef = aggregateCql(sFunc, fFunc);
        grantExecuteOnFunction(sFunc);
        grantExecuteOnFunction(fFunc);

        String aggregate = createAggregate(KEYSPACE, "int", aggDef);
        grantExecuteOnFunction(aggregate);

        String cql = String.format("SELECT %s(v1) FROM %s",
                                   aggregate,
                                   KEYSPACE + "." + currentTable());
        getStatement(cql).checkAccess(clientState);

        // check that revoking EXECUTE permission on any one of the
        // component functions means we lose the ability to execute it
        revokeExecuteOnFunction(aggregate);
        assertUnauthorized(cql, aggregate, "int");
        grantExecuteOnFunction(aggregate);
        getStatement(cql).checkAccess(clientState);

        revokeExecuteOnFunction(sFunc);
        assertUnauthorized(cql, sFunc, "int, int");
        grantExecuteOnFunction(sFunc);
        getStatement(cql).checkAccess(clientState);

        revokeExecuteOnFunction(fFunc);
        assertUnauthorized(cql, fFunc, "int");
        grantExecuteOnFunction(fFunc);
        getStatement(cql).checkAccess(clientState);
    }

    @Test
    public void functionWrappingAggregate() throws Throwable
    {
        String outerFunc = createFunction("int",
                                          "CREATE FUNCTION %s(input int) " +
                                          "CALLED ON NULL INPUT " +
                                          "RETURNS int " +
                                          "LANGUAGE java " +
                                          "AS 'return input;'");

        String sFunc = createSimpleStateFunction();
        String fFunc = createSimpleFinalFunction();
        String aggDef = aggregateCql(sFunc, fFunc);
        grantExecuteOnFunction(sFunc);
        grantExecuteOnFunction(fFunc);

        String aggregate = createAggregate(KEYSPACE, "int", aggDef);

        String cql = String.format("SELECT %s(%s(v1)) FROM %s",
                                   outerFunc,
                                   aggregate,
                                   KEYSPACE + "." + currentTable());

        assertUnauthorized(cql, outerFunc, "int");
        grantExecuteOnFunction(outerFunc);

        assertUnauthorized(cql, aggregate, "int");
        grantExecuteOnFunction(aggregate);

        getStatement(cql).checkAccess(clientState);
    }

    @Test
    public void aggregateWrappingFunction() throws Throwable
    {
        String innerFunc = createFunction("int",
                                          "CREATE FUNCTION %s(input int) " +
                                          "CALLED ON NULL INPUT " +
                                          "RETURNS int " +
                                          "LANGUAGE java " +
                                          "AS 'return input;'");

        String sFunc = createSimpleStateFunction();
        String fFunc = createSimpleFinalFunction();
        String aggDef = aggregateCql(sFunc, fFunc);
        grantExecuteOnFunction(sFunc);
        grantExecuteOnFunction(fFunc);

        String aggregate = createAggregate(KEYSPACE, "int", aggDef);

        String cql = String.format("SELECT %s(%s(v1)) FROM %s",
                                   aggregate,
                                   innerFunc,
                                   KEYSPACE + "." + currentTable());

        assertUnauthorized(cql, aggregate, "int");
        grantExecuteOnFunction(aggregate);

        assertUnauthorized(cql, innerFunc, "int");
        grantExecuteOnFunction(innerFunc);

        getStatement(cql).checkAccess(clientState);
    }

    @Test
    public void grantAndRevokeSyntaxRequiresExplicitKeyspace() throws Throwable
    {
        setupTable("CREATE TABLE %s (k int, s int STATIC, v1 int, v2 int, PRIMARY KEY(k, v1))");
        String functionName = shortFunctionName(createSimpleFunction());
        assertRequiresKeyspace(String.format("GRANT EXECUTE ON FUNCTION %s() TO %s",
                                             functionName,
                                             role.getRoleName()));
        assertRequiresKeyspace(String.format("REVOKE EXECUTE ON FUNCTION %s() FROM %s",
                                             functionName,
                                             role.getRoleName()));
    }

    private void assertRequiresKeyspace(String cql) throws Throwable
    {
        try
        {
            getStatement(cql);
        }
        catch (InvalidRequestException e)
        {
            assertEquals("In this context function name must be explictly qualified by a keyspace", e.getMessage());
        }
    }

    private void assertPermissionsOnNestedFunctions(String innerFunction, String outerFunction) throws Throwable
    {
        String cql = String.format("SELECT k, %s FROM %s WHERE k=0",
                                   functionCall(outerFunction, functionCall(innerFunction)),
                                   KEYSPACE + "." + currentTable());
        // fail fast with an UAE on the first function
        assertUnauthorized(cql, outerFunction, "int");
        grantExecuteOnFunction(outerFunction);

        // after granting execute on the first function, still fail due to the inner function
        assertUnauthorized(cql, innerFunction, "");
        grantExecuteOnFunction(innerFunction);

        // now execution of both is permitted
        getStatement(cql).checkAccess(clientState);
    }

    private void assertPermissionsOnFunction(String cql, String functionName) throws Throwable
    {
        assertPermissionsOnFunction(cql, functionName, "");
    }

    private void assertPermissionsOnFunction(String cql, String functionName, String argTypes) throws Throwable
    {
        assertUnauthorized(cql, functionName, argTypes);
        grantExecuteOnFunction(functionName);
        getStatement(cql).checkAccess(clientState);
    }

    private void assertUnauthorized(BatchStatement batch, Iterable<String> functionNames) throws Throwable
    {
        try
        {
            batch.checkAccess(clientState);
            fail("Expected an UnauthorizedException, but none was thrown");
        }
        catch (UnauthorizedException e)
        {
            String functions = String.format("(%s)", Joiner.on("|").join(functionNames));
            assertTrue(e.getLocalizedMessage()
                        .matches(String.format("User %s has no EXECUTE permission on <function %s\\(\\)> or any of its parents",
                                               roleName,
                                               functions)));
        }
    }

    private void assertUnauthorized(String cql, String functionName, String argTypes) throws Throwable
    {
        try
        {
            getStatement(cql).checkAccess(clientState);
            fail("Expected an UnauthorizedException, but none was thrown");
        }
        catch (UnauthorizedException e)
        {
            assertEquals(String.format("User %s has no EXECUTE permission on <function %s(%s)> or any of its parents",
                                       roleName,
                                       functionName,
                                       argTypes),
                         e.getLocalizedMessage());
        }
    }

    private void grantExecuteOnFunction(String functionName)
    {
            DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER,
                                                     ImmutableSet.of(Permission.EXECUTE),
                                                     functionResource(functionName),
                                                     role);
    }

    private void revokeExecuteOnFunction(String functionName)
    {
        DatabaseDescriptor.getAuthorizer().revoke(AuthenticatedUser.SYSTEM_USER,
                                                  ImmutableSet.of(Permission.EXECUTE),
                                                  functionResource(functionName),
                                                  role);
    }

    void setupClientState()
    {

        try
        {
            role = RoleResource.role(roleName);
            // use reflection to set the logged in user so that we don't need to
            // bother setting up an IRoleManager
            user = new AuthenticatedUser(roleName);
            clientState = ClientState.forInternalCalls();
            Field userField = ClientState.class.getDeclaredField("user");
            userField.setAccessible(true);
            userField.set(clientState, user);
        }
        catch (IllegalAccessException | NoSuchFieldException e)
        {
            throw new RuntimeException(e);
        }
    }

    private void setupTable(String tableDef) throws Throwable
    {
        createTable(tableDef);
        // test user needs SELECT & MODIFY on the table regardless of permissions on any function
        DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER,
                                                 ImmutableSet.of(Permission.SELECT, Permission.MODIFY),
                                                 DataResource.table(KEYSPACE, currentTable()),
                                                 RoleResource.role(user.getName()));
    }

    private String aggregateCql(String sFunc, String fFunc)
    {
        return "CREATE AGGREGATE %s(int) " +
               "SFUNC " + shortFunctionName(sFunc) + " " +
               "STYPE int " +
               "FINALFUNC " + shortFunctionName(fFunc) + " " +
               "INITCOND 0";
    }

    private String createSimpleStateFunction() throws Throwable
    {
        return createFunction("int, int",
                              "CREATE FUNCTION %s(a int, b int) " +
                              "CALLED ON NULL INPUT " +
                              "RETURNS int " +
                              "LANGUAGE java " +
                              "AS 'return Integer.valueOf( (a != null ? a.intValue() : 0 ) + b.intValue());'");
    }

    private String createSimpleFinalFunction() throws Throwable
    {
        return createFunction("int",
                              "CREATE FUNCTION %s(a int) " +
                              "CALLED ON NULL INPUT " +
                              "RETURNS int " +
                              "LANGUAGE java " +
                              "AS 'return a;'");
    }

    private String createSimpleFunction() throws Throwable
    {
        return createFunction("",
                              "CREATE FUNCTION %s() " +
                              "  CALLED ON NULL INPUT " +
                              "  RETURNS int " +
                              "  LANGUAGE java " +
                              "  AS 'return Integer.valueOf(0);'");
    }

    private String createFunction(String argTypes, String functionDef) throws Throwable
    {
        return createFunction(KEYSPACE, argTypes, functionDef);
    }

    private CQLStatement getStatement(String cql)
    {
        return QueryProcessor.getStatement(cql, clientState).statement;
    }

    private FunctionResource functionResource(String functionName)
    {
        // Note that this is somewhat brittle as it assumes that function names are
        // truly unique. As such, it will break in the face of overloading.
        // It is here to avoid having to duplicate the functionality of CqlParser
        // for transforming cql types into AbstractTypes
        FunctionName fn = parseFunctionName(functionName);
        Collection<Function> functions = Schema.instance.getFunctions(fn);
        assertEquals(String.format("Expected a single function definition for %s, but found %s",
                                   functionName,
                                   functions.size()),
                     1, functions.size());
        return FunctionResource.function(fn.keyspace, fn.name, functions.iterator().next().argTypes());
    }

    private String functionCall(String functionName, String...args)
    {
        return String.format("%s(%s)", functionName, Joiner.on(",").join(args));
    }

    static class StubAuthorizer implements IAuthorizer
    {
        Map<Pair<String, IResource>, Set<Permission>> userPermissions = new HashMap<>();

        private void clear()
        {
            userPermissions.clear();
        }

        public Set<Permission> authorize(AuthenticatedUser user, IResource resource)
        {
            Pair<String, IResource> key = Pair.create(user.getName(), resource);
            Set<Permission> perms = userPermissions.get(key);
            return perms != null ? perms : Collections.<Permission>emptySet();
        }

        public void grant(AuthenticatedUser performer,
                          Set<Permission> permissions,
                          IResource resource,
                          RoleResource grantee) throws RequestValidationException, RequestExecutionException
        {
            Pair<String, IResource> key = Pair.create(grantee.getRoleName(), resource);
            Set<Permission> perms = userPermissions.get(key);
            if (null == perms)
            {
                perms = new HashSet<>();
                userPermissions.put(key, perms);
            }
            perms.addAll(permissions);
        }

        public void revoke(AuthenticatedUser performer,
                           Set<Permission> permissions,
                           IResource resource,
                           RoleResource revokee) throws RequestValidationException, RequestExecutionException
        {
            Pair<String, IResource> key = Pair.create(revokee.getRoleName(), resource);
            Set<Permission> perms = userPermissions.get(key);
            if (null != perms)
                perms.removeAll(permissions);
            if (perms.isEmpty())
                userPermissions.remove(key);
        }

        public Set<PermissionDetails> list(AuthenticatedUser performer,
                                           Set<Permission> permissions,
                                           IResource resource,
                                           RoleResource grantee) throws RequestValidationException, RequestExecutionException
        {
            Pair<String, IResource> key = Pair.create(grantee.getRoleName(), resource);
            Set<Permission> perms = userPermissions.get(key);
            if (perms == null)
                return Collections.emptySet();


            Set<PermissionDetails> details = new HashSet<>();
            for (Permission permission : perms)
            {
                if (permissions.contains(permission))
                    details.add(new PermissionDetails(grantee.getRoleName(), resource, permission));
            }
            return details;
        }

        public void revokeAllFrom(RoleResource revokee)
        {
            for (Pair<String, IResource> key : userPermissions.keySet())
                if (key.left.equals(revokee.getRoleName()))
                    userPermissions.remove(key);
        }

        public void revokeAllOn(IResource droppedResource)
        {
            for (Pair<String, IResource> key : userPermissions.keySet())
                if (key.right.equals(droppedResource))
                    userPermissions.remove(key);

        }

        public Set<? extends IResource> protectedResources()
        {
            return Collections.emptySet();
        }

        public void validateConfiguration() throws ConfigurationException
        {

        }

        public void setup()
        {

        }
    }
}
