Merge "ListTags: Set the can_delete field"
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index f69b955..e2be6e6 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -2862,6 +2862,8 @@
 the signature.
 |`tagger`|Only set for annotated tags, if present in the tag.|The tagger as a
 link:rest-api-changes.html#git-person-info[GitPersonInfo] entity.
+|`can_delete`|`false` if not set|
+Whether the calling user can delete this tag.
 |=========================
 
 [[tag-input]]
diff --git a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 0519862..1e0065f 100644
--- a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -999,6 +999,7 @@
 
   protected void grantTagPermissions() throws Exception {
     grant(Permission.CREATE, project, R_TAGS + "*");
+    grant(Permission.DELETE, project, R_TAGS + "");
     grant(Permission.CREATE_TAG, project, R_TAGS + "*");
     grant(Permission.CREATE_SIGNED_TAG, project, R_TAGS + "*");
   }
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/TagsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/TagsIT.java
index 03459da..f191681 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/TagsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/TagsIT.java
@@ -170,11 +170,17 @@
     TagInfo result = tag(input.ref).create(input).get();
     assertThat(result.ref).isEqualTo(R_TAGS + input.ref);
     assertThat(result.revision).isEqualTo(input.revision);
+    assertThat(result.canDelete).isTrue();
 
     input.ref = "refs/tags/v2.0";
     result = tag(input.ref).create(input).get();
     assertThat(result.ref).isEqualTo(input.ref);
     assertThat(result.revision).isEqualTo(input.revision);
+    assertThat(result.canDelete).isTrue();
+
+    setApiUser(user);
+    result = tag(input.ref).get();
+    assertThat(result.canDelete).isFalse();
 
     eventRecorder.assertRefUpdatedEvents(project.get(), result.ref, null, result.revision);
   }
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/TagInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/TagInfo.java
index 2b57781..ccfea46 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/TagInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/TagInfo.java
@@ -21,13 +21,20 @@
   public String message;
   public GitPerson tagger;
 
-  public TagInfo(String ref, String revision) {
+  public TagInfo(String ref, String revision, boolean canDelete) {
     this.ref = ref;
     this.revision = revision;
+    this.canDelete = canDelete;
   }
 
-  public TagInfo(String ref, String revision, String object, String message, GitPerson tagger) {
-    this(ref, revision);
+  public TagInfo(
+      String ref,
+      String revision,
+      String object,
+      String message,
+      GitPerson tagger,
+      boolean canDelete) {
+    this(ref, revision, canDelete);
     this.object = object;
     this.message = message;
     this.tagger = tagger;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateTag.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateTag.java
index ed38c47..f674d17 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateTag.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateTag.java
@@ -134,7 +134,7 @@
             result.getObjectId(),
             identifiedUser.get().getAccount());
         try (RevWalk w = new RevWalk(repo)) {
-          return ListTags.createTagInfo(result, w);
+          return ListTags.createTagInfo(result, w, refControl);
         }
       }
     } catch (InvalidRevisionException e) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListTags.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListTags.java
index 9312e49..7f1ee60 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListTags.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListTags.java
@@ -121,10 +121,11 @@
 
     try (Repository repo = getRepository(resource.getNameKey());
         RevWalk rw = new RevWalk(repo)) {
+      ProjectControl control = resource.getControl();
       Map<String, Ref> all =
-          visibleTags(resource.getControl(), repo, repo.getRefDatabase().getRefs(Constants.R_TAGS));
+          visibleTags(control, repo, repo.getRefDatabase().getRefs(Constants.R_TAGS));
       for (Ref ref : all.values()) {
-        tags.add(createTagInfo(ref, rw));
+        tags.add(createTagInfo(ref, rw, control.controlForRef(ref.getName())));
       }
     }
 
@@ -154,16 +155,16 @@
         tagName = Constants.R_TAGS + tagName;
       }
       Ref ref = repo.getRefDatabase().exactRef(tagName);
+      ProjectControl control = resource.getControl();
       if (ref != null
-          && !visibleTags(resource.getControl(), repo, ImmutableMap.of(ref.getName(), ref))
-              .isEmpty()) {
-        return createTagInfo(ref, rw);
+          && !visibleTags(control, repo, ImmutableMap.of(ref.getName(), ref)).isEmpty()) {
+        return createTagInfo(ref, rw, control.controlForRef(ref.getName()));
       }
     }
     throw new ResourceNotFoundException(id);
   }
 
-  public static TagInfo createTagInfo(Ref ref, RevWalk rw)
+  public static TagInfo createTagInfo(Ref ref, RevWalk rw, RefControl control)
       throws MissingObjectException, IOException {
     RevObject object = rw.parseAny(ref.getObjectId());
     if (object instanceof RevTag) {
@@ -175,10 +176,11 @@
           tag.getName(),
           tag.getObject().getName(),
           tag.getFullMessage().trim(),
-          tagger != null ? CommonConverters.toGitPerson(tag.getTaggerIdent()) : null);
+          tagger != null ? CommonConverters.toGitPerson(tag.getTaggerIdent()) : null,
+          control.canDelete());
     }
     // Lightweight tag
-    return new TagInfo(ref.getName(), ref.getObjectId().getName());
+    return new TagInfo(ref.getName(), ref.getObjectId().getName(), control.canDelete());
   }
 
   private Repository getRepository(Project.NameKey project)