// Copyright (C) 2017 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.acceptance.api.project;

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.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.AccessSection;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.config.AccessCheckInfo;
import com.google.gerrit.extensions.api.config.AccessCheckInput;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

public class CheckAccessIT extends AbstractDaemonTest {
  @Inject private ProjectOperations projectOperations;
  @Inject private GroupOperations groupOperations;
  @Inject private AllProjectsName allProjectsName;

  private Project.NameKey normalProject;
  private Project.NameKey secretProject;
  private Project.NameKey secretRefProject;
  private TestAccount privilegedUser;

  @Before
  public void setUp() throws Exception {
    normalProject = projectOperations.newProject().create();
    secretProject = projectOperations.newProject().create();
    secretRefProject = projectOperations.newProject().create();
    AccountGroup.UUID privilegedGroupUuid =
        groupOperations.newGroup().name(name("privilegedGroup")).create();

    privilegedUser = accountCreator.create("privilegedUser", "snowden@nsa.gov", "Ed Snowden", null);
    groupOperations.group(privilegedGroupUuid).forUpdate().addMember(privilegedUser.id()).update();

    projectOperations
        .project(secretProject)
        .forUpdate()
        .add(allow(Permission.READ).ref("refs/*").group(privilegedGroupUuid))
        .add(block(Permission.READ).ref("refs/*").group(SystemGroupBackend.REGISTERED_USERS))
        .update();

    projectOperations
        .project(secretRefProject)
        .forUpdate()
        .add(deny(Permission.READ).ref("refs/*").group(SystemGroupBackend.ANONYMOUS_USERS))
        .add(allow(Permission.READ).ref("refs/heads/secret/*").group(privilegedGroupUuid))
        .add(
            block(Permission.READ)
                .ref("refs/heads/secret/*")
                .group(SystemGroupBackend.REGISTERED_USERS))
        .add(allow(Permission.READ).ref("refs/heads/*").group(SystemGroupBackend.REGISTERED_USERS))
        .update();

    // Ref permission
    projectOperations
        .project(normalProject)
        .forUpdate()
        .add(allow(Permission.VIEW_PRIVATE_CHANGES).ref("refs/*").group(privilegedGroupUuid))
        .add(allow(Permission.FORGE_SERVER).ref("refs/*").group(privilegedGroupUuid))
        .update();
  }

