// Copyright (C) 2016 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.rest.account;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
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.capabilityKey;
import static com.google.gerrit.entities.RefNames.changeMetaRef;
import static com.google.gerrit.entities.RefNames.patchSetRef;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.LabelId;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RobotComment;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling;
import com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.approval.ApprovalsUtil;
import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import java.io.File;
import java.io.IOException;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ImpersonationIT extends AbstractDaemonTest {
  @Inject private AccountControl.Factory accountControlFactory;
  @Inject private ApprovalsUtil approvalsUtil;
  @Inject private ChangeMessagesUtil cmUtil;
  @Inject private CommentsUtil commentsUtil;
  @Inject private ProjectOperations projectOperations;
  @Inject private RequestScopeOperations requestScopeOperations;

  private RestSession anonRestSession;
  private TestAccount admin2;
  private GroupInfo newGroup;

  @Before
  public void setUp() throws Exception {
    anonRestSession = new RestSession(server, null);
    admin2 = accountCreator.admin2();
    GroupInput gi = new GroupInput();
    gi.name = name("New-Group");
    gi.members = ImmutableList.of(user.id().toString());
    newGroup = gApi.groups().create(gi).get();
  }

  @After
  public void tearDown() throws Exception {
    removeRunAs();
  }

  @Test
  @UseLocalDisk
  public void voteOnBehalfOf() throws Exception {
    allowCodeReviewOnBehalfOf();
    TestAccount realUser = admin;
    TestAccount impersonatedUser = user;
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    try (Repository repo = repoManager.openRepository(project)) {
      String changeMetaRef = changeMetaRef(r.getChange().getId());
      createRefLogFileIfMissing(repo, changeMetaRef);

      ReviewInput in = ReviewInput.recommend();
      in.onBehalfOf = impersonatedUser.id().toString();
      in.message = "Message on behalf of";
      revision.review(in);

      PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
      assertThat(psa.patchSetId().get()).isEqualTo(1);
      assertThat(psa.label()).isEqualTo("Code-Review");
      assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
      assertThat(psa.value()).isEqualTo(1);
      assertThat(psa.realAccountId()).isEqualTo(realUser.id());

      ChangeData cd = r.getChange();
      ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
      assertThat(m.getMessage()).endsWith(in.message);
      assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
      assertThat(m.getRealAuthor()).isEqualTo(realUser.id());

      // The change meta commit is created by the server and has the impersonated user as the
      // author.
      // Person idents of users in NoteDb commits are obfuscated due to privacy reasons.
      RevCommit changeMetaCommit = projectOperations.project(project).getHead(changeMetaRef);
      assertThat(changeMetaCommit.getCommitterIdent().getEmailAddress())
          .isEqualTo(serverIdent.get().getEmailAddress());
      assertThat(changeMetaCommit.getAuthorIdent().getEmailAddress())
          .isEqualTo(changeNoteUtil.getAccountIdAsEmailAddress(impersonatedUser.id()));

      // The ref log for the change meta ref records the impersonated user.
      ReflogEntry changeMetaRefLogEntry = repo.getReflogReader(changeMetaRef).getLastEntry();
      assertThat(changeMetaRefLogEntry.getWho().getEmailAddress())
          .isEqualTo(impersonatedUser.email());
    }
  }

  @Test
  public void overrideImpersonatedVoteWithOtherImpersonatedVote_sameValue() throws Exception {
    allowCodeReviewOnBehalfOf();
    TestAccount realUser = admin;
    TestAccount realUser2 = admin2;
    TestAccount impersonatedUser = user;
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    // realUser votes Code-Review+1 on behalf of impersonatedUser
    ReviewInput in = ReviewInput.recommend();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Message on behalf of";
    revision.review(in);

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(realUser.id());

    ChangeData cd = r.getChange();
    ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser.id());

    // realUser2 votes Code-Review+1 on behalf of impersonatedUser, this should override the
    // impersonated Code-Review+1 of realUser with an impersonated Code-Review+1 of realUser2
    requestScopeOperations.setApiUser(realUser2.id());
    in = ReviewInput.recommend();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Another message on behalf of";
    gApi.changes().id(r.getChangeId()).current().review(in);

    psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(realUser2.id());

    cd = r.getChange();
    m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser2.id());
  }

  @Test
  public void overrideImpersonatedVoteWithOtherImpersonatedVote_differentValue() throws Exception {
    allowCodeReviewOnBehalfOf();
    TestAccount realUser = admin;
    TestAccount realUser2 = admin2;
    TestAccount impersonatedUser = user;
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    // realUser votes Code-Review+1 on behalf of impersonatedUser
    ReviewInput in = ReviewInput.recommend();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Message on behalf of";
    revision.review(in);

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(realUser.id());

    ChangeData cd = r.getChange();
    ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser.id());

    // realUser2 votes Code-Review-1 on behalf of impersonatedUser, this should override the
    // impersonated Code-Review+1 of realUser with an impersonated Code-Review-1 of realUser2
    requestScopeOperations.setApiUser(realUser2.id());
    in = ReviewInput.dislike();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Another message on behalf of";
    gApi.changes().id(r.getChangeId()).current().review(in);

    psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(-1);
    assertThat(psa.realAccountId()).isEqualTo(realUser2.id());

    cd = r.getChange();
    m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser2.id());
  }

  @Test
  public void overrideImpersonatedVoteWithNonImpersonatedVote_sameValue() throws Exception {
    allowCodeReviewOnBehalfOf();
    TestAccount realUser = admin;
    TestAccount impersonatedUser = user;
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    // realUser votes Code-Review+1 on behalf of impersonatedUser
    ReviewInput in = ReviewInput.recommend();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Message on behalf of";
    revision.review(in);

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(realUser.id());

    ChangeData cd = r.getChange();
    ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser.id());

    // impersonatedUser votes Code-Review+1 themselves, this should override the impersonated
    // Code-Review+1 with a non-impersonated Code-Review+1
    requestScopeOperations.setApiUser(impersonatedUser.id());
    in = ReviewInput.recommend();
    in.message = "Message";
    gApi.changes().id(r.getChangeId()).current().review(in);

    psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(impersonatedUser.id());

    cd = r.getChange();
    m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(impersonatedUser.id());
  }

  @Test
  public void overrideImpersonatedVoteWithNonImpersonatedVote_differentValue() throws Exception {
    allowCodeReviewOnBehalfOf();
    TestAccount realUser = admin;
    TestAccount impersonatedUser = user;
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    // realUser votes Code-Review+1 on behalf of impersonatedUser
    ReviewInput in = ReviewInput.recommend();
    in.onBehalfOf = impersonatedUser.id().toString();
    in.message = "Message on behalf of";
    revision.review(in);

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(realUser.id());

    ChangeData cd = r.getChange();
    ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(realUser.id());

    // impersonatedUser votes Code-Review-1 themselves, this should override the impersonated
    // Code-Review+1 with a non-impersonated Code-Review-1
    requestScopeOperations.setApiUser(impersonatedUser.id());
    in = ReviewInput.dislike();
    in.message = "Message";
    gApi.changes().id(r.getChangeId()).current().review(in);

    psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(impersonatedUser.id());
    assertThat(psa.value()).isEqualTo(-1);
    assertThat(psa.realAccountId()).isEqualTo(impersonatedUser.id());

    cd = r.getChange();
    m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(impersonatedUser.id());
    assertThat(m.getRealAuthor()).isEqualTo(impersonatedUser.id());
  }

  @Test
  public void voteOnBehalfOfRequiresLabel() throws Exception {
    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.message = "Message on behalf of";

    AuthException thrown = assertThrows(AuthException.class, () -> revision.review(in));
    assertThat(thrown)
        .hasMessageThat()
        .contains("label required to post review on behalf of \"" + in.onBehalfOf + '"');
  }

  @Test
  @GerritConfig(name = "change.strictLabels", value = "true")
  public void voteOnBehalfOfInvalidLabel() throws Exception {
    allowCodeReviewOnBehalfOf();

    String changeId = createChange().getChangeId();
    ReviewInput in = new ReviewInput().label("Not-A-Label", 5);
    in.onBehalfOf = user.id().toString();

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class, () -> gApi.changes().id(changeId).current().review(in));
    assertThat(thrown).hasMessageThat().contains("label \"Not-A-Label\" is not a configured label");
  }

  @Test
  public void voteOnBehalfOfInvalidLabelIgnoredWithoutStrictLabels() throws Exception {
    allowCodeReviewOnBehalfOf();

    String changeId = createChange().getChangeId();
    ReviewInput in = new ReviewInput().label("Code-Review", 1).label("Not-A-Label", 5);
    in.onBehalfOf = user.id().toString();
    gApi.changes().id(changeId).current().review(in);

    assertThat(gApi.changes().id(changeId).get().labels).doesNotContainKey("Not-A-Label");
  }

  @Test
  public void voteOnBehalfOfLabelNotPermitted() throws Exception {
    try (ProjectConfigUpdate u = updateProject(project)) {
      LabelType verified = TestLabels.verified();
      u.getConfig().upsertLabelType(verified);
      u.save();
    }

    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label(LabelId.VERIFIED, 1);

    AuthException thrown = assertThrows(AuthException.class, () -> revision.review(in));
    assertThat(thrown)
        .hasMessageThat()
        .contains(
            "not permitted to modify label \"Verified\" on behalf of \"" + in.onBehalfOf + '"');
  }

  @Test
  public void voteOnBehalfOfWithComment() throws Exception {
    testVoteOnBehalfOfWithComment();
  }

  @Test
  public void voteOnBehalfOfWithCommentWritingJson() throws Exception {
    testVoteOnBehalfOfWithComment();
  }

  private void testVoteOnBehalfOfWithComment() throws Exception {
    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label("Code-Review", 1);
    CommentInput ci = new CommentInput();
    ci.path = Patch.COMMIT_MSG;
    ci.side = Side.REVISION;
    ci.line = 1;
    ci.message = "message";
    in.comments = ImmutableMap.of(ci.path, ImmutableList.of(ci));
    gApi.changes().id(r.getChangeId()).current().review(in);

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(user.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(admin.id());

    ChangeData cd = r.getChange();
    HumanComment c =
        Iterables.getOnlyElement(commentsUtil.publishedHumanCommentsByChange(cd.notes()));
    assertThat(c.message).isEqualTo(ci.message);
    assertThat(c.author.getId()).isEqualTo(user.id());
    assertThat(c.getRealAuthor().getId()).isEqualTo(admin.id());
  }

  @Test
  public void voteOnBehalfOfWithRobotComment() throws Exception {
    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label("Code-Review", 1);
    RobotCommentInput ci = new RobotCommentInput();
    ci.robotId = "my-robot";
    ci.robotRunId = "abcd1234";
    ci.path = Patch.COMMIT_MSG;
    ci.side = Side.REVISION;
    ci.line = 1;
    ci.message = "message";
    in.robotComments = ImmutableMap.of(ci.path, ImmutableList.of(ci));
    gApi.changes().id(r.getChangeId()).current().review(in);

    ChangeData cd = r.getChange();
    RobotComment c = Iterables.getOnlyElement(commentsUtil.robotCommentsByChange(cd.notes()));
    assertThat(c.message).isEqualTo(ci.message);
    assertThat(c.robotId).isEqualTo(ci.robotId);
    assertThat(c.robotRunId).isEqualTo(ci.robotRunId);
    assertThat(c.author.getId()).isEqualTo(user.id());
    assertThat(c.getRealAuthor().getId()).isEqualTo(admin.id());
  }

  @Test
  public void voteOnBehalfOfCannotModifyDrafts() throws Exception {
    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());
    DraftInput di = new DraftInput();
    di.path = Patch.COMMIT_MSG;
    di.side = Side.REVISION;
    di.line = 1;
    di.message = "message";
    gApi.changes().id(r.getChangeId()).current().createDraft(di);

    requestScopeOperations.setApiUser(admin.id());
    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label("Code-Review", 1);
    in.drafts = DraftHandling.PUBLISH;

    AuthException thrown =
        assertThrows(
            AuthException.class, () -> gApi.changes().id(r.getChangeId()).current().review(in));
    assertThat(thrown).hasMessageThat().contains("not allowed to modify other user's drafts");
  }

  @Test
  public void voteOnBehalfOfMissingUser() throws Exception {
    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = "doesnotexist";
    in.label("Code-Review", 1);

    UnprocessableEntityException thrown =
        assertThrows(UnprocessableEntityException.class, () -> revision.review(in));
    assertThat(thrown).hasMessageThat().contains("not found");
    assertThat(thrown).hasMessageThat().contains("doesnotexist");
  }

  @Test
  public void voteOnBehalfOfFailsWhenUserCannotSeeDestinationRef() throws Exception {
    blockRead(newGroup);

    allowCodeReviewOnBehalfOf();
    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label("Code-Review", 1);

    ResourceConflictException thrown =
        assertThrows(ResourceConflictException.class, () -> revision.review(in));
    assertThat(thrown)
        .hasMessageThat()
        .contains("on_behalf_of account " + user.id() + " cannot see change");
  }

  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  @Test
  public void voteOnBehalfOfInvisibleUserNotAllowed() throws Exception {
    allowCodeReviewOnBehalfOf();
    requestScopeOperations.setApiUser(accountCreator.user2().id());
    assertThat(accountControlFactory.get().canSee(user.id())).isFalse();

    PushOneCommit.Result r = createChange();
    RevisionApi revision = gApi.changes().id(r.getChangeId()).current();

    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.label("Code-Review", 1);

    UnprocessableEntityException thrown =
        assertThrows(UnprocessableEntityException.class, () -> revision.review(in));
    assertThat(thrown).hasMessageThat().contains("not found");
    assertThat(thrown).hasMessageThat().contains(in.onBehalfOf);
  }

  @Test
  @UseLocalDisk
  public void submitOnBehalfOf_mergeAlways() throws Exception {
    TestAccount realUser = admin;
    TestAccount impersonatedUser = admin2;

    // Create a project with MERGE_ALWAYS submit strategy so that a merge commit is created on
    // submit and we can verify its committer and author and the ref log for the update of the
    // target branch.
    Project.NameKey project =
        projectOperations.newProject().submitType(SubmitType.MERGE_ALWAYS).create();

    testSubmitOnBehalfOf(project, realUser, impersonatedUser);

    // The merge commit is created by the server and has the impersonated user as the author.
    RevCommit mergeCommit = projectOperations.project(project).getHead("refs/heads/master");
    assertThat(mergeCommit.getCommitterIdent().getEmailAddress())
        .isEqualTo(serverIdent.get().getEmailAddress());
    assertThat(mergeCommit.getAuthorIdent().getEmailAddress()).isEqualTo(impersonatedUser.email());

    // The ref log for the target branch records the impersonated user.
    try (Repository repo = repoManager.openRepository(project)) {
      ReflogEntry targetBranchRefLogEntry =
          repo.getReflogReader("refs/heads/master").getLastEntry();
      assertThat(targetBranchRefLogEntry.getWho().getEmailAddress())
          .isEqualTo(impersonatedUser.email());
    }
  }

  @Test
  @UseLocalDisk
  public void submitOnBehalfOf_rebaseAlways() throws Exception {
    TestAccount realUser = admin;
    TestAccount impersonatedUser = admin2;

    // Create a project with REBASE_ALWAYS submit strategy so that a new patch set is created on
    // submit and we can verify its committer and author and the ref log for the update of the
    // patch set ref and the target branch.
    Project.NameKey project =
        projectOperations.newProject().submitType(SubmitType.REBASE_ALWAYS).create();

    ChangeData cd = testSubmitOnBehalfOf(project, realUser, impersonatedUser);

    // Rebase on submit is expected to create a new patch set.
    assertThat(cd.currentPatchSet().id().get()).isEqualTo(2);

    // The patch set commit is created by the impersonated user and has the real user as the author.
    // Recording the real user as the author seems to a bug, we would expect the author to be the
    // impersonated user.
    RevCommit newPatchSetCommit =
        projectOperations.project(project).getHead(cd.currentPatchSet().refName());
    assertThat(newPatchSetCommit.getCommitterIdent().getEmailAddress())
        .isEqualTo(impersonatedUser.email());
    assertThat(newPatchSetCommit.getAuthorIdent().getEmailAddress()).isEqualTo(realUser.email());

    try (Repository repo = repoManager.openRepository(project)) {
      // The ref log for the patch set ref records the impersonated user.
      ReflogEntry patchSetRefLogEntry =
          repo.getReflogReader(cd.currentPatchSet().refName()).getLastEntry();
      assertThat(patchSetRefLogEntry.getWho().getEmailAddress())
          .isEqualTo(impersonatedUser.email());

      // The ref log for the target branch records the impersonated user.
      ReflogEntry targetBranchRefLogEntry =
          repo.getReflogReader("refs/heads/master").getLastEntry();
      assertThat(targetBranchRefLogEntry.getWho().getEmailAddress())
          .isEqualTo(impersonatedUser.email());
    }
  }

  @CanIgnoreReturnValue
  private ChangeData testSubmitOnBehalfOf(
      Project.NameKey project, TestAccount realUser, TestAccount impersonatedUser)
      throws Exception {
    allowSubmitOnBehalfOf(project);

    TestRepository<InMemoryRepository> testRepo = cloneProject(project, realUser);

    PushOneCommit.Result r = createChange(testRepo);
    String changeId = project.get() + "~master~" + r.getChangeId();
    gApi.changes().id(changeId).current().review(ReviewInput.approve());
    SubmitInput in = new SubmitInput();
    in.onBehalfOf = impersonatedUser.email();

    try (Repository repo = repoManager.openRepository(project)) {
      String changeMetaRef = changeMetaRef(r.getChange().getId());
      createRefLogFileIfMissing(repo, changeMetaRef);
      createRefLogFileIfMissing(repo, "refs/heads/master");
      createRefLogFileIfMissing(repo, patchSetRef(PatchSet.id(r.getChange().getId(), 2)));

      gApi.changes().id(changeId).current().submit(in);

      ChangeData cd = r.getChange();
      assertThat(cd.change().isMerged()).isTrue();
      PatchSetApproval submitter =
          approvalsUtil.getSubmitter(cd.notes(), cd.change().currentPatchSetId());
      assertThat(submitter.accountId()).isEqualTo(impersonatedUser.id());
      assertThat(submitter.realAccountId()).isEqualTo(realUser.id());

      // The change meta commit is created by the server and has the impersonated user as the
      // author.
      // Person idents of users in NoteDb commits are obfuscated due to privacy reasons.
      RevCommit changeMetaCommit = projectOperations.project(project).getHead(changeMetaRef);
      assertThat(changeMetaCommit.getCommitterIdent().getEmailAddress())
          .isEqualTo(serverIdent.get().getEmailAddress());
      assertThat(changeMetaCommit.getAuthorIdent().getEmailAddress())
          .isEqualTo(changeNoteUtil.getAccountIdAsEmailAddress(impersonatedUser.id()));

      // The ref log for the change meta ref records the impersonated user.
      ReflogEntry changeMetaRefLogEntry = repo.getReflogReader(changeMetaRef).getLastEntry();
      assertThat(changeMetaRefLogEntry.getWho().getEmailAddress())
          .isEqualTo(impersonatedUser.email());

      return cd;
    }
  }

  @Test
  public void submitOnBehalfOfInvalidUser() throws Exception {
    allowSubmitOnBehalfOf();
    PushOneCommit.Result r = createChange();
    String changeId = project.get() + "~master~" + r.getChangeId();
    gApi.changes().id(changeId).current().review(ReviewInput.approve());
    SubmitInput in = new SubmitInput();
    in.onBehalfOf = "doesnotexist";
    UnprocessableEntityException thrown =
        assertThrows(
            UnprocessableEntityException.class,
            () -> gApi.changes().id(changeId).current().submit(in));
    assertThat(thrown).hasMessageThat().contains("not found");
    assertThat(thrown).hasMessageThat().contains("doesnotexist");
  }

  @Test
  public void submitOnBehalfOfNotPermitted() throws Exception {
    PushOneCommit.Result r = createChange();
    gApi.changes()
        .id(project.get() + "~master~" + r.getChangeId())
        .current()
        .review(ReviewInput.approve());
    SubmitInput in = new SubmitInput();
    in.onBehalfOf = admin2.email();
    AuthException thrown =
        assertThrows(
            AuthException.class,
            () ->
                gApi.changes()
                    .id(project.get() + "~master~" + r.getChangeId())
                    .current()
                    .submit(in));
    assertThat(thrown).hasMessageThat().contains("submit on behalf of other users not permitted");
  }

  @Test
  public void submitOnBehalfOfFailsWhenUserCannotSeeDestinationRef() throws Exception {
    blockRead(newGroup);

    allowSubmitOnBehalfOf();
    PushOneCommit.Result r = createChange();
    String changeId = project.get() + "~master~" + r.getChangeId();
    gApi.changes().id(changeId).current().review(ReviewInput.approve());
    SubmitInput in = new SubmitInput();
    in.onBehalfOf = user.email();
    UnprocessableEntityException thrown =
        assertThrows(
            UnprocessableEntityException.class,
            () -> gApi.changes().id(changeId).current().submit(in));
    assertThat(thrown)
        .hasMessageThat()
        .contains("on_behalf_of account " + user.id() + " cannot see change");
  }

  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  @Test
  public void submitOnBehalfOfInvisibleUserNotAllowed() throws Exception {
    allowSubmitOnBehalfOf();
    requestScopeOperations.setApiUser(accountCreator.user2().id());
    assertThat(accountControlFactory.get().canSee(user.id())).isFalse();

    PushOneCommit.Result r = createChange();
    String changeId = project.get() + "~master~" + r.getChangeId();
    gApi.changes().id(changeId).current().review(ReviewInput.approve());
    SubmitInput in = new SubmitInput();
    in.onBehalfOf = user.email();
    UnprocessableEntityException thrown =
        assertThrows(
            UnprocessableEntityException.class,
            () -> gApi.changes().id(changeId).current().submit(in));
    assertThat(thrown).hasMessageThat().contains("not found");
    assertThat(thrown).hasMessageThat().contains(in.onBehalfOf);
  }

  @Test
  public void runAsValidUser() throws Exception {
    allowRunAs();
    RestResponse res = adminRestSession.getWithHeaders("/accounts/self", runAsHeader(user.id()));
    res.assertOK();
    AccountInfo account = newGson().fromJson(res.getEntityContent(), AccountInfo.class);
    assertThat(account._accountId).isEqualTo(user.id().get());
  }

  @GerritConfig(name = "auth.enableRunAs", value = "false")
  @Test
  public void runAsDisabledByConfig() throws Exception {
    allowRunAs();
    RestResponse res = adminRestSession.getWithHeaders("/changes/", runAsHeader(user.id()));
    res.assertForbidden();
    assertThat(res.getEntityContent())
        .isEqualTo("X-Gerrit-RunAs disabled by auth.enableRunAs = false");
  }

  @Test
  public void runAsNotPermitted() throws Exception {
    RestResponse res = adminRestSession.getWithHeaders("/changes/", runAsHeader(user.id()));
    res.assertForbidden();
    assertThat(res.getEntityContent()).isEqualTo("not permitted to use X-Gerrit-RunAs");
  }

  @Test
  public void runAsNeverPermittedForAnonymousUsers() throws Exception {
    allowRunAs();
    RestResponse res = anonRestSession.getWithHeaders("/changes/", runAsHeader(user.id()));
    res.assertForbidden();
    assertThat(res.getEntityContent()).isEqualTo("not permitted to use X-Gerrit-RunAs");
  }

  @Test
  public void runAsInvalidUser() throws Exception {
    allowRunAs();
    RestResponse res = adminRestSession.getWithHeaders("/changes/", runAsHeader("doesnotexist"));
    res.assertForbidden();
    assertThat(res.getEntityContent()).isEqualTo("no account matches X-Gerrit-RunAs");
  }

  @Test
  public void voteUsingRunAsAvoidsRestrictionsOfOnBehalfOf() throws Exception {
    allowRunAs();
    PushOneCommit.Result r = createChange();

    requestScopeOperations.setApiUser(user.id());
    DraftInput di = new DraftInput();
    di.path = Patch.COMMIT_MSG;
    di.side = Side.REVISION;
    di.line = 1;
    di.message = "inline comment";
    gApi.changes().id(r.getChangeId()).current().createDraft(di);
    requestScopeOperations.setApiUser(admin.id());

    // Things that aren't allowed with on_behalf_of:
    //  - no labels.
    //  - publish other user's drafts.
    ReviewInput in = new ReviewInput();
    in.message = "message";
    in.drafts = DraftHandling.PUBLISH;
    RestResponse res =
        adminRestSession.postWithHeaders(
            "/changes/" + r.getChangeId() + "/revisions/current/review",
            in,
            runAsHeader(user.id()));
    res.assertOK();

    ChangeMessageInfo m = Iterables.getLast(gApi.changes().id(r.getChangeId()).get().messages);
    assertThat(m.message).endsWith(in.message);
    assertThat(m.author._accountId).isEqualTo(user.id().get());

    CommentInfo c =
        Iterables.getOnlyElement(
            gApi.changes().id(r.getChangeId()).commentsRequest().get().get(di.path));
    assertThat(c.author._accountId).isEqualTo(user.id().get());
    assertThat(c.message).isEqualTo(di.message);

    requestScopeOperations.setApiUser(user.id());
    assertThat(gApi.changes().id(r.getChangeId()).drafts()).isEmpty();
  }

  @Test
  public void runAsWithOnBehalfOf() throws Exception {
    // - Has the same restrictions as on_behalf_of (e.g. requires labels).
    // - Takes the effective user from on_behalf_of (user).
    // - Takes the real user from the real caller, not the intermediate
    //   X-Gerrit-RunAs user (user2).
    allowRunAs();
    allowCodeReviewOnBehalfOf();
    TestAccount user2 = accountCreator.user2();

    PushOneCommit.Result r = createChange();
    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.message = "Message on behalf of";

    String endpoint = "/changes/" + r.getChangeId() + "/revisions/current/review";
    RestResponse res = adminRestSession.postWithHeaders(endpoint, in, runAsHeader(user2.id()));
    res.assertForbidden();
    assertThat(res.getEntityContent())
        .isEqualTo("label required to post review on behalf of \"" + in.onBehalfOf + '"');

    in.label("Code-Review", 1);
    adminRestSession.postWithHeaders(endpoint, in, runAsHeader(user2.id())).assertOK();

    PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
    assertThat(psa.patchSetId().get()).isEqualTo(1);
    assertThat(psa.label()).isEqualTo("Code-Review");
    assertThat(psa.accountId()).isEqualTo(user.id());
    assertThat(psa.value()).isEqualTo(1);
    assertThat(psa.realAccountId()).isEqualTo(admin.id()); // not user2

    ChangeData cd = r.getChange();
    ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
    assertThat(m.getMessage()).endsWith(in.message);
    assertThat(m.getAuthor()).isEqualTo(user.id());
    assertThat(m.getRealAuthor()).isEqualTo(admin.id()); // not user2
  }

  @Test
  public void changeMessageCreatedOnBehalfOfHasRealUser() throws Exception {
    allowCodeReviewOnBehalfOf();

    PushOneCommit.Result r = createChange();
    ReviewInput in = new ReviewInput();
    in.onBehalfOf = user.id().toString();
    in.message = "Message on behalf of";
    in.label("Code-Review", 1);

    requestScopeOperations.setApiUser(accountCreator.user2().id());
    gApi.changes().id(r.getChangeId()).revision(r.getPatchSetId().getId()).review(in);

    ChangeInfo info = gApi.changes().id(r.getChangeId()).get(MESSAGES);
    assertThat(info.messages).hasSize(2);

    ChangeMessageInfo changeMessageInfo = Iterables.getLast(info.messages);
    assertThat(changeMessageInfo.realAuthor).isNotNull();
    assertThat(changeMessageInfo.realAuthor._accountId)
        .isEqualTo(accountCreator.user2().id().get());
  }

  private void allowCodeReviewOnBehalfOf() throws Exception {
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .impersonation(true)
                .ref("refs/heads/*")
                .group(REGISTERED_USERS)
                .range(-1, 1))
        .update();
  }

  private void allowSubmitOnBehalfOf() throws Exception {
    allowSubmitOnBehalfOf(project);
  }

  private void allowSubmitOnBehalfOf(Project.NameKey project) throws Exception {
    String heads = "refs/heads/*";
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.SUBMIT_AS).ref(heads).group(REGISTERED_USERS))
        .add(allow(Permission.SUBMIT).ref(heads).group(REGISTERED_USERS))
        .add(
            allowLabel(TestLabels.codeReview().getName())
                .ref(heads)
                .group(REGISTERED_USERS)
                .range(-2, 2))
        .update();
  }

  private void blockRead(GroupInfo group) throws Exception {
    projectOperations
        .project(project)
        .forUpdate()
        .add(block(Permission.READ).ref("refs/heads/master").group(AccountGroup.uuid(group.id)))
        .update();
  }

  private void allowRunAs() throws Exception {
    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(GlobalCapability.RUN_AS).group(ANONYMOUS_USERS))
        .update();
  }

  private void removeRunAs() throws Exception {
    projectOperations
        .allProjectsForUpdate()
        .remove(capabilityKey(GlobalCapability.RUN_AS).group(ANONYMOUS_USERS))
        .update();
  }

  private static Header runAsHeader(Object user) {
    return new BasicHeader("X-Gerrit-RunAs", user.toString());
  }

  private void createRefLogFileIfMissing(Repository repo, String ref) throws IOException {
    File log = new File(repo.getDirectory(), "logs/" + ref);
    if (!log.exists()) {
      log.getParentFile().mkdirs();
      assertThat(log.createNewFile()).isTrue();
    }
  }
}
