Admin-Project UI page accessible to users
Make the Admin->Projects page in the UI available to non-admin users.
The page will only show projects in which the user has read access.
Change-Id: I803609da4631cf037ba8b667ec927d1f9e3f8620
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java
index 7fafcb7..4dc998b 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java
@@ -23,6 +23,7 @@
public class InheritedRefRight {
private RefRight right;
private boolean inherited;
+ private boolean owner;
/**
* Creates a instance of a {@link RefRight} with data about inheritance
@@ -35,10 +36,12 @@
*
* @param right the right
* @param inherited true if the right is inherited, false otherwise
+ * @param owner true if right is owned by current user, false otherwise
*/
- public InheritedRefRight(RefRight right, boolean inherited) {
+ public InheritedRefRight(RefRight right, boolean inherited, boolean owner) {
this.right = right;
this.inherited = inherited;
+ this.owner = owner;
}
public RefRight getRight() {
@@ -49,6 +52,10 @@
return inherited;
}
+ public boolean isOwner() {
+ return owner;
+ }
+
@Override
public boolean equals(Object o) {
if (o instanceof InheritedRefRight) {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java
new file mode 100644
index 0000000..56c31ad
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java
@@ -0,0 +1,53 @@
+// Copyright (C) 2010 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.common.data;
+
+import com.google.gerrit.reviewdb.Branch;
+
+import java.util.List;
+
+/**
+ * It holds list of branches and boolean to indicate
+ * if it is allowed to add new branches.
+ */
+public final class ListBranchesResult {
+ protected boolean canAdd;
+
+ protected List<Branch> branches;
+
+ protected ListBranchesResult() {
+ }
+
+ public ListBranchesResult(final List<Branch> branches, boolean canAdd) {
+ this.branches = branches;
+ this.canAdd = canAdd;
+ }
+
+ public boolean getCanAdd() {
+ return canAdd;
+ }
+
+ public void setCanAdd(boolean canAdd) {
+ this.canAdd = canAdd;
+ }
+
+ public List<Branch> getBranches() {
+ return branches;
+ }
+
+ public void setBranches(List<Branch> branches) {
+ this.branches = branches;
+ }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
index b3c7183..355ab4a 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
@@ -22,7 +22,6 @@
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtjsonrpc.client.RemoteJsonService;
import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
import com.google.gwtjsonrpc.client.RpcImpl.Version;
import java.util.List;
@@ -31,7 +30,7 @@
@RpcImpl(version = Version.V2_0)
public interface ProjectAdminService extends RemoteJsonService {
@SignInRequired
- void ownedProjects(AsyncCallback<List<Project>> callback);
+ void visibleProjects(AsyncCallback<List<Project>> callback);
@SignInRequired
void projectDetail(Project.NameKey projectName,
@@ -43,7 +42,7 @@
@SignInRequired
void deleteRight(Project.NameKey projectName, Set<RefRight.Key> ids,
- AsyncCallback<VoidResult> callback);
+ AsyncCallback<ProjectDetail> callback);
@SignInRequired
void addRight(Project.NameKey projectName, ApprovalCategory.Id categoryId,
@@ -52,11 +51,11 @@
@SignInRequired
void listBranches(Project.NameKey projectName,
- AsyncCallback<List<Branch>> callback);
+ AsyncCallback<ListBranchesResult> callback);
@SignInRequired
void addBranch(Project.NameKey projectName, String branchName,
- String startingRevision, AsyncCallback<List<Branch>> callback);
+ String startingRevision, AsyncCallback<ListBranchesResult> callback);
@SignInRequired
void deleteBranch(Project.NameKey projectName, Set<Branch.NameKey> ids,
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
index ac5c63c..2aa8c62 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
@@ -24,6 +24,10 @@
public Project project;
public Map<AccountGroup.Id, AccountGroup> groups;
public List<InheritedRefRight> rights;
+ public boolean canModifyDescription;
+ public boolean canModifyMergeType;
+ public boolean canModifyAgreements;
+ public boolean canModifyAccess;
public ProjectDetail() {
}
@@ -39,4 +43,20 @@
public void setRights(final List<InheritedRefRight> r) {
rights = r;
}
+
+ public void setCanModifyDescription(final boolean cmd) {
+ canModifyDescription = cmd;
+ }
+
+ public void setCanModifyMergeType(final boolean cmmt) {
+ canModifyMergeType = cmmt;
+ }
+
+ public void setCanModifyAgreements(final boolean cma) {
+ canModifyAgreements = cma;
+ }
+
+ public void setCanModifyAccess(final boolean cma) {
+ canModifyAccess = cma;
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesPanel.java
index 865135a..090b000 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesPanel.java
@@ -17,6 +17,7 @@
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.FancyFlexTable;
+import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.common.data.GitwebLink;
import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.InvalidRevisionException;
@@ -57,6 +58,8 @@
private NpTextBox nameTxtBox;
private NpTextBox irevTxtBox;
+ private final FlowPanel addPanel = new FlowPanel();
+
public ProjectBranchesPanel(final Project.NameKey toShow) {
final FlowPanel body = new FlowPanel();
initBranches(body);
@@ -71,14 +74,20 @@
super.onLoad();
Util.PROJECT_SVC.listBranches(projectName,
- new GerritCallback<List<Branch>>() {
- public void onSuccess(final List<Branch> result) {
+ new GerritCallback<ListBranchesResult>() {
+ public void onSuccess(final ListBranchesResult result) {
enableForm(true);
- branches.display(result);
+ display(result.getBranches());
+ addPanel.setVisible(result.getCanAdd());
}
});
}
+ private void display(final List<Branch> listBranches) {
+ branches.display(listBranches);
+ delBranch.setVisible(branches.hasBranchCanDelete());
+ }
+
private void enableForm(final boolean on) {
delBranch.setEnabled(on);
addBranch.setEnabled(on);
@@ -87,7 +96,6 @@
}
private void initBranches(final Panel body) {
- final FlowPanel addPanel = new FlowPanel();
addPanel.setStyleName(Gerrit.RESOURCES.css().addSshKeyPanel());
final Grid addGrid = new Grid(2, 2);
@@ -209,12 +217,12 @@
addBranch.setEnabled(false);
Util.PROJECT_SVC.addBranch(projectName, branchName, rev,
- new GerritCallback<List<Branch>>() {
- public void onSuccess(final List<Branch> result) {
+ new GerritCallback<ListBranchesResult>() {
+ public void onSuccess(final ListBranchesResult result) {
addBranch.setEnabled(true);
nameTxtBox.setText("");
irevTxtBox.setText("");
- branches.display(result);
+ display(result.getBranches());
}
@Override
@@ -239,6 +247,8 @@
}
private class BranchesTable extends FancyFlexTable<Branch> {
+ boolean canDelete;
+
BranchesTable() {
table.setWidth("");
table.setText(0, 2, Util.C.columnBranchName());
@@ -282,6 +292,8 @@
}
void display(final List<Branch> result) {
+ canDelete = false;
+
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
@@ -296,7 +308,13 @@
void populate(final int row, final Branch k) {
final GitwebLink c = Gerrit.getConfig().getGitwebLink();
- table.setWidget(row, 1, new CheckBox());
+ if (k.getCanDelete()) {
+ table.setWidget(row, 1, new CheckBox());
+ canDelete = true;
+ } else {
+ table.setText(row, 1, "");
+ }
+
table.setText(row, 2, k.getShortName());
if (k.getRevision() != null) {
@@ -320,5 +338,9 @@
setRowItem(row, k);
}
+
+ boolean hasBranchCanDelete() {
+ return canDelete;
+ }
}
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
index ea5fba6..49566ba 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
@@ -70,7 +70,7 @@
@Override
protected void onLoad() {
- enableForm(false);
+ enableForm(false, false, false);
saveProject.setEnabled(false);
super.onLoad();
refresh();
@@ -80,18 +80,26 @@
Util.PROJECT_SVC.projectDetail(projectName,
new GerritCallback<ProjectDetail>() {
public void onSuccess(final ProjectDetail result) {
- enableForm(true);
+ enableForm(result.canModifyAgreements,
+ result.canModifyDescription, result.canModifyMergeType);
+ saveProject.setVisible(
+ result.canModifyAgreements ||
+ result.canModifyDescription ||
+ result.canModifyMergeType);
saveProject.setEnabled(false);
display(result);
}
});
}
- private void enableForm(final boolean on) {
- submitType.setEnabled(on);
- descTxt.setEnabled(on);
- useContributorAgreements.setEnabled(on);
- useSignedOffBy.setEnabled(on);
+ private void enableForm(final boolean canModifyAgreements,
+ final boolean canModifyDescription, final boolean canModifyMergeType) {
+ submitType.setEnabled(canModifyMergeType);
+ descTxt.setEnabled(canModifyDescription);
+ useContributorAgreements.setEnabled(canModifyAgreements);
+ useSignedOffBy.setEnabled(canModifyAgreements);
+ saveProject.setEnabled(
+ canModifyAgreements || canModifyDescription || canModifyMergeType);
}
private void initDescription(final Panel body) {
@@ -185,13 +193,14 @@
.getValue(submitType.getSelectedIndex())));
}
- enableForm(false);
+ enableForm(false, false, false);
saveProject.setEnabled(false);
Util.PROJECT_SVC.changeProjectSettings(project,
new GerritCallback<ProjectDetail>() {
public void onSuccess(final ProjectDetail result) {
- enableForm(true);
+ enableForm(result.canModifyAgreements,
+ result.canModifyDescription, result.canModifyMergeType);
display(result);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
index 04d7038..97f1224 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
@@ -39,7 +39,7 @@
@Override
protected void onLoad() {
super.onLoad();
- Util.PROJECT_SVC.ownedProjects(new ScreenLoadCallback<List<Project>>(this) {
+ Util.PROJECT_SVC.visibleProjects(new ScreenLoadCallback<List<Project>>(this) {
@Override
protected void preDisplay(final List<Project> result) {
projects.display(result);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
index 58b076f..80f1c38 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
@@ -54,7 +54,6 @@
import com.google.gwtexpui.globalkey.client.NpTextBox;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
-import com.google.gwtjsonrpc.client.VoidResult;
import java.util.HashSet;
import java.util.List;
@@ -76,6 +75,8 @@
private SuggestBox nameTxt;
private NpTextBox referenceTxt;
+ private final FlowPanel addPanel = new FlowPanel();
+
public ProjectRightsPanel(final Project.NameKey toShow) {
projectName = toShow;
@@ -121,7 +122,6 @@
}
private void initRights(final Panel body) {
- final FlowPanel addPanel = new FlowPanel();
addPanel.setStyleName(Gerrit.RESOURCES.css().addSshKeyPanel());
final Grid addGrid = new Grid(5, 2);
@@ -223,7 +223,8 @@
delRight.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
- rights.deleteChecked();
+ final HashSet<RefRight.Key> refRightIds = rights.getRefRightIdsChecked();
+ doDeleteRefRights(refRightIds);
}
});
@@ -254,6 +255,22 @@
parentName.setText(parent.get());
rights.display(result.groups, result.rights);
+
+ addPanel.setVisible(result.canModifyAccess);
+ delRight.setVisible(rights.getCanDelete());
+ }
+
+ private void doDeleteRefRights(final HashSet<RefRight.Key> refRightIds) {
+ if (!refRightIds.isEmpty()) {
+ Util.PROJECT_SVC.deleteRight(projectName, refRightIds,
+ new GerritCallback<ProjectDetail>() {
+ @Override
+ public void onSuccess(final ProjectDetail result) {
+ //The user could no longer modify access after deleting a ref right.
+ display(result);
+ }
+ });
+ }
}
private void doAddNewRight() {
@@ -393,6 +410,8 @@
}
private class RightsTable extends FancyFlexTable<RefRight> {
+ boolean canDelete;
+
RightsTable() {
table.setWidth("");
table.setText(0, 2, Util.C.columnApprovalCategory());
@@ -408,7 +427,7 @@
fmt.addStyleName(0, 5, Gerrit.RESOURCES.css().dataHeader());
}
- void deleteChecked() {
+ HashSet<RefRight.Key> getRefRightIdsChecked() {
final HashSet<RefRight.Key> refRightIds = new HashSet<RefRight.Key>();
for (int row = 1; row < table.getRowCount(); row++) {
RefRight r = getRowItem(row);
@@ -417,28 +436,13 @@
refRightIds.add(r.getKey());
}
}
-
- GerritCallback<VoidResult> updateTable =
- new GerritCallback<VoidResult>() {
- @Override
- public void onSuccess(final VoidResult result) {
- for (int row = 1; row < table.getRowCount();) {
- RefRight r = getRowItem(row);
- if (r != null && refRightIds.contains(r.getKey())) {
- table.removeRow(row);
- } else {
- row++;
- }
- }
- }
- };
- if (!refRightIds.isEmpty()) {
- Util.PROJECT_SVC.deleteRight(projectName, refRightIds, updateTable);
- }
+ return refRightIds;
}
void display(final Map<AccountGroup.Id, AccountGroup> groups,
final List<InheritedRefRight> refRights) {
+ canDelete = false;
+
while (1 < table.getRowCount())
table.removeRow(table.getRowCount() - 1);
@@ -450,8 +454,7 @@
}
}
- void populate(final int row,
- final Map<AccountGroup.Id, AccountGroup> groups,
+ void populate(final int row, final Map<AccountGroup.Id, AccountGroup> groups,
final InheritedRefRight r) {
final GerritConfig config = Gerrit.getConfig();
final RefRight right = r.getRight();
@@ -460,10 +463,11 @@
right.getApprovalCategoryId());
final AccountGroup group = groups.get(right.getAccountGroupId());
- if (r.isInherited()) {
+ if (r.isInherited() || !r.isOwner()) {
table.setText(row, 1, "");
} else {
table.setWidget(row, 1, new CheckBox());
+ canDelete = true;
}
if (ar != null) {
@@ -525,5 +529,9 @@
m.append(e.getName());
}
}
+
+ private boolean getCanDelete() {
+ return canDelete;
+ }
}
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/AddBranch.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/AddBranch.java
index 69eb7b8..4fc775e 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/AddBranch.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/AddBranch.java
@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.rpc.project;
+import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.InvalidRevisionException;
import com.google.gerrit.httpd.rpc.Handler;
@@ -42,9 +43,8 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.util.List;
-class AddBranch extends Handler<List<Branch>> {
+class AddBranch extends Handler<ListBranchesResult> {
private static final Logger log = LoggerFactory.getLogger(AddBranch.class);
interface Factory {
@@ -85,7 +85,7 @@
}
@Override
- public List<Branch> call() throws NoSuchProjectException,
+ public ListBranchesResult call() throws NoSuchProjectException,
InvalidNameException, InvalidRevisionException, IOException {
final ProjectControl projectControl =
projectControlFactory.controlFor(projectName);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/DeleteRefRights.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/DeleteRefRights.java
index 2d0ab4e..db179ed 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/DeleteRefRights.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/DeleteRefRights.java
@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.rpc.project;
+import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
@@ -23,7 +24,6 @@
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefControl;
-import com.google.gwtjsonrpc.client.VoidResult;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -31,12 +31,13 @@
import java.util.Collections;
import java.util.Set;
-class DeleteRefRights extends Handler<VoidResult> {
+class DeleteRefRights extends Handler<ProjectDetail> {
interface Factory {
DeleteRefRights create(@Assisted Project.NameKey projectName,
@Assisted Set<RefRight.Key> toRemove);
}
+ private final ProjectDetailFactory.Factory projectDetailFactory;
private final ProjectControl.Factory projectControlFactory;
private final ProjectCache projectCache;
private final ReviewDb db;
@@ -45,11 +46,13 @@
private final Set<RefRight.Key> toRemove;
@Inject
- DeleteRefRights(final ProjectControl.Factory projectControlFactory,
+ DeleteRefRights(final ProjectDetailFactory.Factory projectDetailFactory,
+ final ProjectControl.Factory projectControlFactory,
final ProjectCache projectCache, final ReviewDb db,
@Assisted final Project.NameKey projectName,
@Assisted final Set<RefRight.Key> toRemove) {
+ this.projectDetailFactory = projectDetailFactory;
this.projectControlFactory = projectControlFactory;
this.projectCache = projectCache;
this.db = db;
@@ -59,7 +62,7 @@
}
@Override
- public VoidResult call() throws NoSuchProjectException, OrmException,
+ public ProjectDetail call() throws NoSuchProjectException, OrmException,
NoSuchRefException {
final ProjectControl projectControl =
projectControlFactory.controlFor(projectName);
@@ -80,7 +83,7 @@
}
}
projectCache.evictAll();
- return VoidResult.INSTANCE;
+ return projectDetailFactory.create(projectName).call();
}
private RefControl controlForRef(ProjectControl p, String ref) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ListBranches.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ListBranches.java
index 158bed1..c02af37 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ListBranches.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ListBranches.java
@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.rpc.project;
+import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Branch;
import com.google.gerrit.reviewdb.Project;
@@ -21,6 +22,7 @@
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.project.RefControl;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -36,7 +38,7 @@
import java.util.List;
import java.util.Map;
-class ListBranches extends Handler<List<Branch>> {
+class ListBranches extends Handler<ListBranchesResult> {
interface Factory {
ListBranches create(@Assisted Project.NameKey name);
}
@@ -58,7 +60,7 @@
}
@Override
- public List<Branch> call() throws NoSuchProjectException,
+ public ListBranchesResult call() throws NoSuchProjectException,
RepositoryNotFoundException {
final ProjectControl pctl = projectControlFactory.validateFor( //
projectName, //
@@ -91,7 +93,8 @@
// showing the resolved value, show the name it references.
//
String target = ref.getTarget().getName();
- if (!pctl.controlForRef(target).isVisible()) {
+ RefControl targetRefControl = pctl.controlForRef(target);
+ if (!targetRefControl.isVisible()) {
continue;
}
if (target.startsWith(Constants.R_HEADS)) {
@@ -100,6 +103,8 @@
Branch b = createBranch(Constants.HEAD);
b.setRevision(new RevId(target));
+ b.setCanDelete(targetRefControl.canDelete());
+
if (Constants.HEAD.equals(ref.getName())) {
headBranch = b;
} else {
@@ -108,12 +113,17 @@
continue;
}
+ RefControl refControl = pctl.controlForRef(ref.getName());
+
if (ref.getName().startsWith(Constants.R_HEADS)
- && pctl.controlForRef(ref.getName()).isVisible()) {
+ && refControl.isVisible()) {
final Branch b = createBranch(ref.getName());
if (ref.getObjectId() != null) {
b.setRevision(new RevId(ref.getObjectId().name()));
}
+
+ b.setCanDelete(refControl.canDelete());
+
branches.add(b);
}
}
@@ -129,7 +139,7 @@
if (headBranch != null) {
branches.add(0, headBranch);
}
- return branches;
+ return new ListBranchesResult(branches, pctl.canAddRefs());
}
private Branch createBranch(final String name) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
index 80e1949..9b06dd9 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.rpc.project;
+import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.common.data.ProjectAdminService;
import com.google.gerrit.common.data.ProjectDetail;
import com.google.gerrit.reviewdb.ApprovalCategory;
@@ -21,7 +22,6 @@
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.VoidResult;
import com.google.inject.Inject;
import java.util.List;
@@ -32,7 +32,7 @@
private final ChangeProjectSettings.Factory changeProjectSettingsFactory;
private final DeleteBranches.Factory deleteBranchesFactory;
private final ListBranches.Factory listBranchesFactory;
- private final OwnedProjects.Factory ownedProjectsFactory;
+ private final VisibleProjects.Factory visibleProjectsFactory;
private final ProjectDetailFactory.Factory projectDetailFactory;
private final AddRefRight.Factory addRefRightFactory;
private final DeleteRefRights.Factory deleteRefRightsFactory;
@@ -42,7 +42,7 @@
final ChangeProjectSettings.Factory changeProjectSettingsFactory,
final DeleteBranches.Factory deleteBranchesFactory,
final ListBranches.Factory listBranchesFactory,
- final OwnedProjects.Factory ownedProjectsFactory,
+ final VisibleProjects.Factory visibleProjectsFactory,
final ProjectDetailFactory.Factory projectDetailFactory,
final AddRefRight.Factory addRefRightFactory,
final DeleteRefRights.Factory deleteRefRightsFactory) {
@@ -50,15 +50,15 @@
this.changeProjectSettingsFactory = changeProjectSettingsFactory;
this.deleteBranchesFactory = deleteBranchesFactory;
this.listBranchesFactory = listBranchesFactory;
- this.ownedProjectsFactory = ownedProjectsFactory;
+ this.visibleProjectsFactory = visibleProjectsFactory;
this.projectDetailFactory = projectDetailFactory;
this.addRefRightFactory = addRefRightFactory;
this.deleteRefRightsFactory = deleteRefRightsFactory;
}
@Override
- public void ownedProjects(final AsyncCallback<List<Project>> callback) {
- ownedProjectsFactory.create().to(callback);
+ public void visibleProjects(final AsyncCallback<List<Project>> callback) {
+ visibleProjectsFactory.create().to(callback);
}
@Override
@@ -75,7 +75,7 @@
@Override
public void deleteRight(final Project.NameKey projectName,
- final Set<RefRight.Key> toRemove, final AsyncCallback<VoidResult> callback) {
+ final Set<RefRight.Key> toRemove, final AsyncCallback<ProjectDetail> callback) {
deleteRefRightsFactory.create(projectName, toRemove).to(callback);
}
@@ -90,7 +90,7 @@
@Override
public void listBranches(final Project.NameKey projectName,
- final AsyncCallback<List<Branch>> callback) {
+ final AsyncCallback<ListBranchesResult> callback) {
listBranchesFactory.create(projectName).to(callback);
}
@@ -104,7 +104,7 @@
@Override
public void addBranch(final Project.NameKey projectName,
final String branchName, final String startingRevision,
- final AsyncCallback<List<Branch>> callback) {
+ final AsyncCallback<ListBranchesResult> callback) {
addBranchFactory.create(projectName, branchName, startingRevision).to(
callback);
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectDetailFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectDetailFactory.java
index bf1ef61..cdd535b 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectDetailFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectDetailFactory.java
@@ -26,6 +26,7 @@
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.project.RefControl;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -64,10 +65,10 @@
@Override
public ProjectDetail call() throws NoSuchProjectException {
- final ProjectState projectState =
- projectControlFactory.validateFor(projectName,
- ProjectControl.OWNER | ProjectControl.VISIBLE).getProjectState();
-
+ final ProjectControl pc =
+ projectControlFactory.validateFor(projectName, ProjectControl.OWNER
+ | ProjectControl.VISIBLE);
+ final ProjectState projectState = pc.getProjectState();
final ProjectDetail detail = new ProjectDetail();
detail.setProject(projectState.getProject());
@@ -75,7 +76,8 @@
final List<InheritedRefRight> refRights = new ArrayList<InheritedRefRight>();
for (final RefRight r : projectState.getInheritedRights()) {
- InheritedRefRight refRight = new InheritedRefRight(r, true);
+ InheritedRefRight refRight = new InheritedRefRight(
+ r, true, controlForRef(pc, r.getRefPattern()).isOwner());
if (!refRights.contains(refRight)) {
refRights.add(refRight);
wantGroup(r.getAccountGroupId());
@@ -83,7 +85,8 @@
}
for (final RefRight r : projectState.getLocalRights()) {
- refRights.add(new InheritedRefRight(r, false));
+ refRights.add(new InheritedRefRight(
+ r, false, controlForRef(pc, r.getRefPattern()).isOwner()));
wantGroup(r.getAccountGroupId());
}
@@ -118,8 +121,15 @@
}
});
+ final boolean userIsOwner = pc.isOwner();
+ final boolean userIsOwnerAnyRef = pc.isOwnerAnyRef();
+
detail.setRights(refRights);
detail.setGroups(groups);
+ detail.setCanModifyAccess(userIsOwnerAnyRef);
+ detail.setCanModifyAgreements(userIsOwner);
+ detail.setCanModifyDescription(userIsOwner);
+ detail.setCanModifyMergeType(userIsOwner);
return detail;
}
@@ -134,4 +144,11 @@
groups.put(groupId, groupCache.get(groupId));
}
}
+
+ private RefControl controlForRef(ProjectControl p, String ref) {
+ if (ref.endsWith("/*")) {
+ ref = ref.substring(0, ref.length() - 1);
+ }
+ return p.controlForRef(ref);
+ }
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
index 9c8affd..7932c79 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
@@ -34,7 +34,7 @@
factory(DeleteBranches.Factory.class);
factory(DeleteRefRights.Factory.class);
factory(ListBranches.Factory.class);
- factory(OwnedProjects.Factory.class);
+ factory(VisibleProjects.Factory.class);
factory(ProjectDetailFactory.Factory.class);
}
});
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/OwnedProjects.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/VisibleProjects.java
similarity index 67%
rename from gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/OwnedProjects.java
rename to gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/VisibleProjects.java
index 2bf7530..9d778f1 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/OwnedProjects.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/VisibleProjects.java
@@ -14,27 +14,23 @@
package com.google.gerrit.httpd.rpc.project;
+
import com.google.gerrit.httpd.rpc.Handler;
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Project;
-import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.List;
-class OwnedProjects extends Handler<List<Project>> {
+class VisibleProjects extends Handler<List<Project>> {
interface Factory {
- OwnedProjects create();
+ VisibleProjects create();
}
private final ProjectControl.Factory projectControlFactory;
@@ -42,7 +38,7 @@
private final ReviewDb db;
@Inject
- OwnedProjects(final ProjectControl.Factory projectControlFactory,
+ VisibleProjects(final ProjectControl.Factory projectControlFactory,
final IdentifiedUser user, final ReviewDb db) {
this.projectControlFactory = projectControlFactory;
this.user = user;
@@ -54,25 +50,16 @@
final List<Project> result;
if (user.isAdministrator()) {
result = db.projects().all().toList();
-
} else {
- final HashSet<Project.NameKey> seen = new HashSet<Project.NameKey>();
result = new ArrayList<Project>();
- for (final AccountGroup.Id groupId : user.getEffectiveGroups()) {
- for (final RefRight r : db.refRights().byCategoryGroup(
- ApprovalCategory.OWN, groupId)) {
- final Project.NameKey name = r.getProjectNameKey();
- if (!seen.add(name)) {
- continue;
+ for (Project p : db.projects().all().toList()) {
+ try {
+ ProjectControl c = projectControlFactory.controlFor(p.getNameKey());
+ if (c.isVisible() || c.isOwner()) {
+ result.add(p);
}
- try {
- ProjectControl c = projectControlFactory.controlFor(name);
- if (c.isOwnerAnyRef()) {
- result.add(c.getProject());
- }
- } catch (NoSuchProjectException e) {
- continue;
- }
+ } catch (NoSuchProjectException e) {
+ continue;
}
}
}
diff --git a/gerrit-httpd/src/test/java/com/google/gerrit/httpd/rpc/project/ListBranchesTest.java b/gerrit-httpd/src/test/java/com/google/gerrit/httpd/rpc/project/ListBranchesTest.java
index 1a1e9a7..4c482d4 100644
--- a/gerrit-httpd/src/test/java/com/google/gerrit/httpd/rpc/project/ListBranchesTest.java
+++ b/gerrit-httpd/src/test/java/com/google/gerrit/httpd/rpc/project/ListBranchesTest.java
@@ -24,6 +24,7 @@
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
+import com.google.gerrit.common.data.ListBranchesResult;
import com.google.gerrit.reviewdb.Branch;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -121,11 +122,12 @@
}
- private List<Branch> permitted(boolean getHead)
+ private ListBranchesResult permitted(boolean getHead)
throws NoSuchProjectException, IOException {
Map<String, Ref> refs = realDb.getAllRefs();
validate().andReturn(pc);
+
expect(grm.openRepository(eq(name.get()))).andReturn(mockDb);
expect(mockDb.getAllRefs()).andDelegateTo(realDb);
if (getHead) {
@@ -140,12 +142,16 @@
}
mockDb.close();
+
+ expect(pc.canAddRefs()).andReturn(true);
+
expectLastCall();
doReplay();
- final List<Branch> r = new ListBranches(pcf, grm, name).call();
+ final ListBranchesResult r = new ListBranches(pcf, grm, name).call();
doVerify();
assertNotNull(r);
+ assertNotNull(r.getBranches());
return r;
}
@@ -153,6 +159,9 @@
RefControl rc = createStrictMock(RefControl.class);
refMocks.add(rc);
expect(rc.isVisible()).andReturn(visible);
+ if (visible) {
+ expect(rc.canDelete()).andReturn(true);
+ }
if (ref.isSymbolic()) {
expect(pc.controlForRef(ref.getTarget().getName())).andReturn(rc);
@@ -162,10 +171,11 @@
}
public void testEmptyProject() throws Exception {
- List<Branch> r = permitted(true);
- assertEquals(1, r.size());
+ ListBranchesResult r = permitted(true);
- Branch b = r.get(0);
+ assertEquals(1, r.getBranches().size());
+
+ Branch b = r.getBranches().get(0);
assertNotNull(b);
assertNotNull(b.getNameKey());
@@ -182,10 +192,10 @@
public void testMasterBranch() throws Exception {
set("master", idA);
- List<Branch> r = permitted(false);
- assertEquals(2, r.size());
+ ListBranchesResult r = permitted(false);
+ assertEquals(2, r.getBranches().size());
- Branch b = r.get(0);
+ Branch b = r.getBranches().get(0);
assertNotNull(b);
assertNotNull(b.getNameKey());
@@ -198,7 +208,7 @@
assertNotNull(b.getRevision());
assertEquals("master", b.getRevision().get());
- b = r.get(1);
+ b = r.getBranches().get(1);
assertNotNull(b);
assertNotNull(b.getNameKey());
@@ -215,10 +225,10 @@
public void testBranchNotHead() throws Exception {
set("foo", idA);
- List<Branch> r = permitted(true);
- assertEquals(2, r.size());
+ ListBranchesResult r = permitted(true);
+ assertEquals(2, r.getBranches().size());
- Branch b = r.get(0);
+ Branch b = r.getBranches().get(0);
assertNotNull(b);
assertNotNull(b.getNameKey());
@@ -231,7 +241,7 @@
assertNotNull(b.getRevision());
assertEquals("master", b.getRevision().get());
- b = r.get(1);
+ b = r.getBranches().get(1);
assertNotNull(b);
assertNotNull(b.getNameKey());
@@ -258,18 +268,19 @@
for (Ref ref : u.values()) {
assumeVisible(ref, true);
}
+ expect(pc.canAddRefs()).andReturn(true);
mockDb.close();
expectLastCall();
doReplay();
- final List<Branch> r = new ListBranches(pcf, grm, name).call();
+ final ListBranchesResult r = new ListBranches(pcf, grm, name).call();
doVerify();
assertNotNull(r);
- assertEquals(3, r.size());
- assertEquals(HEAD, r.get(0).getShortName());
- assertEquals("bar", r.get(1).getShortName());
- assertEquals("foo", r.get(2).getShortName());
+ assertEquals(3, r.getBranches().size());
+ assertEquals(HEAD, r.getBranches().get(0).getShortName());
+ assertEquals("bar", r.getBranches().get(1).getShortName());
+ assertEquals("foo", r.getBranches().get(2).getShortName());
}
public void testHeadNotVisible() throws Exception {
@@ -284,14 +295,15 @@
expect(mockDb.getAllRefs()).andReturn(u);
assumeVisible(bar, false);
assumeVisible(bar, false);
+ expect(pc.canAddRefs()).andReturn(true);
mockDb.close();
expectLastCall();
doReplay();
- final List<Branch> r = new ListBranches(pcf, grm, name).call();
+ final ListBranchesResult r = new ListBranches(pcf, grm, name).call();
doVerify();
assertNotNull(r);
- assertTrue(r.isEmpty());
+ assertTrue(r.getBranches().isEmpty());
}
public void testHeadVisibleButBranchHidden() throws Exception {
@@ -311,16 +323,17 @@
assumeVisible(bar, true);
assumeVisible(bar, true);
assumeVisible(foo, false);
+ expect(pc.canAddRefs()).andReturn(true);
mockDb.close();
expectLastCall();
doReplay();
- final List<Branch> r = new ListBranches(pcf, grm, name).call();
+ final ListBranchesResult r = new ListBranches(pcf, grm, name).call();
doVerify();
assertNotNull(r);
- assertEquals(2, r.size());
- assertEquals(HEAD, r.get(0).getShortName());
- assertEquals("bar", r.get(1).getShortName());
+ assertEquals(2, r.getBranches().size());
+ assertEquals(HEAD, r.getBranches().get(0).getShortName());
+ assertEquals("bar", r.getBranches().get(1).getShortName());
}
}
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Branch.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Branch.java
index 2bacc63..27716a8 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Branch.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Branch.java
@@ -71,6 +71,7 @@
protected NameKey name;
protected RevId revision;
+ protected boolean canDelete;
protected Branch() {
}
@@ -98,4 +99,12 @@
public void setRevision(final RevId id) {
revision = id;
}
+
+ public boolean getCanDelete() {
+ return canDelete;
+ }
+
+ public void setCanDelete(boolean canDelete) {
+ this.canDelete = canDelete;
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
index d8e2069..24fe3f0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
@@ -121,6 +121,11 @@
|| canPerformOnAnyRef(ApprovalCategory.READ, (short) 1);
}
+ public boolean canAddRefs() {
+ return (canPerformOnAnyRef(ApprovalCategory.PUSH_HEAD, ApprovalCategory.PUSH_HEAD_CREATE)
+ || isOwnerAnyRef());
+ }
+
/** Can this user see all the refs in this projects? */
public boolean allRefsAreVisible() {
return visibleForReplication()