// 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.server.project;

import static com.google.gerrit.server.project.ProjectCache.noSuchProject;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.RetryHelper;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;

/** Manages access control for creating Git references (aka branches, tags). */
@Singleton
public class CreateRefControl {

  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final PermissionBackend permissionBackend;
  private final ProjectCache projectCache;
  private final Reachable reachable;
  private final RetryHelper retryHelper;

  @Inject
  CreateRefControl(
      PermissionBackend permissionBackend,
      ProjectCache projectCache,
      Reachable reachable,
      RetryHelper retryHelper) {
    this.permissionBackend = permissionBackend;
    this.projectCache = projectCache;
    this.reachable = reachable;
    this.retryHelper = retryHelper;
  }

  /**
   * Checks whether the {@link CurrentUser} can create a new Git ref.
   *
   * @param user the user performing the operation
   * @param repo repository on which user want to create
   * @param destBranch the branch the new {@link RevObject} should be created on
   * @param object the object the user will start the reference with
   * @param sourceBranches the source ref from which the new ref is created from
   * @throws AuthException if creation is denied; the message explains the denial.
   * @throws PermissionBackendException on failure of permission checks.
   * @throws ResourceConflictException if the project state does not permit the operation
   */
  public void checkCreateRef(
      Provider<? extends CurrentUser> user,
      Repository repo,
      BranchNameKey destBranch,
      RevObject object,
      boolean forPush,
      BranchNameKey... sourceBranches)
      throws AuthException, PermissionBackendException, NoSuchProjectException, IOException,
          ResourceConflictException {
    ProjectState ps =
        projectCache.get(destBranch.project()).orElseThrow(noSuchProject(destBranch.project()));
    ps.checkStatePermitsWrite();

    PermissionBackend.ForRef perm = permissionBackend.user(user.get()).ref(destBranch);
    if (object instanceof RevCommit) {
      perm.check(RefPermission.CREATE);
      if (sourceBranches.length == 0) {
        checkCreateCommit(user, repo, (RevCommit) object, ps.getNameKey(), perm, forPush);
      } else {
        for (BranchNameKey src : sourceBranches) {
          PermissionBackend.ForRef forRef = permissionBackend.user(user.get()).ref(src);
          if (forRef.testOrFalse(RefPermission.READ)) {
            return;
          }
        }
        AuthException e =
            new AuthException(
                String.format(
                    "must have %s on existing ref to create new ref from it",
                    RefPermission.READ.describeForException()));
        e.setAdvice(
            String.format(
                "use an existing ref visible to you, or get %s permission on the ref",
                RefPermission.READ.describeForException()));
        throw e;
      }
    } else if (object instanceof RevTag) {
      RevTag tag = (RevTag) object;
      try (RevWalk rw = new RevWalk(repo)) {
        rw.parseBody(tag);
      } catch (IOException e) {
        logger.atSevere().withCause(e).log(
            "RevWalk(%s) parsing %s:", destBranch.project(), tag.name());
        throw e;
      }

      // If tagger is present, require it matches the user's email.
      PersonIdent tagger = tag.getTaggerIdent();
      if (tagger != null
          && (!user.get().isIdentifiedUser()
              || !user.get().asIdentifiedUser().hasEmailAddress(tagger.getEmailAddress()))) {
        perm.check(RefPermission.FORGE_COMMITTER);
      }

      RevObject target = tag.getObject();
      if (target instanceof RevCommit) {
        checkCreateCommit(user, repo, (RevCommit) target, ps.getNameKey(), perm, forPush);
      } else {
        checkCreateRef(user, repo, destBranch, target, forPush);
      }

      // If the tag has a PGP signature, allow a lower level of permission
      // than if it doesn't have a PGP signature.
      PermissionBackend.ForRef forRef = permissionBackend.user(user.get()).ref(destBranch);
      if (tag.getRawGpgSignature() != null) {
        forRef.check(RefPermission.CREATE_SIGNED_TAG);
      } else {
        forRef.check(RefPermission.CREATE_TAG);
      }
    }
  }

  /**
   * Check if the user is allowed to create a new commit object if this creation would introduce a
   * new commit to the repository.
   */
  private void checkCreateCommit(
      Provider<? extends CurrentUser> user,
      Repository repo,
      RevCommit commit,
      Project.NameKey project,
      PermissionBackend.ForRef forRef,
      boolean forPush)
      throws AuthException, PermissionBackendException, IOException {
    try {
      // If the user has UPDATE (push) permission, they can set the ref to an arbitrary commit:
      //
      //  * if they don't have access, we don't advertise the data, and a conforming git client
      //  would send the object along with the push as outcome of the negotation.
      //  * a malicious client could try to send the update without sending the object. This
      //  is prevented by JGit's ConnectivityChecker (see receive.checkReferencedObjectsAreReachable
      //  to switch off this costly check).
      //
      // Thus, when using the git command-line client, we don't need to do extra checks for users
      // with push access.
      //
      // When using the REST API, there is no negotiation, and the target commit must already be on
      // the server, so we must check that the user can see that commit.
      if (forPush) {
        // We can only shortcut for UPDATE permission. Pushing a tag (CREATE_TAG, CREATE_SIGNED_TAG)
        // can also introduce new objects. While there may not be a confidentiality problem
        // (the caller supplies the data as documented above), the permission is for creating
        // tags to existing commits.
        forRef.check(RefPermission.UPDATE);
        return;
      }
    } catch (AuthException denied) {
      // Fall through to check reachability.
    }
    if (reachable.fromRefs(
        project,
        repo,
        commit,
        repo.getRefDatabase().getRefsByPrefix(Constants.R_HEADS, Constants.R_TAGS),
        Optional.of(user.get()))) {
      // If the user has no push permissions, check whether the object is
      // merged into a branch or tag readable by this user. If so, they are
      // not effectively "pushing" more objects, so they can create the ref
      // even if they don't have push permission.
      return;
    }

    // Previous check only catches normal branches. Try PatchSet refs too. If we can create refs,
    // we're not a replica, so we can always use the change index.
    List<ChangeData> changes =
        retryHelper
            .changeIndexQuery(
                "queryChangesByProjectCommitWithLimit1",
                q -> q.enforceVisibility(true).setLimit(1).byProjectCommit(project, commit))
            .call();
    if (!changes.isEmpty()) {
      return;
    }

    AuthException e =
        new AuthException(
            String.format(
                "%s for creating new commit object not permitted",
                RefPermission.UPDATE.describeForException()));
    e.setAdvice(
        String.format(
            "use a SHA1 visible to you, or get %s permission on the ref",
            RefPermission.UPDATE.describeForException()));
    throw e;
  }
}
