/*
 * 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);
    }

    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()
        {

        }
    }
}
