// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor;

import static org.junit.Assert.*;

import com.google.common.collect.Sets;
import org.junit.*;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.util.*;

/**
 * Test cases for {@link Acl}.
 */
public class AclTest {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  private static Set<UserPrincipal> U(String... names) {
    Set<UserPrincipal> set = new TreeSet<UserPrincipal>();
    for (String n : names) {
      set.add(new UserPrincipal(n));
    }
    return set;
  }

  private static Set<GroupPrincipal> G(String... names) {
    Set<GroupPrincipal> set = new TreeSet<GroupPrincipal>();
    for (String n : names) {
      set.add(new GroupPrincipal(n));
    }
    return set;
  }

  @Test
  public void testNonHierarchialUsage() {
    Acl acl = new Acl.Builder()
        .setPermitGroups(G("permitGroup"))
        .setDenyGroups(G("denyGroup"))
        .setPermitUsers(U("permitUser", "bothUser"))
        .setDenyUsers(U("denyUser", "bothUser"))
        .build();
    // Test all main combinations:
    // (user permitted, denied, or indeterminate) x (group permitted, denied,
    //   indeterminate, no groups)
    assertEquals(AuthzStatus.PERMIT, acl.isAuthorizedLocal(
        createIdentity("permitUser", "permitGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("permitUser", "denyGroup")));
    assertEquals(AuthzStatus.PERMIT, acl.isAuthorizedLocal(
        createIdentity("permitUser", "unknownGroup")));
    assertEquals(AuthzStatus.PERMIT, acl.isAuthorizedLocal(
        createIdentity("permitUser")));

    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("denyUser", "permitGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("denyUser", "denyGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("denyUser", "unknownGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("denyUser")));

    assertEquals(AuthzStatus.PERMIT, acl.isAuthorizedLocal(
        createIdentity("unknownUser", "permitGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("unknownUser", "denyGroup")));
    assertEquals(AuthzStatus.INDETERMINATE, acl.isAuthorizedLocal(
        createIdentity("unknownUser", "unknownGroup")));
    assertEquals(AuthzStatus.INDETERMINATE, acl.isAuthorizedLocal(
        createIdentity("unknownUser")));

    // Make sure that deny wins.
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("permitUser", "denyGroup", "permitGroup")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("bothUser", "permitGroup")));
  }

  @Test
  public void testNullInheritanceType() {
    thrown.expect(NullPointerException.class);
    Acl.Builder builder = new Acl.Builder().setInheritanceType(null);
  }

  @Test
  public void testDefaults() {
    Acl acl = Acl.EMPTY;
    assertEquals(Collections.emptySet(), acl.getDenyGroups());
    assertEquals(Collections.emptySet(), acl.getPermitGroups());
    assertEquals(Collections.emptySet(), acl.getDenyUsers());
    assertEquals(Collections.emptySet(), acl.getPermitUsers());
    assertNull(acl.getInheritFrom());
    assertEquals(Acl.InheritanceType.LEAF_NODE, acl.getInheritanceType());
  }

  @Test
  public void testAccessors() {
    final Set<GroupPrincipal> goldenDenyGroups = Collections.unmodifiableSet(
        new HashSet<GroupPrincipal>(G("dg1", "dg2", "g3")));
    final Set<GroupPrincipal> goldenPermitGroups = Collections.unmodifiableSet(
        new HashSet<GroupPrincipal>(G("pg1", "pg2", "g3")));
    final Set<UserPrincipal> goldenDenyUsers = Collections.unmodifiableSet(
        new HashSet<UserPrincipal>(U("du1", "du2", "du3", "u4")));
    final Set<UserPrincipal> goldenPermitUsers = Collections.unmodifiableSet(
        new HashSet<UserPrincipal>(U("pu1", "pu2", "u4", "g3")));
    final DocId goldenInheritFrom = new DocId("something");
    final Acl.InheritanceType goldenInheritType
        = Acl.InheritanceType.CHILD_OVERRIDES;

    Set<GroupPrincipal> denyGroups 
        = new HashSet<GroupPrincipal>(goldenDenyGroups);
    Set<GroupPrincipal> permitGroups 
        = new HashSet<GroupPrincipal>(goldenPermitGroups);
    Set<UserPrincipal> denyUsers
        = new HashSet<UserPrincipal>(goldenDenyUsers);
    Set<UserPrincipal> permitUsers
        = new HashSet<UserPrincipal>(goldenPermitUsers);
    Acl.Builder builder = new Acl.Builder()
        .setDenyGroups(denyGroups).setPermitGroups(permitGroups)
        .setDenyUsers(denyUsers).setPermitUsers(permitUsers)
        .setInheritFrom(goldenInheritFrom)
        .setInheritanceType(goldenInheritType);
    Acl acl = builder.build();
    assertEquals(goldenDenyGroups, acl.getDenyGroups());
    assertEquals(goldenPermitGroups, acl.getPermitGroups());
    assertEquals(goldenDenyUsers, acl.getDenyUsers());
    assertEquals(goldenPermitUsers, acl.getPermitUsers());
    assertEquals(goldenInheritFrom, acl.getInheritFrom());
    assertEquals(goldenInheritType, acl.getInheritanceType());

    // Verify the builder makes copies of provided data.
    denyGroups.clear();
    permitGroups.clear();
    denyUsers.clear();
    permitUsers.clear();
    assertEquals(acl, builder.build());

    // Verify that Acl doesn't mutate due to changes in Builder.
    builder.setDenyGroups(Collections.<GroupPrincipal>emptySet());
    builder.setPermitGroups(Collections.<GroupPrincipal>emptySet());
    builder.setDenyUsers(Collections.<UserPrincipal>emptySet());
    builder.setPermitUsers(Collections.<UserPrincipal>emptySet());
    builder.setInheritFrom(null);
    builder.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES);

    assertEquals(goldenDenyGroups, acl.getDenyGroups());
    assertEquals(goldenPermitGroups, acl.getPermitGroups());
    assertEquals(goldenDenyUsers, acl.getDenyUsers());
    assertEquals(goldenPermitUsers, acl.getPermitUsers());
    assertEquals(goldenInheritFrom, acl.getInheritFrom());
    assertEquals(goldenInheritType, acl.getInheritanceType());
  }

  @Test
  public void testTypeAgnosticAccessors() {
    Acl acl = new Acl.Builder()
        .setPermitUsers(U("todelete1")).setDenyUsers(U("todelete2"))
        .setPermitGroups(G("todelete3")).setDenyGroups(G("todelete4"))
        .setPermits(Sets.union(U("good1"), G("good2")))
        .setDenies(Sets.union(U("good3"), G("good4")))
        .build();
    assertEquals(new Acl.Builder()
        .setPermitUsers(U("good1")).setDenyUsers(U("good3"))
        .setPermitGroups(G("good2")).setDenyGroups(G("good4"))
        .build(), acl);
    assertEquals(Sets.union(U("good1"), G("good2")), acl.getPermits());
    assertEquals(Sets.union(U("good3"), G("good4")), acl.getDenies());
  }

  @Test
  public void testDenyGroupsImmutability() {
    Acl acl = new Acl.Builder().setEverythingCaseInsensitive()
        .setDenyGroups(G("item")).build();
    thrown.expect(UnsupportedOperationException.class);
    acl.getDenyGroups().clear();
  }

  @Test
  public void testPermitGroupsImmutability() {
    Acl acl = new Acl.Builder().setPermitGroups(G("item")).build();
    thrown.expect(UnsupportedOperationException.class);
    acl.getPermitGroups().clear();
  }

  @Test
  public void testDenyUsersImmutability() {
    Acl acl = new Acl.Builder().setDenyUsers(U("item")).build();
    thrown.expect(UnsupportedOperationException.class);
    acl.getDenyUsers().clear();
  }

  @Test
  public void testPermitUsersImmutability() {
    Acl acl = new Acl.Builder().setEverythingCaseInsensitive()
        .setPermitUsers(U("item")).build();
    thrown.expect(UnsupportedOperationException.class);
    acl.getPermitUsers().clear();
  }

  @Test
  public void testNullUser() {
    Acl.Builder builder = new Acl.Builder();
    thrown.expect(NullPointerException.class);
    builder.setPermitUsers(Arrays.asList((UserPrincipal) null));
  }

  @Test
  public void testEmptyGroup() {
    Acl.Builder builder = new Acl.Builder();
    thrown.expect(IllegalArgumentException.class);
    builder.setDenyGroups(G(""));
  }

  @Test
  public void testWhitespaceSurroundingUserBefore() {
    Acl.Builder builder = new Acl.Builder();
    thrown.expect(IllegalArgumentException.class);
    builder.setDenyUsers(U(" test"));
  }

  @Test
  public void testWhitespaceSurroundingUserAfter() {
    Acl.Builder builder = new Acl.Builder();
    thrown.expect(IllegalArgumentException.class);
    builder.setDenyUsers(U("test\t"));
  }

  @Test
  public void testToString() {
    Acl acl = new Acl.Builder()
        .setDenyGroups(new HashSet<GroupPrincipal>(G("dg1", "dg2", "g3")))
        .setPermitGroups(new HashSet<GroupPrincipal>(G("pg1", "pg2", "g3")))
        .setDenyUsers(new HashSet<UserPrincipal>(U("du1", "du2", "du3", "u4")))
        .setPermitUsers(new HashSet<UserPrincipal>(U("pu1", "pu2", "u4", "g3")))
        .setInheritFrom(new DocId("something"))
        .setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES).build();

    assertEquals("Acl(caseSensitive=true, "
        + "inheritFrom=DocId(something), "
        + "inheritType=CHILD_OVERRIDES, "
        + "permitGroups=[Principal(Group,g3,Default), Principal(Group,pg1,Default), "
            + "Principal(Group,pg2,Default)], "
        + "denyGroups=[Principal(Group,dg1,Default), Principal(Group,dg2,Default), "
            + "Principal(Group,g3,Default)], "
        + "permitUsers=[Principal(User,g3,Default), Principal(User,pu1,Default), "
            + "Principal(User,pu2,Default), Principal(User,u4,Default)], "
        + "denyUsers=[Principal(User,du1,Default), Principal(User,du2,Default), "
            + "Principal(User,du3,Default), Principal(User,u4,Default)])"
        , acl.toString());
  }

  @Test
  public void testEquals() {
    Acl.Builder builder = new Acl.Builder();
    Acl base = builder.build();

    builder.setPermitGroups(G("testing"));
    Acl permitGroups = builder.build();
    builder.setPermitGroups(Collections.<GroupPrincipal>emptySet());

    builder.setDenyGroups(G("testing"));
    Acl denyGroups = builder.build();
    builder.setDenyGroups(Collections.<GroupPrincipal>emptySet());

    builder.setPermitUsers(U("testing"));
    Acl permitUsers = builder.build();
    builder.setPermitUsers(Collections.<UserPrincipal>emptySet());

    builder.setDenyUsers(U("testing"));
    Acl denyUsers = builder.build();
    builder.setDenyUsers(Collections.<UserPrincipal>emptySet());

    builder.setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES);
    builder.setInheritFrom(new DocId("testing"));
    Acl inheritFrom1 = builder.build();

    builder.setInheritFrom(new DocId("testing2"));
    Acl inheritFrom2 = builder.build();

    builder.setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES);
    Acl childOverrides = builder.build();

    builder.setInheritFrom(new DocId("testing2"));
    Acl childOverridesAgain = builder.build();
    builder.setInheritanceType(Acl.InheritanceType.LEAF_NODE);
    builder.setInheritFrom(null);

    Acl baseAgain = builder.build();

    assertFalse(base.equals(null));
    assertTrue(base.equals(base));
    assertFalse(base.equals(permitGroups));
    assertFalse(base.equals(denyGroups));
    assertFalse(base.equals(permitUsers));
    assertFalse(base.equals(denyUsers));
    assertFalse(base.equals(inheritFrom1));
    assertFalse(base.equals(inheritFrom2));
    assertFalse(base.equals(childOverrides));
    assertTrue(base.equals(baseAgain));

    assertFalse(inheritFrom1.equals(inheritFrom2));
    assertFalse(inheritFrom2.equals(childOverrides));
    assertTrue(childOverrides.equals(childOverridesAgain));

    assertEquals(base.hashCode(), base.hashCode());
    assertEquals(base.hashCode(), baseAgain.hashCode());

    builder.setPermitGroups(G("testing"));
    builder.setDenyGroups(G("testing"));
    builder.setPermitUsers(U("testing"));
    builder.setDenyUsers(U("testing"));
    Acl withCase = builder.build();
    Acl noCase = builder.setEverythingCaseInsensitive().build(); 
    Acl caseAgain = builder.setEverythingCaseSensitive().build();
    builder.setEverythingCaseInsensitive();
    Acl noCase2 = builder.setPermitUsers(U("TeSTiNg")).build(); 
    Acl noCase3 = builder.setPermitUsers(U("tEstInG")).build(); 
    assertEquals(withCase, caseAgain);
    assertEquals(noCase2, noCase);
    assertEquals(noCase2, noCase3);
    assertFalse(withCase.equals(noCase));
    assertFalse(caseAgain.equals(noCase));
    assertEquals(withCase.hashCode(), caseAgain.hashCode());
    /* It is conceivable that hashCode of different object matches.
       So this test could fail in the future; it is unlikely. */
    assertFalse(withCase.hashCode() == noCase.hashCode());
    assertFalse(caseAgain.hashCode() == noCase.hashCode());
  }

  @Test
  public void testCopy() {
    Set<GroupPrincipal> denyGroups = Collections.unmodifiableSet(
        new HashSet<GroupPrincipal>(G("dg1", "dg2", "g3")));
    Set<GroupPrincipal> permitGroups = Collections.unmodifiableSet(
        new HashSet<GroupPrincipal>(G("pg1", "pg2", "g3")));
    Set<UserPrincipal> denyUsers = Collections.unmodifiableSet(
        new HashSet<UserPrincipal>(U("du1", "du2", "du3", "u4")));
    Set<UserPrincipal> permitUsers = Collections.unmodifiableSet(
        new HashSet<UserPrincipal>(U("pu1", "pu2", "u4", "g3")));
    DocId inheritFrom = new DocId("something");
    Acl.InheritanceType inheritType = Acl.InheritanceType.CHILD_OVERRIDES;

    Acl aclOrig = new Acl.Builder()
        .setDenyGroups(denyGroups).setPermitGroups(permitGroups)
        .setDenyUsers(denyUsers).setPermitUsers(permitUsers)
        .setInheritFrom(inheritFrom).setInheritanceType(inheritType).build();
    Acl acl = new Acl.Builder(aclOrig).build();
    assertEquals(denyGroups, acl.getDenyGroups());
    assertEquals(permitGroups, acl.getPermitGroups());
    assertEquals(denyUsers, acl.getDenyUsers());
    assertEquals(permitUsers, acl.getPermitUsers());
    assertEquals(inheritFrom, acl.getInheritFrom());
    assertEquals(inheritType, acl.getInheritanceType());
    assertTrue(aclOrig.equals(acl));
    assertEquals(aclOrig.hashCode(), acl.hashCode());
  }

  @Test
  public void testInheritance() {
    Acl root = new Acl.Builder().setPermitUsers(U("user"))
        .setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES).build();
    Acl middle = new Acl.Builder()
        .setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES)
        .setInheritFrom(new DocId("parent")).build();
    Acl leaf = new Acl.Builder().setDenyUsers(U("user"))
        .setInheritFrom(new DocId("parent")).build();
    Collection<String> empty
        = Collections.unmodifiableList(Collections.<String>emptyList());

    assertEquals(AuthzStatus.PERMIT, Acl.isAuthorized(createIdentity("user"),
          Arrays.asList(root, middle, leaf)));
  }

