// Copyright (C) 2010 The Android Open Source Project
//
// 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.gerrit.server.permissions;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.entities.Permission.EDIT_TOPIC_NAME;
import static com.google.gerrit.entities.Permission.LABEL;
import static com.google.gerrit.entities.Permission.OWNER;
import static com.google.gerrit.entities.Permission.PUSH;
import static com.google.gerrit.entities.Permission.READ;
import static com.google.gerrit.entities.Permission.SUBMIT;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.CHANGE_OWNER;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.LabelId;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.PermissionRange;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.InvalidNameException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.InternalUser;
import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RefPattern;
import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.testing.InMemoryModule;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class RefControlTest {
  private static final AccountGroup.UUID ADMIN = AccountGroup.uuid("test.admin");
  private static final AccountGroup.UUID DEVS = AccountGroup.uuid("test.devs");

  private void assertAdminsAreOwnersAndDevsAreNot() throws Exception {
    ProjectControl uBlah = user(localKey, DEVS);
    ProjectControl uAdmin = user(localKey, DEVS, ADMIN);

    assertWithMessage("not owner").that(uBlah.isOwner()).isFalse();
    assertWithMessage("is owner").that(uAdmin.isOwner()).isTrue();
  }

  private void assertOwner(String ref, ProjectControl u) {
    assertWithMessage("OWN " + ref).that(u.controlForRef(ref).isOwner()).isTrue();
  }

  private void assertNotOwner(ProjectControl u) {
    assertWithMessage("not owner").that(u.isOwner()).isFalse();
  }

  private void assertAllRefsAreVisible(ProjectControl u) {
    assertWithMessage("all refs visible")
        .that(u.allRefsAreVisible(Collections.emptySet()))
        .isTrue();
  }

  private void assertAllRefsAreNotVisible(ProjectControl u) {
    assertWithMessage("all refs NOT visible")
        .that(u.allRefsAreVisible(Collections.emptySet()))
        .isFalse();
  }

  private void assertNotOwner(String ref, ProjectControl u) {
    assertWithMessage("NOT OWN " + ref).that(u.controlForRef(ref).isOwner()).isFalse();
  }

  private void assertCanAccess(ProjectControl u) {
    boolean access = u.asForProject().testOrFalse(ProjectPermission.ACCESS);
    assertWithMessage("can access").that(access).isTrue();
  }

  private void assertAccessDenied(ProjectControl u) {
    boolean access = u.asForProject().testOrFalse(ProjectPermission.ACCESS);
    assertWithMessage("cannot access").that(access).isFalse();
  }

  private void assertCanRead(String ref, ProjectControl u) {
    assertWithMessage("can read " + ref)
        .that(
            u.controlForRef(ref)
                .hasReadPermissionOnRef(
                    true)) // This should be false but the test relies on inheritance into refs/tags
        .isTrue();
  }

  private void assertCannotRead(String ref, ProjectControl u) {
    assertWithMessage("cannot read " + ref)
        .that(
            u.controlForRef(ref)
                .hasReadPermissionOnRef(
                    true)) // This should be false but the test relies on inheritance into refs/tags
        .isFalse();
  }

  private void assertCanSubmit(String ref, ProjectControl u) {
    assertWithMessage("can submit " + ref).that(u.controlForRef(ref).canSubmit(false)).isTrue();
  }

  private void assertCannotSubmit(String ref, ProjectControl u) {
    assertWithMessage("can submit " + ref).that(u.controlForRef(ref).canSubmit(false)).isFalse();
  }

  private void assertCanUpload(ProjectControl u) {
    assertWithMessage("can upload").that(u.canPushToAtLeastOneRef()).isTrue();
  }

  private void assertCreateChange(String ref, ProjectControl u) {
    boolean create = u.asForProject().ref(ref).testOrFalse(RefPermission.CREATE_CHANGE);
    assertWithMessage("can create change " + ref).that(create).isTrue();
  }

  private void assertCannotUpload(ProjectControl u) {
    assertWithMessage("cannot upload").that(u.canPushToAtLeastOneRef()).isFalse();
  }

  private void assertCannotCreateChange(String ref, ProjectControl u) {
    boolean create = u.asForProject().ref(ref).testOrFalse(RefPermission.CREATE_CHANGE);
    assertWithMessage("cannot create change " + ref).that(create).isFalse();
  }

  private void assertCanUpdate(String ref, ProjectControl u) {
    boolean update = u.asForProject().ref(ref).testOrFalse(RefPermission.UPDATE);
    assertWithMessage("can update " + ref).that(update).isTrue();
  }

  private void assertCannotUpdate(String ref, ProjectControl u) {
    boolean update = u.asForProject().ref(ref).testOrFalse(RefPermission.UPDATE);
    assertWithMessage("cannot update " + ref).that(update).isFalse();
  }

  private void assertCanForceUpdate(String ref, ProjectControl u) {
    boolean update = u.asForProject().ref(ref).testOrFalse(RefPermission.FORCE_UPDATE);
    assertWithMessage("can force push " + ref).that(update).isTrue();
  }

  private void assertCannotForceUpdate(String ref, ProjectControl u) {
    boolean update = u.asForProject().ref(ref).testOrFalse(RefPermission.FORCE_UPDATE);
    assertWithMessage("cannot force push " + ref).that(update).isFalse();
  }

  private void assertCanVote(int score, PermissionRange range) {
    assertWithMessage("can vote " + score).that(range.contains(score)).isTrue();
  }

  private void assertCannotVote(int score, PermissionRange range) {
    assertWithMessage("cannot vote " + score).that(range.contains(score)).isFalse();
  }

  private final AccountGroup.UUID fixers = AccountGroup.uuid("test.fixers");
  private final Project.NameKey localKey = Project.nameKey("local");
  private final Project.NameKey parentKey = Project.nameKey("parent");

  @Inject private AllProjectsName allProjectsName;
  @Inject private AllUsersName allUsersName;
  @Inject private InMemoryRepositoryManager repoManager;
  @Inject private MetaDataUpdate.Server metaDataUpdateFactory;
  @Inject private ProjectCache projectCache;
  @Inject private ProjectControl.Factory projectControlFactory;
  @Inject private ProjectOperations projectOperations;
  @Inject private SchemaCreator schemaCreator;
  @Inject private SingleVersionListener singleVersionListener;
  @Inject private ThreadLocalRequestContext requestContext;

  @Before
  public void setUp() throws Exception {
    Injector injector = Guice.createInjector(new InMemoryModule());
    injector.injectMembers(this);

    // Tests previously used ProjectConfig.Factory to create ProjectConfigs without going through
    // the ProjectCache, which was wrong. Manually call getInstance so we don't store it in a
    // field that is accessible to test methods.
    ProjectConfig.Factory projectConfigFactory = injector.getInstance(ProjectConfig.Factory.class);

    singleVersionListener.start();
    try {
      schemaCreator.create();
    } finally {
      singleVersionListener.stop();
    }

    // Clear out All-Projects and use the lowest-level API possible for project creation, so the
    // only ACL entries are exactly what is initialized by this test, and we aren't subject to
    // changing defaults in SchemaCreator or ProjectCreator.
    try (Repository allProjectsRepo = repoManager.createRepository(allProjectsName);
        TestRepository<Repository> tr = new TestRepository<>(allProjectsRepo)) {
      tr.delete(REFS_CONFIG);
      try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
        ProjectConfig allProjectsConfig = projectConfigFactory.create(allProjectsName);
        allProjectsConfig.load(md);
        LabelType cr = TestLabels.codeReview();
        allProjectsConfig.upsertLabelType(cr);
        allProjectsConfig.commit(md);
      }
    }

    repoManager.createRepository(parentKey).close();
    repoManager.createRepository(localKey).close();
    try (MetaDataUpdate md = metaDataUpdateFactory.create(localKey)) {
      ProjectConfig newLocal = projectConfigFactory.create(localKey);
      newLocal.load(md);
      newLocal.updateProject(p -> p.setParent(parentKey));
      newLocal.commit(md);
    }

    requestContext.setContext(() -> null);
  }

  @After
  public void tearDown() throws Exception {
    requestContext.setContext(null);
  }

  @Test
  public void ownerProject() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(ADMIN))
        .update();
    assertAdminsAreOwnersAndDevsAreNot();
  }

  @Test
  public void denyOwnerProject() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(ADMIN))
        .add(deny(OWNER).ref("refs/*").group(DEVS))
        .update();
    assertAdminsAreOwnersAndDevsAreNot();
  }

  @Test
  public void blockOwnerProject() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(ADMIN))
        .add(block(OWNER).ref("refs/*").group(DEVS))
        .update();
    assertAdminsAreOwnersAndDevsAreNot();
  }

  @Test
  public void allRefsAreVisibleForRegularProject() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(DEVS))
        .add(allow(READ).ref("refs/groups/*").group(DEVS))
        .add(allow(READ).ref("refs/users/default").group(DEVS))
        .update();

    assertAllRefsAreVisible(user(localKey, DEVS));
  }

  @Test
  public void allRefsAreNotVisibleForAllUsers() throws Exception {
    projectOperations
        .project(allUsersName)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(DEVS))
        .add(allow(READ).ref("refs/groups/*").group(DEVS))
        .add(allow(READ).ref("refs/users/default").group(DEVS))
        .update();

    assertAllRefsAreNotVisible(user(allUsersName, DEVS));
  }

  @Test
  public void userRefIsVisibleForInternalUser() throws Exception {
    internalUser(localKey).controlForRef("refs/users/default").asForRef().check(RefPermission.READ);
  }

  @Test
  public void branchDelegation1() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(ADMIN))
        .add(allow(OWNER).ref("refs/heads/x/*").group(DEVS))
        .update();

    ProjectControl uDev = user(localKey, DEVS);
    assertNotOwner(uDev);

    assertOwner("refs/heads/x/*", uDev);
    assertOwner("refs/heads/x/y", uDev);
    assertOwner("refs/heads/x/y/*", uDev);

    assertNotOwner("refs/*", uDev);
    assertNotOwner("refs/heads/master", uDev);
  }

  @Test
  public void branchDelegation2() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(ADMIN))
        .add(allow(OWNER).ref("refs/heads/x/*").group(DEVS))
        .add(allow(OWNER).ref("refs/heads/x/y/*").group(fixers))
        .setExclusiveGroup(permissionKey(OWNER).ref("refs/heads/x/y/*"), true)
        .update();

    ProjectControl uDev = user(localKey, DEVS);
    assertNotOwner(uDev);

    assertOwner("refs/heads/x/*", uDev);
    assertOwner("refs/heads/x/y", uDev);
    assertOwner("refs/heads/x/y/*", uDev);
    assertNotOwner("refs/*", uDev);
    assertNotOwner("refs/heads/master", uDev);

    ProjectControl uFix = user(localKey, fixers);
    assertNotOwner(uFix);

    assertOwner("refs/heads/x/y/*", uFix);
    assertOwner("refs/heads/x/y/bar", uFix);
    assertNotOwner("refs/heads/x/*", uFix);
    assertNotOwner("refs/heads/x/y", uFix);
    assertNotOwner("refs/*", uFix);
    assertNotOwner("refs/heads/master", uFix);
  }

  @Test
  public void inheritRead_SingleBranchDeniesUpload() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .add(allow(PUSH).ref("refs/for/refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/heads/foobar").group(REGISTERED_USERS))
        .setExclusiveGroup(permissionKey(READ).ref("refs/heads/foobar"), true)
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/for/refs/heads/foobar"), true)
        .update();

    ProjectControl u = user(localKey);
    assertCanUpload(u);
    assertCreateChange("refs/heads/master", u);
    assertCannotCreateChange("refs/heads/foobar", u);
  }

  @Test
  public void inheritRead_SingleBranchDoesNotOverrideInherited() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .add(allow(PUSH).ref("refs/for/refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/heads/foobar").group(REGISTERED_USERS))
        .update();

    ProjectControl u = user(localKey);
    assertCanUpload(u);
    assertCreateChange("refs/heads/master", u);
    assertCreateChange("refs/heads/foobar", u);
  }

  @Test
  public void inheritDuplicateSections() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(ADMIN))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(DEVS))
        .update();
    assertCanAccess(user(localKey, "a", ADMIN));
    assertCanAccess(user(localKey, "d", DEVS));
  }

  @Test
  public void inheritRead_OverrideWithDeny() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(deny(READ).ref("refs/*").group(REGISTERED_USERS))
        .update();

    assertAccessDenied(user(localKey));
  }

  @Test
  public void inheritRead_AppendWithDenyOfRef() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(deny(READ).ref("refs/heads/*").group(REGISTERED_USERS))
        .update();

    ProjectControl u = user(localKey);
    assertCanAccess(u);
    assertCanRead("refs/master", u);
    assertCanRead("refs/tags/foobar", u);
    assertCanRead("refs/heads/master", u);
  }

  @Test
  public void inheritRead_OverridesAndDeniesOfRef() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(deny(READ).ref("refs/*").group(REGISTERED_USERS))
        .add(allow(READ).ref("refs/heads/*").group(REGISTERED_USERS))
        .update();

    ProjectControl u = user(localKey);
    assertCanAccess(u);
    assertCannotRead("refs/foobar", u);
    assertCannotRead("refs/tags/foobar", u);
    assertCanRead("refs/heads/foobar", u);
  }

  @Test
  public void inheritSubmit_OverridesAndDeniesOfRef() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(SUBMIT).ref("refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(deny(SUBMIT).ref("refs/*").group(REGISTERED_USERS))
        .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
        .update();

    ProjectControl u = user(localKey);
    assertCannotSubmit("refs/foobar", u);
    assertCannotSubmit("refs/tags/foobar", u);
    assertCanSubmit("refs/heads/foobar", u);
  }

  @Test
  public void cannotUploadToAnyRef() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/heads/*").group(DEVS))
        .add(allow(PUSH).ref("refs/for/refs/heads/*").group(DEVS))
        .update();

    ProjectControl u = user(localKey);
    assertCannotUpload(u);
    assertCannotCreateChange("refs/heads/master", u);
  }

  @Test
  public void usernamePatternCanUploadToAnyRef() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/users/${username}/*").group(REGISTERED_USERS))
        .update();
    ProjectControl u = user(localKey, "a-registered-user");
    assertCanUpload(u);
  }

  @Test
  public void usernamePatternRegExpCanUploadToAnyRef() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            allow(PUSH)
                .ref("^refs/heads/users/${username}/(public|private)/.+")
                .group(REGISTERED_USERS))
        .update();
    ProjectControl u = user(localKey, "a-registered-user");
    assertCanUpload(u);
    assertCanUpdate("refs/heads/users/a-registered-user/private/a", u);
  }

  @Test
  public void usernamePatternNonRegex() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/sb/${username}/heads/*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, "u", DEVS);
    ProjectControl d = user(localKey, "d", DEVS);
    assertCannotRead("refs/sb/d/heads/foobar", u);
    assertCanRead("refs/sb/d/heads/foobar", d);
  }

  @Test
  public void usernamePatternWithRegex() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("^refs/sb/${username}/heads/.*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, "d.v", DEVS);
    ProjectControl d = user(localKey, "dev", DEVS);
    assertCanAccess(u);
    assertCanAccess(d);
    assertCannotRead("refs/sb/dev/heads/foobar", u);
    assertCanRead("refs/sb/dev/heads/foobar", d);
  }

  @Test
  public void usernameEmailPatternWithRegex() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("^refs/sb/${username}/heads/.*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, "d.v@ger-rit.org", DEVS);
    ProjectControl d = user(localKey, "dev@ger-rit.org", DEVS);
    assertCannotRead("refs/sb/dev@ger-rit.org/heads/foobar", u);
    assertCanRead("refs/sb/dev@ger-rit.org/heads/foobar", d);
  }

  @Test
  public void sortWithRegex() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("^refs/heads/.*").group(DEVS))
        .update();
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(READ).ref("^refs/heads/.*-QA-.*").group(ANONYMOUS_USERS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    ProjectControl d = user(localKey, DEVS);
    assertCanRead("refs/heads/foo-QA-bar", u);
    assertCanRead("refs/heads/foo-QA-bar", d);
  }

  @Test
  public void blockRule_ParentBlocksChild() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/tags/*").group(DEVS))
        .update();
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
        .update();
    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/tags/V10", u);
  }

  @Test
  public void blockRule_ParentBlocksChildEvenIfAlreadyBlockedInChild() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/tags/*").group(DEVS))
        .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/tags/V10", u);
  }

  @Test
  public void blockPartialRangeLocally() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/master").group(DEVS).range(+1, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);

    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(2, range);
  }

  @Test
  public void blockLabelRange_ParentBlocksChild() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);

    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-1, range);
    assertCanVote(1, range);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void blockLabelRange_ParentBlocksChildEvenIfAlreadyBlockedInChild() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .add(blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);

    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-1, range);
    assertCanVote(1, range);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void inheritSubmit_AllowInChildDoesntAffectUnblockInParent() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(SUBMIT).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
        .update();

    ProjectControl u = user(localKey);
    assertWithMessage("submit is allowed")
        .that(u.controlForRef("refs/heads/master").canPerform(SUBMIT))
        .isTrue();
  }

  @Test
  public void unblockNoForce() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCanUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockForce() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS).force(true))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCanForceUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockRead_NotPossible() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(READ).ref("refs/*").group(ANONYMOUS_USERS))
        .add(allow(READ).ref("refs/*").group(ADMIN))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(READ).ref("refs/*").group(ANONYMOUS_USERS))
        .add(allow(READ).ref("refs/*").group(ADMIN))
        .update();

    ProjectControl u = user(localKey);
    assertCannotRead("refs/heads/master", u);
  }

  @Test
  public void unblockForceWithAllowNoForce_NotPossible() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotForceUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockMoreSpecificRef_Fails() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockMoreSpecificRefInLocal_Fails() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockMoreSpecificRefWithExclusiveFlag() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCanUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockVoteMoreSpecificRefWithExclusiveFlag() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/master").group(DEVS).range(-2, 2))
        .setExclusiveGroup(labelPermissionKey(LabelId.CODE_REVIEW).ref("refs/heads/master"), true)
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-2, range);
  }

  @Test
  public void unblockFromParentDoesNotAffectChild() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/master").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockFromParentDoesNotAffectChildDifferentGroups() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/master").group(ANONYMOUS_USERS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockMoreSpecificRefInLocalWithExclusiveFlag_Fails() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void blockMoreSpecificRefWithinProject() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/secret").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
        .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/*"), true)
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/secret", u);
    assertCanUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockOtherPermissionWithMoreSpecificRefAndExclusiveFlag_Fails() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
        .add(allow(SUBMIT).ref("refs/heads/master").group(DEVS))
        .setExclusiveGroup(permissionKey(SUBMIT).ref("refs/heads/master"), true)
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockLargerScope_Fails() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/master").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", u);
  }

  @Test
  public void unblockInLocal_Fails() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(PUSH).ref("refs/heads/*").group(fixers))
        .update();

    ProjectControl f = user(localKey, fixers);
    assertCannotUpdate("refs/heads/master", f);
  }

  @Test
  public void unblockInParentBlockInLocal() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(PUSH).ref("refs/heads/*").group(DEVS))
        .update();

    ProjectControl d = user(localKey, DEVS);
    assertCannotUpdate("refs/heads/master", d);
  }

  @Test
  public void unblockForceEditTopicName() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(block(EDIT_TOPIC_NAME).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .add(allow(EDIT_TOPIC_NAME).ref("refs/heads/*").group(DEVS).force(true))
        .update();

    ProjectControl u = user(localKey, DEVS);
    assertWithMessage("u can edit topic name")
        .that(u.controlForRef("refs/heads/master").canForceEditTopicName())
        .isTrue();
  }

  @Test
  public void unblockInLocalForceEditTopicName_Fails() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(EDIT_TOPIC_NAME).ref("refs/heads/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(EDIT_TOPIC_NAME).ref("refs/heads/*").group(DEVS).force(true))
        .update();

    ProjectControl u = user(localKey, REGISTERED_USERS);
    assertWithMessage("u can't edit topic name")
        .that(u.controlForRef("refs/heads/master").canForceEditTopicName())
        .isFalse();
  }

  @Test
  public void unblockRange() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(ANONYMOUS_USERS)
                .range(-1, +1))
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-2, range);
    assertCanVote(2, range);
  }

  @Test
  public void unblockRangeOnMoreSpecificRef_Fails() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(ANONYMOUS_USERS)
                .range(-1, +1))
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/master").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void unblockRangeOnLargerScope_Fails() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/master")
                .group(ANONYMOUS_USERS)
                .range(-1, +1))
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void nonconfiguredCannotVote() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, REGISTERED_USERS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-1, range);
    assertCannotVote(1, range);
  }

  @Test
  public void unblockInLocalRange_Fails() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void unblockRangeForChangeOwner() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW, true);
    assertCanVote(-2, range);
    assertCanVote(2, range);
  }

  @Test
  public void unblockRangeForNotChangeOwner() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void blockChangeOwnerVote() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(blockLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCannotVote(-2, range);
    assertCannotVote(2, range);
  }

  @Test
  public void unionOfPermissibleVotes() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-1, +1))
        .add(
            allowLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(REGISTERED_USERS)
                .range(-2, +2))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-2, range);
    assertCanVote(2, range);
  }

  @Test
  public void unionOfPermissibleVotesPermissionOrder() throws Exception {
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            allowLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(REGISTERED_USERS)
                .range(-2, +2))
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-1, +1))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-2, range);
    assertCanVote(2, range);
  }

  @Test
  public void unionOfBlockedVotes() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(allowLabel(LabelId.CODE_REVIEW).ref("refs/heads/*").group(DEVS).range(-1, +1))
        .add(
            blockLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(REGISTERED_USERS)
                .range(-2, +2))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(
            blockLabel(LabelId.CODE_REVIEW)
                .ref("refs/heads/*")
                .group(REGISTERED_USERS)
                .range(-2, +1))
        .update();

    ProjectControl u = user(localKey, DEVS);
    PermissionRange range =
        u.controlForRef("refs/heads/master").getRange(LABEL + LabelId.CODE_REVIEW);
    assertCanVote(-1, range);
    assertCannotVote(1, range);
  }

  @Test
  public void blockOwner() throws Exception {
    projectOperations
        .project(parentKey)
        .forUpdate()
        .add(block(OWNER).ref("refs/*").group(ANONYMOUS_USERS))
        .update();
    projectOperations
        .project(localKey)
        .forUpdate()
        .add(allow(OWNER).ref("refs/*").group(DEVS))
        .update();

    assertThat(user(localKey, DEVS).isOwner()).isFalse();
  }

  @Test
  public void validateRefPatternsOK() throws Exception {
    RefPattern.validate("refs/*");
    RefPattern.validate("^refs/heads/*");
    RefPattern.validate("^refs/tags/[0-9a-zA-Z-_.]+");
    RefPattern.validate("refs/heads/review/${username}/*");
    RefPattern.validate("^refs/heads/review/${username}/.+");
  }

  @Test
  public void testValidateBadRefPatternDoubleCaret() throws Exception {
    assertThrows(InvalidNameException.class, () -> RefPattern.validate("^^refs/*"));
  }

  @Test
  public void testValidateBadRefPatternDanglingCharacter() throws Exception {
    assertThrows(
        InvalidNameException.class,
        () -> RefPattern.validate("^refs/heads/tmp/sdk/[0-9]{3,3}_R[1-9][A-Z][0-9]{3,3}*"));
  }

  @Test
  public void validateRefPatternNoDanglingCharacter() throws Exception {
    RefPattern.validate("^refs/heads/tmp/sdk/[0-9]{3,3}_R[1-9][A-Z][0-9]{3,3}");
  }

  private ProjectState getProjectState(Project.NameKey nameKey) throws Exception {
    return projectCache.get(nameKey).orElseThrow(illegalState(nameKey));
  }

  private ProjectControl internalUser(Project.NameKey localKey) throws Exception {
    return projectControlFactory.create(new InternalUser(), getProjectState(localKey));
  }

  private ProjectControl user(Project.NameKey localKey, AccountGroup.UUID... memberOf)
      throws Exception {
    return user(localKey, null, memberOf);
  }

  private ProjectControl user(
      Project.NameKey localKey, @Nullable String name, AccountGroup.UUID... memberOf)
      throws Exception {
    return projectControlFactory.create(new MockUser(name, memberOf), getProjectState(localKey));
  }

  private static class MockUser extends CurrentUser {
    @Nullable private final String username;
    private final GroupMembership groups;

    MockUser(@Nullable String name, AccountGroup.UUID[] groupId) {
      username = name;
      ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId);
      groupIds.add(REGISTERED_USERS);
      groupIds.add(ANONYMOUS_USERS);
      groups = new ListGroupMembership(groupIds);
    }

    @Override
    public GroupMembership getEffectiveGroups() {
      return groups;
    }

    @Override
    public Object getCacheKey() {
      return new Object();
    }

    @Override
    public Optional<String> getUserName() {
      return Optional.ofNullable(username);
    }
  }
}