  @Test
  public void emptyInput() throws Exception {
    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.projects().name(normalProject.get()).checkAccess(new AccessCheckInput()));
    assertThat(thrown).hasMessageThat().contains("input requires 'account'");
  }

  @Test
  public void nonexistentPermission() throws Exception {
    AccessCheckInput in = new AccessCheckInput();
    in.account = user.email();
    in.permission = "notapermission";
    in.ref = "refs/heads/master";

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.projects().name(normalProject.get()).checkAccess(in));
    assertThat(thrown).hasMessageThat().contains("not recognized");
  }

  @Test
  public void permissionLacksRef() throws Exception {
    AccessCheckInput in = new AccessCheckInput();
    in.account = user.email();
    in.permission = "forge_author";

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.projects().name(normalProject.get()).checkAccess(in));
    assertThat(thrown).hasMessageThat().contains("must set 'ref'");
  }

  @Test
  public void changePermission() throws Exception {
    AccessCheckInput in = new AccessCheckInput();
    in.account = user.email();
    in.permission = "rebase";
    in.ref = "refs/heads/master";

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.projects().name(normalProject.get()).checkAccess(in));
    assertThat(thrown).hasMessageThat().contains("recognized as ref permission");
  }

  @Test
  public void nonexistentEmail() throws Exception {
    AccessCheckInput in = new AccessCheckInput();
    in.account = "doesnotexist@invalid.com";
    in.permission = "rebase";
    in.ref = "refs/heads/master";

    UnprocessableEntityException thrown =
        assertThrows(
            UnprocessableEntityException.class,
            () -> gApi.projects().name(normalProject.get()).checkAccess(in));
    assertThat(thrown).hasMessageThat().contains("Account 'doesnotexist@invalid.com' not found");
  }

  private static class TestCase {
    AccessCheckInput input;
    String project;
    String permission;
    int want;
    List<String> expectedDebugLogs;

    static TestCase project(String mail, String project, int want, List<String> expectedDebugLogs) {
      TestCase t = new TestCase();
      t.input = new AccessCheckInput();
      t.input.account = mail;
      t.project = project;
      t.want = want;
      t.expectedDebugLogs = expectedDebugLogs;
      return t;
    }

    static TestCase projectRef(
        String mail, String project, String ref, int want, List<String> expectedDebugLogs) {
      TestCase t = new TestCase();
      t.input = new AccessCheckInput();
      t.input.account = mail;
      t.input.ref = ref;
      t.project = project;
      t.want = want;
      t.expectedDebugLogs = expectedDebugLogs;
      return t;
    }

    static TestCase projectRefPerm(
        String mail,
        String project,
        String ref,
        String permission,
        int want,
        List<String> expectedDebugLogs) {
      TestCase t = new TestCase();
      t.input = new AccessCheckInput();
      t.input.account = mail;
      t.input.ref = ref;
      t.input.permission = permission;
      t.project = project;
      t.want = want;
      t.expectedDebugLogs = expectedDebugLogs;
      return t;
    }
  }

  @Test
  public void httpGet() throws Exception {
    RestResponse rep =
        adminRestSession.get(
            "/projects/"
                + normalProject.get()
                + "/check.access"
                + "?ref=refs/heads/master&perm=viewPrivateChanges&account="
                + user.email());
    rep.assertOK();
    assertThat(rep.getEntityContent()).contains("403");
  }

  @Test
  public void accessible() throws Exception {
    List<TestCase> inputs =
        ImmutableList.of(
            // Test 1
            TestCase.projectRefPerm(
                user.email(),
                normalProject.get(),
                "refs/heads/master",
                Permission.VIEW_PRIVATE_CHANGES,
                403,
                ImmutableList.of(
                    "'user1' can perform 'read' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/*'",
                    "'user1' cannot perform 'viewPrivateChanges' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/master'")),
            // Test 2
            TestCase.project(
                user.email(),
                normalProject.get(),
                200,
                ImmutableList.of(
                    "'user1' can perform 'read' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/*'")),
            // Test 3
            TestCase.project(
                user.email(),
                secretProject.get(),
                403,
                ImmutableList.of(
                    "'user1' cannot perform 'read' with force=false on project '"
                        + secretProject.get()
                        + "' for ref 'refs/heads/*' because this permission is blocked",
                    "'user1' cannot perform 'read' with force=false on project '"
                        + secretProject.get()
                        + "' for ref 'refs/meta/version' because this permission is blocked")),
            // Test 4
            TestCase.projectRef(
                user.email(),
                secretRefProject.get(),
                "refs/heads/secret/master",
                403,
                ImmutableList.of(
                    "'user1' can perform 'read' with force=false on project '"
                        + secretRefProject.get()
                        + "' for ref 'refs/heads/*'",
                    "'user1' cannot perform 'read' with force=false on project '"
                        + secretRefProject.get()
                        + "' for ref 'refs/heads/secret/master' because this permission is blocked")),
            // Test 5
            TestCase.projectRef(
                privilegedUser.email(),
                secretRefProject.get(),
                "refs/heads/secret/master",
                200,
                ImmutableList.of(
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + secretRefProject.get()
                        + "' for ref 'refs/heads/*'",
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + secretRefProject.get()
                        + "' for ref 'refs/heads/secret/master'")),
            // Test 6
            TestCase.projectRef(
                privilegedUser.email(),
                normalProject.get(),
                null,
                200,
                ImmutableList.of(
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/*'")),
            // Test 7
            TestCase.projectRef(
                privilegedUser.email(),
                secretProject.get(),
                null,
                200,
                ImmutableList.of(
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + secretProject.get()
                        + "' for ref 'refs/*'")),
            // Test 8
            TestCase.projectRefPerm(
                privilegedUser.email(),
                normalProject.get(),
                "refs/heads/master",
                Permission.VIEW_PRIVATE_CHANGES,
                200,
                ImmutableList.of(
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/*'",
                    "'privilegedUser' can perform 'viewPrivateChanges' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/master'")),
            // Test 9
            TestCase.projectRefPerm(
                privilegedUser.email(),
                normalProject.get(),
                "refs/heads/master",
                Permission.FORGE_SERVER,
                200,
                ImmutableList.of(
                    "'privilegedUser' can perform 'read' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/*'",
                    "'privilegedUser' can perform 'forgeServerAsCommitter' with force=false on project '"
                        + normalProject.get()
                        + "' for ref 'refs/heads/master'")));

    for (TestCase tc : inputs) {
      String in = newGson().toJson(tc.input);
      AccessCheckInfo info = null;

      try {
        info = gApi.projects().name(tc.project).checkAccess(tc.input);
      } catch (RestApiException e) {
        assertWithMessage(String.format("check.access(%s, %s): exception %s", tc.project, in, e))
            .fail();
      }

      int want = tc.want;
      if (want != info.status) {
        assertWithMessage(
                String.format(
                    "check.access(%s, %s) = %d, want %d", tc.project, in, info.status, want))
            .fail();
      }

      switch (want) {
        case 403:
          if (tc.permission != null) {
            assertThat(info.message).contains("lacks permission " + tc.permission);
          }
          break;
        case 404:
          assertThat(info.message).contains("does not exist");
          break;
        case 200:
          assertThat(info.message).isNull();
          break;
        default:
          assertWithMessage(String.format("unknown code %d", want)).fail();
      }

      if (!info.debugLogs.equals(tc.expectedDebugLogs)) {
        assertWithMessage(
                String.format(
                    "check.access(%s, %s) = %s, want %s",
                    tc.project, in, info.debugLogs, tc.expectedDebugLogs))
            .fail();
      }
    }
  }

  @Test
  public void noBranches() throws Exception {
    try (Repository repo = repoManager.openRepository(normalProject)) {
      RefUpdate u = repo.updateRef(RefNames.REFS_HEADS + "master");
      u.setForceUpdate(true);
      assertThat(u.delete()).isEqualTo(Result.FORCED);
    }
    AccessCheckInput input = new AccessCheckInput();
    input.account = privilegedUser.email();

    AccessCheckInfo info = gApi.projects().name(normalProject.get()).checkAccess(input);
    assertThat(info.status).isEqualTo(200);
    assertThat(info.message).contains("no branches");
  }

  @Test
  @Sandboxed
  public void noRules() throws Exception {
    normalProject = projectOperations.newProject().create();

    for (AccessSection section :
        projectOperations.project(allProjectsName).getProjectConfig().getAccessSections()) {
      if (!section.getName().startsWith(Constants.R_REFS)) {
        continue;
      }
      for (Permission permission : section.getPermissions()) {
        projectOperations
            .project(allProjectsName)
            .forUpdate()
            .remove(permissionKey(permission.getName()).ref(section.getName()).build())
            .update();
      }
    }
    AccessCheckInput input = new AccessCheckInput();
    input.account = privilegedUser.email();
    input.permission = Permission.READ;
    input.ref = "refs/heads/main";

    AccessCheckInfo info = gApi.projects().name(normalProject.get()).checkAccess(input);
    assertThat(info.status).isEqualTo(403);

    assertThat(info.debugLogs).isNotEmpty();
    assertThat(info.debugLogs.get(0)).contains("Found no rules");
  }
}
