Add a new permission to permit rebasing changes in the web UI

So far only the change owner and submitters are permitted to rebase a
change in the web UI by pushing the 'Rebase Change' button. This change
introduces a new access right that can be assigned to other users to
permit them to do the rebase in the web UI as well.

Change-Id: I21e9981bd685f1d69e792abbd7eeaf1a60d039b8
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index d2078ab..8d89fa2 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -697,6 +697,21 @@
 is already restricted to the correct set of users.
 
 
+[[category_rebase]]
+Rebase
+~~~~~~
+
+This category permits users to rebase changes via the web UI by pushing
+the `Rebase Change` button.
+
+The change owner and submitters can always rebase changes in the web UI
+(even without having the `Rebase` access right assigned).
+
+Users without this access right who are able to upload new patch sets
+can still do the rebase locally and upload the rebased commit as a new
+patch set.
+
+
 [[category_submit]]
 Submit
 ~~~~~~
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java
index f818d7b..20261de 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java
@@ -30,6 +30,7 @@
   public static final String PUSH_MERGE = "pushMerge";
   public static final String PUSH_TAG = "pushTag";
   public static final String READ = "read";
+  public static final String REBASE = "rebase";
   public static final String SUBMIT = "submit";
 
   private static final List<String> NAMES_LC;
@@ -47,6 +48,7 @@
     NAMES_LC.add(PUSH_MERGE.toLowerCase());
     NAMES_LC.add(PUSH_TAG.toLowerCase());
     NAMES_LC.add(LABEL.toLowerCase());
+    NAMES_LC.add(REBASE.toLowerCase());
     NAMES_LC.add(SUBMIT.toLowerCase());
 
     labelIndex = NAMES_LC.indexOf(Permission.LABEL);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index 389ed2c..ef7b73d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -100,6 +100,7 @@
 	pushMerge, \
 	pushTag, \
 	read, \
+	rebase, \
 	submit
 create = Create Reference
 forgeAuthor = Forge Author Identity
@@ -110,6 +111,7 @@
 pushMerge = Push Merge Commit
 pushTag = Push Annotated Tag
 read = Read
+rebase = Rebase
 submit = Submit
 
 refErrorEmpty = Reference must be supplied
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index 53301b9..d17762e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -201,7 +201,8 @@
 
   /** Can this user rebase this change? */
   public boolean canRebase() {
-    return isOwner() || getRefControl().canSubmit();
+    return isOwner() || getRefControl().canSubmit()
+        || getRefControl().canRebase();
   }
 
   /** Can this user restore this change? */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
index a865603..db370e0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
@@ -125,6 +125,12 @@
         && canWrite();
   }
 
+  /** @return true if this user can rebase changes on this ref */
+  public boolean canRebase() {
+    return canPerform(Permission.REBASE)
+        && canWrite();
+  }
+
   /** @return true if this user can submit patch sets to this ref */
   public boolean canSubmit() {
     if (GitRepositoryManager.REF_CONFIG.equals(refName)) {