Allow Owner permission to inherit

The Owner permission should be inherited from any parent project,
so long as the parent project isn't the global -- All Projects --
parent project.

Change-Id: I2a1f1d9c941a44d2ed4b8d900ee3ef6e48368343
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccessRightEditor.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccessRightEditor.java
index 762cc47..ce4f094 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccessRightEditor.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccessRightEditor.java
@@ -21,25 +21,21 @@
 import com.google.gerrit.client.ui.RPCSuggestOracle;
 import com.google.gerrit.common.data.ApprovalType;
 import com.google.gerrit.common.data.ProjectDetail;
+import com.google.gerrit.reviewdb.AccountGroup;
 import com.google.gerrit.reviewdb.ApprovalCategory;
 import com.google.gerrit.reviewdb.ApprovalCategoryValue;
-import com.google.gerrit.reviewdb.AccountGroup;
 import com.google.gerrit.reviewdb.Project;
 import com.google.gerrit.reviewdb.RefRight;
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
 import com.google.gwt.event.dom.client.ChangeEvent;
 import com.google.gwt.event.dom.client.ChangeHandler;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
 import com.google.gwt.event.dom.client.KeyCodes;
 import com.google.gwt.event.dom.client.KeyPressEvent;
 import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
 import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.Composite;
@@ -148,7 +144,7 @@
         .getActionTypes()) {
       final ApprovalCategory c = at.getCategory();
       if (Gerrit.getConfig().getWildProject().equals(projectKey)
-          && ApprovalCategory.OWN.equals(c.getId())) {
+          && !c.getId().canBeOnWildProject()) {
         // Giving out control of the WILD_PROJECT to other groups beyond
         // Administrators is dangerous. Having control over WILD_PROJECT
         // is about the same as having Administrator access as users are
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ApprovalCategory.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ApprovalCategory.java
index a8946b5..29ea97e 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ApprovalCategory.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ApprovalCategory.java
@@ -74,12 +74,13 @@
       id = newValue;
     }
 
-    /** True if the right can inherit from the magical "-- All Projects --". */
-    public boolean canInheritFromWildProject() {
+    /** True if the right can be assigned on the wild project. */
+    public boolean canBeOnWildProject() {
       if (OWN.equals(this)) {
         return false;
+      } else {
+        return true;
       }
-      return true;
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
index 567ecfe..302e458 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
@@ -56,12 +56,22 @@
       @WildProjectName final Project.NameKey wildProject,
       final ProjectControl.AssistedFactory projectControlFactory,
       @Assisted final Project project,
-      @Assisted final Collection<RefRight> rights) {
+      @Assisted Collection<RefRight> rights) {
     this.anonymousUser = anonymousUser;
     this.projectCache = projectCache;
     this.wildProject = wildProject;
     this.projectControlFactory = projectControlFactory;
 
+    if (wildProject.equals(project.getNameKey())) {
+      rights = new ArrayList<RefRight>(rights);
+      for (Iterator<RefRight> itr = rights.iterator(); itr.hasNext();) {
+        if (!itr.next().getApprovalCategoryId().canBeOnWildProject()) {
+          itr.remove();
+        }
+      }
+      rights = Collections.unmodifiableCollection(rights);
+    }
+
     this.project = project;
     this.localRights = rights;
 
@@ -174,9 +184,7 @@
    */
   public Collection<RefRight> getAllRights(ApprovalCategory.Id action, boolean dropOverridden) {
     Collection<RefRight> rights = new LinkedList<RefRight>(getLocalRights(action));
-    if (action.canInheritFromWildProject()) {
-      rights.addAll(filter(getInheritedRights(), action));
-    }
+    rights.addAll(filter(getInheritedRights(), action));
     if (dropOverridden) {
       Set<Grant> grants = new HashSet<Grant>();
       Iterator<RefRight> iter = rights.iterator();
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
index 81b1762..cf5d264 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
@@ -248,7 +248,7 @@
     assertFalse("NOT OWN " + ref, u.controlForRef(ref).isOwner());
   }
 
-  private void grant(Project.NameKey project, ApprovalCategory.Id categoryId, 
+  private void grant(Project.NameKey project, ApprovalCategory.Id categoryId,
       AccountGroup.Id group, String ref, int maxValue) {
     grant(project, categoryId, group, ref, maxValue, maxValue);
   }
@@ -284,7 +284,7 @@
 
   private ProjectState newProjectState() {
     ProjectCache projectCache = null;
-    Project.NameKey wildProject = null;
+    Project.NameKey wildProject = new Project.NameKey("-- All Projects --");
     ProjectControl.AssistedFactory projectControlFactory = null;
     ProjectState ps =
         new ProjectState(anonymousUser, projectCache, wildProject,