  @Test
  public void testEmptyAclChain() {
    thrown.expect(IllegalArgumentException.class);
    Acl.isAuthorized(createIdentity("user"), Collections.<Acl>emptyList());
  }

  @Test
  public void testInvalidRootAclChain() {
    Acl acl = new Acl.Builder().setInheritFrom(new DocId("parent")).build();
    thrown.expect(IllegalArgumentException.class);
    Acl.isAuthorized(createIdentity("user"), Collections.singletonList(acl));
  }

  @Test
  public void testInvalidChildInChain() {
    Acl.Builder builder = new Acl.Builder();
    Acl root = builder.build();
    Acl child = builder.setInheritFrom(new DocId("parent")).build();
    Acl broken = root;

    thrown.expect(IllegalArgumentException.class);
    Acl.isAuthorized(createIdentity("user"),
                     Arrays.asList(root, child, broken));
  }

  @Test
  public void testIsAuthorizedBatchNullEntry() throws IOException {
    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), null);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("alice", "eng");
    thrown.expect(NullPointerException.class);
    Acl.isAuthorizedBatch(identity, Arrays.asList(new DocId("1")),
                          retriever);
  }

  @Test
  public void testIsAuthorizedBatchMissingCachedParent() throws IOException {
    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    DocId id = new DocId("1");
    DocId id2 = new DocId("2");
    acls.put(id, new Acl.Builder().setInheritFrom(id2)
        .setPermitUsers(U("user")).build());
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("user", "wrong group");
    assertEquals(AuthzStatus.INDETERMINATE, Acl.isAuthorizedBatch(identity,
        Arrays.asList(id, id2), retriever).get(id));
  }

  @Test
  public void testIsAuthorizedBatchOptimized() throws IOException {
    final DocId file = new DocId("file1");
    final DocId parent = new DocId("parent");

    final Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(file, new Acl.Builder().setInheritFrom(parent).build());
    acls.put(parent,
        new Acl.Builder().setPermitUsers(U("user"))
        .setInheritanceType(Acl.InheritanceType.CHILD_OVERRIDES).build());

    Acl.BatchRetriever retriever = new Acl.BatchRetriever() {
      private boolean accessed = false;

      @Override
      public Map<DocId, Acl> retrieveAcls(Set<DocId> ids) {
        assertEquals(false, accessed);
        accessed = true;
        assertEquals(Arrays.asList(file), new ArrayList<DocId>(ids));
        return acls;
      }
    };
    AuthnIdentity identity = createIdentity("user");
    assertEquals(AuthzStatus.PERMIT, Acl.isAuthorizedBatch(identity,
        Arrays.asList(file), retriever).get(file));
  }

  @Test
  public void testIsAuthorizedBatchPoorOptimized() throws IOException {
    final DocId file1 = new DocId("file1");
    final DocId file2 = new DocId("file2");
    final DocId missingParent = new DocId("missing parent");
    final DocId parent = new DocId("parent");
    final DocId root = new DocId("root");

    final Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(file1, new Acl.Builder().setInheritFrom(parent).build());
    acls.put(file2, new Acl.Builder().setInheritFrom(missingParent)
        .setDenyUsers(U("unrelated")).build());
    acls.put(parent, new Acl.Builder().setInheritFrom(root)
        .setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES).build());
    acls.put(root,
        new Acl.Builder().setPermitUsers(U("user"))
        .setInheritanceType(Acl.InheritanceType.PARENT_OVERRIDES).build());

    Acl.BatchRetriever retriever = new Acl.BatchRetriever() {
      @Override
      public Map<DocId, Acl> retrieveAcls(Set<DocId> ids) {
        Set<DocId> case1 = new HashSet<DocId>(Arrays.asList(file1, file2));
        Set<DocId> case2
            = new HashSet<DocId>(Arrays.asList(missingParent, parent));
        Set<DocId> case3 = new HashSet<DocId>(Arrays.asList(root));
        Map<DocId, Acl> result = new HashMap<DocId, Acl>();
        if (case1.equals(ids)) {
          result.put(file1, acls.get(file1));
          result.put(file2, acls.get(file2));
        } else if (case2.equals(ids)) {
          // Don't provide missingParent, since it is missing.
          result.put(parent, acls.get(parent));
          // Be inefficient and re-provide some ACLs.
          result.put(file1, acls.get(file1));
        } else if (case3.equals(ids)) {
          // Provide results for something we didn't previously. This shouldn't
          // change our results.
          result.put(missingParent, acls.get(root));
          result.put(root, acls.get(root));
        } else {
          fail();
        }
        return result;
      }
    };

    Map<DocId, AuthzStatus> golden = new HashMap<DocId, AuthzStatus>();
    golden.put(file1, AuthzStatus.PERMIT);
    golden.put(file2, AuthzStatus.INDETERMINATE);
    golden = Collections.unmodifiableMap(golden);

    AuthnIdentity identity = createIdentity("user");
    assertEquals(golden, Acl.isAuthorizedBatch(identity,
        Arrays.asList(file1, file2), retriever));
  }

  @Test
  public void testEmptyIsAuthorized() {
    assertEquals(AuthzStatus.INDETERMINATE, Acl.isAuthorized(
        createIdentity("user"), Arrays.asList(Acl.EMPTY)));
  }

  @Test
  public void testCommonForm() {
    assertEquals("child-overrides",
                 Acl.InheritanceType.CHILD_OVERRIDES.getCommonForm());
  }

  private static String split(String usersOrGroups)[] {
    if ("".equals(usersOrGroups)) {
      return new String[0];
    }
    return usersOrGroups.split(",");
  }

  private static Acl buildAcl(String permitUsers, String permitGroups,
                              String denyUsers, String denyGroups) {
    return new Acl.Builder()
        .setPermitUsers(U(split(permitUsers)))
        .setPermitGroups(G(split(permitGroups)))
        .setDenyUsers(U(split(denyUsers)))
        .setDenyGroups(G(split(denyGroups)))
        .build();
  }

  private static Acl buildAcl(String permitUsers, String permitGroups,
                              String denyUsers, String denyGroups,
                              Acl.InheritanceType type) {
    return new Acl.Builder(
        buildAcl(permitUsers, permitGroups, denyUsers, denyGroups))
        .setInheritanceType(type).build();
  }

  private static Acl buildAcl(String permitUsers, String permitGroups,
                              String denyUsers, String denyGroups,
                              String inheritFrom) {
    return new Acl.Builder(
        buildAcl(permitUsers, permitGroups, denyUsers, denyGroups))
        .setInheritFrom(new DocId(inheritFrom)).build();
  }

  private static Acl buildAcl(String permitUsers, String permitGroups,
                              String denyUsers, String denyGroups,
                              Acl.InheritanceType type, String inheritFrom) {
    return new Acl.Builder(
        buildAcl(permitUsers, permitGroups, denyUsers, denyGroups))
        .setInheritanceType(type).setInheritFrom(new DocId(inheritFrom))
        .build();
  }

  private AuthzStatus callIsAuthorized(AuthnIdentity identity, DocId id,
      Acl.BatchRetriever retriever) throws IOException {
    return Acl.isAuthorizedBatch(identity, Arrays.asList(id), retriever)
        .get(id);
  }

  private void testRule(Acl.InheritanceType rule, AuthzStatus child,
                        AuthzStatus parent, AuthzStatus expectedResult) {
    assertEquals(expectedResult, rule.isAuthorized(
        new MockDecision(child), new MockDecision(parent)));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testCombineChildOverrides() {
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.DENY,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.INDETERMINATE,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.CHILD_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.INDETERMINATE,
             AuthzStatus.INDETERMINATE);
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testCombineParentOverrides() {
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.PERMIT, AuthzStatus.INDETERMINATE,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.DENY, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.PARENT_OVERRIDES,
             AuthzStatus.INDETERMINATE, AuthzStatus.INDETERMINATE,
             AuthzStatus.INDETERMINATE);
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testCombineAndBothPermit() {
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.PERMIT, AuthzStatus.PERMIT,
             AuthzStatus.PERMIT);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.PERMIT, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.PERMIT, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.DENY, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.DENY, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.DENY, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.INDETERMINATE, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.INDETERMINATE, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.AND_BOTH_PERMIT,
             AuthzStatus.INDETERMINATE, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
  }

  @Test
  public void testCombineLeafNode() {
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.PERMIT, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.PERMIT, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.PERMIT, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.DENY, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.DENY, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.DENY, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.INDETERMINATE, AuthzStatus.PERMIT,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.INDETERMINATE, AuthzStatus.DENY,
             AuthzStatus.DENY);
    testRule(Acl.InheritanceType.LEAF_NODE,
             AuthzStatus.INDETERMINATE, AuthzStatus.INDETERMINATE,
             AuthzStatus.DENY);
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testAuthorizeNoInheritance() throws IOException {
    // Test basic rule: DENY overrides PERMIT.
    Acl expectedAcl1 = buildAcl("", "eng,hr", "", "eng,finance,interns");
    Acl expectedAcl2 = buildAcl("alice,bob", "", "bob,charlie,dave", "");
    Acl expectedAcl3 = buildAcl("alice,bob", "", "", "");
    Acl expectedAcl4 = buildAcl("", "", "bob,charlie,dave", "");
    Acl emptyAcl = Acl.EMPTY;

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), expectedAcl1);
    acls.put(new DocId("2"), expectedAcl2);
    acls.put(new DocId("3"), expectedAcl3);
    acls.put(new DocId("4"), expectedAcl4);
    acls.put(new DocId("5"), emptyAcl);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("alice", "eng");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));

    identity = createIdentity("bob", "hr");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("2"), retriever));
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("3"), retriever));
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("4"), retriever));

    identity = createIdentity("alice", "hr");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("2"), retriever));
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("3"), retriever));
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("4"), retriever));

    identity = createIdentity("eve");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("3"), retriever));
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("4"), retriever));

    identity = createIdentity("no-importante", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("3"), retriever));
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("4"), retriever));

    // Docs with empty ACLs should return INDETERMINATE.
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, new DocId("5"), retriever));
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, new DocId("9"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A Windows filesystem-like scenario:
  // a file has no ACL, inherits PERMIT from folder
  @Test
  public void testAuthorizeChildInheritsPermit() throws IOException {
    Acl file = buildAcl("", "", "", "", "Folder");
    Acl folder = buildAcl("adam", "", "", "",
        Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A Windows filesystem-like scenario:
  // a file has no ACL, inherits DENY from folder
  @Test
  public void testAuthorizeChildInheritsDeny() throws IOException {
    Acl file = buildAcl("", "", "", "", "Folder");
    Acl folder = buildAcl("", "", "adam", "",
        Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A Windows filesystem-like scenario:
  // a file has a PERMIT ACL, overrides folder's DENY
  @Test
  public void testAuthorizeChildOverridesDeny() throws IOException {
    Acl file = buildAcl("adam", "", "", "", "Folder");
    Acl folder = buildAcl("", "", "", "eng",
        Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam", "eng");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A Windows filesystem-like scenario:
  // a file has a DENY ACL, overrides folder's PERMIT
  @Test
  public void testAuthorizeChildOverridesPermit() throws IOException {
    Acl file = buildAcl("", "", "eve", "", "Folder");
    Acl folder = buildAcl("", "qa", "", "",
        Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    // eve is denied...
    AuthnIdentity identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
    // although qa is in general permitted.
    identity = createIdentity("bob", "qa");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A Windows share-like scenario:
  // - a share has a DENY ACL, which overrides any PERMITS underneath it.
  // - a share has a PERMIT ACL, which matches a PERMIT from underneath
  // - a share has a PERMIT ACL, but does not match INDETERMINATE from
  //   underneath.
  @Test
  public void testAuthorizeParentOverridesPermit() throws IOException {
    Acl file = buildAcl("bob", "qa", "", "", "Folder");
    Acl folder = buildAcl("adam", "", "", "",
        Acl.InheritanceType.CHILD_OVERRIDES, "Share");
    Acl share = buildAcl("charlie", "finance", "", "eng",
        Acl.InheritanceType.AND_BOTH_PERMIT);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    acls.put(new DocId("Share"), share);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    // Permitted by Folder, but denied by Share
    AuthnIdentity identity = createIdentity("adam", "eng");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));

    // Permitted by File (via group), but denied by Share (by omission)
    identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));

    // Permitted by File (via user), permitted by Share (via group)
    identity = createIdentity("bob", "finance");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));

    // Permitted by Share (via user), but INDETERMINATE otherwise, so DENY
    identity = createIdentity("charlie");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A somewhat contrived Windows share scenario:
  // a file has a DENY ACL, does not agree with share's PERMIT
  @Test
  public void testAuthorizeParentOverridesDeny() throws IOException {
    Acl file = buildAcl("", "", "eve", "", "Share");
    Acl share = buildAcl("", "qa", "", "", Acl.InheritanceType.AND_BOTH_PERMIT);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Share"), share);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A contrived Windows file system scenario:
  // neither file nor folder has any ACLs
  @Test
  public void testAuthorizeInheritanceNoAcl() throws IOException {
    Acl file = buildAcl("", "", "", "", "Folder");
    Acl folder = buildAcl("", "", "", "", Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder"), folder);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // A SharePoint example: a subsite grants PERMIT and website overrides a
  // PERMIT
  @Test
  public void testAuthorizeSP() throws IOException {
    Acl file = buildAcl("eve", "", "", "", "Subsite");
    Acl subsite = buildAcl("", "eng", "", "",
        Acl.InheritanceType.CHILD_OVERRIDES, "Website");
    Acl website = buildAcl("", "", "", "qa",
        Acl.InheritanceType.PARENT_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Subsite"), subsite);
    acls.put(new DocId("Website"), website);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam", "eng");
    assertEquals(AuthzStatus.PERMIT,
        callIsAuthorized(identity, new DocId("1"), retriever));

    identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.DENY,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // We hope the backend will not have cycles in inhertitance trees,
  // but Authorize has to be robust against the possibility.
  @Test
  public void testAuthorizeInheritanceCycle() throws IOException {
    Acl file = buildAcl("", "qa", "", "", "Folder");
    Acl folder = buildAcl("adam", "", "", "",
        Acl.InheritanceType.CHILD_OVERRIDES, "Share");
    Acl share = buildAcl("", "", "", "eng",
        Acl.InheritanceType.AND_BOTH_PERMIT, "File");

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    DocId fid = new DocId("File");
    acls.put(fid, file);
    acls.put(new DocId("Folder"), folder);
    acls.put(new DocId("Share"), share);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam", "eng");
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, fid, retriever));

    identity = createIdentity("eve", "qa");
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, fid, retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testAuthorizeInheritanceMissingAclNonEmpty() throws IOException {
    Acl file = buildAcl("", "group", "", "", "Folder");

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    // No "Folder" ACLs
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("user", "group");
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  @Test
  public void testAuthorizeInheritanceMissingAclEmpty() throws IOException {
    Acl file = buildAcl("", "", "", "", "Folder");

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    // No "Folder" ACLs
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("user", "group");
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  // Port of test from GSA with similar name. Should be kept in sync.
  // Illegal chain: it contains a LEAF_NODE in the middle
  @Test
  public void testAuthorizeIllegalChain() throws IOException {
    Acl file = buildAcl("", "", "", "", "Folder1");
    Acl folder1 = buildAcl("adam", "", "", "", Acl.InheritanceType.LEAF_NODE,
        "Folder2");
    Acl folder2 = buildAcl("", "", "", "", Acl.InheritanceType.CHILD_OVERRIDES);

    Map<DocId, Acl> acls = new HashMap<DocId, Acl>();
    acls.put(new DocId("1"), file);
    acls.put(new DocId("Folder1"), folder1);
    acls.put(new DocId("Folder2"), folder2);
    Acl.BatchRetriever retriever = new MockBatchRetriever(acls);

    AuthnIdentity identity = createIdentity("adam");
    assertEquals(AuthzStatus.INDETERMINATE,
        callIsAuthorized(identity, new DocId("1"), retriever));
  }

  @Test
  public void testDefaultCaseSensitive() {
    assertTrue(new Acl.Builder().build().isEverythingCaseSensitive());
    assertTrue(!new Acl.Builder().build().isEverythingCaseInsensitive());
  }

  @Test
  public void testCanChangeCaseSensitivity() {
    assertFalse(new Acl.Builder().setEverythingCaseInsensitive()
        .build().isEverythingCaseSensitive());
    assertTrue(new Acl.Builder()
        .setEverythingCaseInsensitive().setEverythingCaseSensitive()
        .build().isEverythingCaseSensitive());
  }

  @Test
  public void testCaseInsensitiveUsage() {
    Acl acl = new Acl.Builder()
        .setPermitGroups(G("PermiTGroup"))
        .setDenyGroups(G("DenYGroup"))
        .setPermitUsers(U("PermiTUser", "BotHUser"))
        .setDenyUsers(U("DenYUser", "BotHUser"))
        .setEverythingCaseInsensitive()
        .build();
    assertEquals(AuthzStatus.PERMIT, acl.isAuthorizedLocal(
        createIdentity("permitUser")));
    assertEquals(AuthzStatus.DENY, acl.isAuthorizedLocal(
        createIdentity("denyUser")));
    assertEquals(AuthzStatus.INDETERMINATE, acl.isAuthorizedLocal(
        createIdentity("unknownUser")));
  }

  private AuthnIdentity createIdentity(String username, String... groups) {
    return createIdentity(username, Arrays.asList(groups));
  }

  private AuthnIdentity createIdentity(final String username,
      List<String> groups) {
    final UserPrincipal user = new UserPrincipal(username);
    final Set<GroupPrincipal> groupSet = Collections.unmodifiableSet(
        new TreeSet<GroupPrincipal>(GroupPrincipal.makeSet(groups)));
    return new AuthnIdentity() {
      @Override
      public UserPrincipal getUser() {
        return user;
      }

      @Override
      public String getPassword() {
        return null;
      }

      @Override
      public Set<GroupPrincipal> getGroups() {
        return groupSet;
      }
    };
  }

  private static class MockBatchRetriever implements Acl.BatchRetriever {
    private Map<DocId, Acl> acls;

    public MockBatchRetriever(Map<DocId, Acl> acls) {
      this.acls = acls;
    }

    @Override
    public Map<DocId, Acl> retrieveAcls(Set<DocId> ids) {
      Map<DocId, Acl> result = new HashMap<DocId, Acl>(ids.size() * 2);
      for (DocId docId : ids) {
        if (acls.containsKey(docId)) {
          result.put(docId, acls.get(docId));
        }
      }
      return Collections.unmodifiableMap(result);
    }
  }

  private static class MockDecision extends Acl.Decision {
    private final AuthzStatus status;

    public MockDecision(AuthzStatus status) {
      this.status = status;
    }

    @Override
    protected AuthzStatus computeDecision() {
      return status;
    }
  }
}
