Allow extra group suggestions for project owners.
The suggestGroupOwner currently only returns groups that are visible to the user. When editing a project config, include the Project.NameKey so owners can be shown and add groups to which they are not a member. Change-Id: I1df4a025b6e11e92a44e77e2e96e16f4e187f1a1
This commit is contained in:
		| @@ -29,9 +29,16 @@ public interface SuggestService extends RemoteJsonService { | |||||||
|   void suggestAccount(String query, Boolean enabled, int limit, |   void suggestAccount(String query, Boolean enabled, int limit, | ||||||
|       AsyncCallback<List<AccountInfo>> callback); |       AsyncCallback<List<AccountInfo>> callback); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * @see #suggestAccountGroup(com.google.gerrit.reviewdb.client.Project.NameKey, String, int, AsyncCallback) | ||||||
|  |    */ | ||||||
|  |   @Deprecated | ||||||
|   void suggestAccountGroup(String query, int limit, |   void suggestAccountGroup(String query, int limit, | ||||||
|       AsyncCallback<List<GroupReference>> callback); |       AsyncCallback<List<GroupReference>> callback); | ||||||
|  |  | ||||||
|  |   void suggestAccountGroupForProject(Project.NameKey project, String query, | ||||||
|  |       int limit, AsyncCallback<List<GroupReference>> callback); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * @see #suggestChangeReviewer(com.google.gerrit.reviewdb.client.Change.Id, String, int, AsyncCallback) |    * @see #suggestChangeReviewer(com.google.gerrit.reviewdb.client.Change.Id, String, int, AsyncCallback) | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -276,7 +276,8 @@ public class AccessSectionEditor extends Composite implements | |||||||
|   private class PermissionEditorSource extends EditorSource<PermissionEditor> { |   private class PermissionEditorSource extends EditorSource<PermissionEditor> { | ||||||
|     @Override |     @Override | ||||||
|     public PermissionEditor create(int index) { |     public PermissionEditor create(int index) { | ||||||
|       PermissionEditor subEditor = new PermissionEditor(readOnly, value); |       PermissionEditor subEditor = | ||||||
|  |           new PermissionEditor(projectAccess.getProjectName(), readOnly, value); | ||||||
|       permissionContainer.insert(subEditor, index); |       permissionContainer.insert(subEditor, index); | ||||||
|       return subEditor; |       return subEditor; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ package com.google.gerrit.client.admin; | |||||||
| import com.google.gerrit.client.ui.AccountGroupSuggestOracle; | import com.google.gerrit.client.ui.AccountGroupSuggestOracle; | ||||||
| import com.google.gerrit.client.ui.RPCSuggestOracle; | import com.google.gerrit.client.ui.RPCSuggestOracle; | ||||||
| import com.google.gerrit.common.data.GroupReference; | import com.google.gerrit.common.data.GroupReference; | ||||||
|  | import com.google.gerrit.reviewdb.client.Project; | ||||||
| import com.google.gwt.editor.client.LeafValueEditor; | import com.google.gwt.editor.client.LeafValueEditor; | ||||||
| import com.google.gwt.event.dom.client.KeyCodes; | import com.google.gwt.event.dom.client.KeyCodes; | ||||||
| import com.google.gwt.event.dom.client.KeyPressEvent; | import com.google.gwt.event.dom.client.KeyPressEvent; | ||||||
| @@ -140,4 +141,8 @@ public class GroupReferenceBox extends Composite implements | |||||||
|   public void setAccessKey(char key) { |   public void setAccessKey(char key) { | ||||||
|     suggestBox.setAccessKey(key); |     suggestBox.setAccessKey(key); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public void setProject(Project.NameKey projectName) { | ||||||
|  |     oracle.setProject(projectName); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import com.google.gerrit.common.data.Permission; | |||||||
| import com.google.gerrit.common.data.PermissionRange; | import com.google.gerrit.common.data.PermissionRange; | ||||||
| import com.google.gerrit.common.data.PermissionRule; | import com.google.gerrit.common.data.PermissionRule; | ||||||
| import com.google.gerrit.common.data.RefConfigSection; | import com.google.gerrit.common.data.RefConfigSection; | ||||||
|  | import com.google.gerrit.reviewdb.client.Project; | ||||||
| import com.google.gwt.core.client.GWT; | import com.google.gwt.core.client.GWT; | ||||||
| import com.google.gwt.core.client.Scheduler; | import com.google.gwt.core.client.Scheduler; | ||||||
| import com.google.gwt.core.client.Scheduler.ScheduledCommand; | import com.google.gwt.core.client.Scheduler.ScheduledCommand; | ||||||
| @@ -98,20 +99,25 @@ public class PermissionEditor extends Composite implements Editor<Permission>, | |||||||
|   @UiField |   @UiField | ||||||
|   DivElement deleted; |   DivElement deleted; | ||||||
|  |  | ||||||
|  |   private final Project.NameKey projectName; | ||||||
|   private final boolean readOnly; |   private final boolean readOnly; | ||||||
|   private final AccessSection section; |   private final AccessSection section; | ||||||
|   private Permission value; |   private Permission value; | ||||||
|   private PermissionRange.WithDefaults validRange; |   private PermissionRange.WithDefaults validRange; | ||||||
|   private boolean isDeleted; |   private boolean isDeleted; | ||||||
|  |  | ||||||
|   public PermissionEditor(boolean readOnly, AccessSection section) { |   public PermissionEditor(Project.NameKey projectName, | ||||||
|  |       boolean readOnly, | ||||||
|  |       AccessSection section) { | ||||||
|     this.readOnly = readOnly; |     this.readOnly = readOnly; | ||||||
|     this.section = section; |     this.section = section; | ||||||
|  |     this.projectName = projectName; | ||||||
|  |  | ||||||
|     normalName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE); |     normalName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE); | ||||||
|     deletedName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE); |     deletedName = new ValueLabel<String>(PermissionNameRenderer.INSTANCE); | ||||||
|  |  | ||||||
|     initWidget(uiBinder.createAndBindUi(this)); |     initWidget(uiBinder.createAndBindUi(this)); | ||||||
|  |     groupToAdd.setProject(projectName); | ||||||
|     rules = ListEditor.of(new RuleEditorSource()); |     rules = ListEditor.of(new RuleEditorSource()); | ||||||
|  |  | ||||||
|     exclusiveGroup.setEnabled(!readOnly); |     exclusiveGroup.setEnabled(!readOnly); | ||||||
| @@ -223,7 +229,8 @@ public class PermissionEditor extends Composite implements Editor<Permission>, | |||||||
|       // If the oracle didn't get to complete a UUID, resolve it now. |       // If the oracle didn't get to complete a UUID, resolve it now. | ||||||
|       // |       // | ||||||
|       addRule.setEnabled(false); |       addRule.setEnabled(false); | ||||||
|       SuggestUtil.SVC.suggestAccountGroup(ref.getName(), 1, |       SuggestUtil.SVC.suggestAccountGroupForProject( | ||||||
|  |           projectName, ref.getName(), 1, | ||||||
|           new GerritCallback<List<GroupReference>>() { |           new GerritCallback<List<GroupReference>>() { | ||||||
|             @Override |             @Override | ||||||
|             public void onSuccess(List<GroupReference> result) { |             public void onSuccess(List<GroupReference> result) { | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import com.google.gerrit.client.RpcStatus; | |||||||
| import com.google.gerrit.client.rpc.GerritCallback; | import com.google.gerrit.client.rpc.GerritCallback; | ||||||
| import com.google.gerrit.common.data.GroupReference; | import com.google.gerrit.common.data.GroupReference; | ||||||
| import com.google.gerrit.reviewdb.client.AccountGroup; | import com.google.gerrit.reviewdb.client.AccountGroup; | ||||||
|  | import com.google.gerrit.reviewdb.client.Project; | ||||||
| import com.google.gwt.user.client.ui.SuggestOracle; | import com.google.gwt.user.client.ui.SuggestOracle; | ||||||
| import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle; | import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle; | ||||||
|  |  | ||||||
| @@ -31,11 +32,14 @@ public class AccountGroupSuggestOracle extends HighlightSuggestOracle { | |||||||
|   private Map<String, AccountGroup.UUID> priorResults = |   private Map<String, AccountGroup.UUID> priorResults = | ||||||
|       new HashMap<String, AccountGroup.UUID>(); |       new HashMap<String, AccountGroup.UUID>(); | ||||||
|  |  | ||||||
|  |   private Project.NameKey projectName; | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void onRequestSuggestions(final Request req, final Callback callback) { |   public void onRequestSuggestions(final Request req, final Callback callback) { | ||||||
|     RpcStatus.hide(new Runnable() { |     RpcStatus.hide(new Runnable() { | ||||||
|       public void run() { |       public void run() { | ||||||
|         SuggestUtil.SVC.suggestAccountGroup(req.getQuery(), req.getLimit(), |         SuggestUtil.SVC.suggestAccountGroupForProject( | ||||||
|  |             projectName, req.getQuery(), req.getLimit(), | ||||||
|             new GerritCallback<List<GroupReference>>() { |             new GerritCallback<List<GroupReference>>() { | ||||||
|               public void onSuccess(final List<GroupReference> result) { |               public void onSuccess(final List<GroupReference> result) { | ||||||
|                 priorResults.clear(); |                 priorResults.clear(); | ||||||
| @@ -52,6 +56,10 @@ public class AccountGroupSuggestOracle extends HighlightSuggestOracle { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public void setProject(Project.NameKey projectName) { | ||||||
|  |     this.projectName = projectName; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   private static class AccountGroupSuggestion implements |   private static class AccountGroupSuggestion implements | ||||||
|       SuggestOracle.Suggestion { |       SuggestOracle.Suggestion { | ||||||
|     private final GroupReference info; |     private final GroupReference info; | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ import com.google.gerrit.server.account.AccountCache; | |||||||
| import com.google.gerrit.server.account.AccountControl; | import com.google.gerrit.server.account.AccountControl; | ||||||
| import com.google.gerrit.server.account.AccountVisibility; | import com.google.gerrit.server.account.AccountVisibility; | ||||||
| import com.google.gerrit.server.account.GroupBackend; | import com.google.gerrit.server.account.GroupBackend; | ||||||
|  | import com.google.gerrit.server.account.GroupBackends; | ||||||
| import com.google.gerrit.server.account.GroupControl; | import com.google.gerrit.server.account.GroupControl; | ||||||
| import com.google.gerrit.server.account.GroupMembers; | import com.google.gerrit.server.account.GroupMembers; | ||||||
| import com.google.gerrit.server.config.GerritServerConfig; | import com.google.gerrit.server.config.GerritServerConfig; | ||||||
| @@ -38,6 +39,7 @@ import com.google.gerrit.server.patch.AddReviewer; | |||||||
| import com.google.gerrit.server.project.ChangeControl; | import com.google.gerrit.server.project.ChangeControl; | ||||||
| import com.google.gerrit.server.project.NoSuchChangeException; | import com.google.gerrit.server.project.NoSuchChangeException; | ||||||
| import com.google.gerrit.server.project.NoSuchProjectException; | import com.google.gerrit.server.project.NoSuchProjectException; | ||||||
|  | import com.google.gerrit.server.project.ProjectControl; | ||||||
| import com.google.gwtjsonrpc.common.AsyncCallback; | import com.google.gwtjsonrpc.common.AsyncCallback; | ||||||
| import com.google.gwtorm.server.OrmException; | import com.google.gwtorm.server.OrmException; | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
| @@ -52,6 +54,8 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
|  | import javax.annotation.Nullable; | ||||||
|  |  | ||||||
| class SuggestServiceImpl extends BaseServiceImplementation implements | class SuggestServiceImpl extends BaseServiceImplementation implements | ||||||
|     SuggestService { |     SuggestService { | ||||||
|   private static final String MAX_SUFFIX = "\u9fa5"; |   private static final String MAX_SUFFIX = "\u9fa5"; | ||||||
| @@ -63,6 +67,7 @@ class SuggestServiceImpl extends BaseServiceImplementation implements | |||||||
|   private final IdentifiedUser.GenericFactory identifiedUserFactory; |   private final IdentifiedUser.GenericFactory identifiedUserFactory; | ||||||
|   private final AccountControl.Factory accountControlFactory; |   private final AccountControl.Factory accountControlFactory; | ||||||
|   private final ChangeControl.Factory changeControlFactory; |   private final ChangeControl.Factory changeControlFactory; | ||||||
|  |   private final ProjectControl.Factory projectControlFactory; | ||||||
|   private final Config cfg; |   private final Config cfg; | ||||||
|   private final GroupBackend groupBackend; |   private final GroupBackend groupBackend; | ||||||
|   private final boolean suggestAccounts; |   private final boolean suggestAccounts; | ||||||
| @@ -76,6 +81,7 @@ class SuggestServiceImpl extends BaseServiceImplementation implements | |||||||
|       final IdentifiedUser.GenericFactory identifiedUserFactory, |       final IdentifiedUser.GenericFactory identifiedUserFactory, | ||||||
|       final AccountControl.Factory accountControlFactory, |       final AccountControl.Factory accountControlFactory, | ||||||
|       final ChangeControl.Factory changeControlFactory, |       final ChangeControl.Factory changeControlFactory, | ||||||
|  |       final ProjectControl.Factory projectControlFactory, | ||||||
|       @GerritServerConfig final Config cfg, final GroupBackend groupBackend) { |       @GerritServerConfig final Config cfg, final GroupBackend groupBackend) { | ||||||
|     super(schema, currentUser); |     super(schema, currentUser); | ||||||
|     this.reviewDbProvider = schema; |     this.reviewDbProvider = schema; | ||||||
| @@ -85,6 +91,7 @@ class SuggestServiceImpl extends BaseServiceImplementation implements | |||||||
|     this.identifiedUserFactory = identifiedUserFactory; |     this.identifiedUserFactory = identifiedUserFactory; | ||||||
|     this.accountControlFactory = accountControlFactory; |     this.accountControlFactory = accountControlFactory; | ||||||
|     this.changeControlFactory = changeControlFactory; |     this.changeControlFactory = changeControlFactory; | ||||||
|  |     this.projectControlFactory = projectControlFactory; | ||||||
|     this.cfg = cfg; |     this.cfg = cfg; | ||||||
|     this.groupBackend = groupBackend; |     this.groupBackend = groupBackend; | ||||||
|  |  | ||||||
| @@ -175,19 +182,37 @@ class SuggestServiceImpl extends BaseServiceImplementation implements | |||||||
|  |  | ||||||
|   public void suggestAccountGroup(final String query, final int limit, |   public void suggestAccountGroup(final String query, final int limit, | ||||||
|       final AsyncCallback<List<GroupReference>> callback) { |       final AsyncCallback<List<GroupReference>> callback) { | ||||||
|  |     suggestAccountGroupForProject(null, query, limit, callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public void suggestAccountGroupForProject(final Project.NameKey project, | ||||||
|  |       final String query, final int limit, | ||||||
|  |       final AsyncCallback<List<GroupReference>> callback) { | ||||||
|     run(callback, new Action<List<GroupReference>>() { |     run(callback, new Action<List<GroupReference>>() { | ||||||
|       public List<GroupReference> run(final ReviewDb db) { |       public List<GroupReference> run(final ReviewDb db) { | ||||||
|         return suggestAccountGroup(query, limit); |         ProjectControl projectControl = null; | ||||||
|  |         if (project != null) { | ||||||
|  |           try { | ||||||
|  |             projectControl = projectControlFactory.controlFor(project); | ||||||
|  |           } catch (NoSuchProjectException e) { | ||||||
|  |             return Collections.emptyList(); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         return suggestAccountGroup(projectControl, query, limit); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private List<GroupReference> suggestAccountGroup(final String query, final int limit) { |   private List<GroupReference> suggestAccountGroup( | ||||||
|  |       @Nullable final ProjectControl projectControl, final String query, final int limit) { | ||||||
|     final int n = limit <= 0 ? 10 : Math.min(limit, 10); |     final int n = limit <= 0 ? 10 : Math.min(limit, 10); | ||||||
|     List<GroupReference> out = Lists.newArrayListWithCapacity(n); |     List<GroupReference> out = Lists.newArrayListWithCapacity(n); | ||||||
|     for (GroupReference g : groupBackend.suggest(query)) { |     for (GroupReference g : groupBackend.suggest(query)) { | ||||||
|       try { |       try { | ||||||
|         if (groupControlFactory.controlFor(g.getUUID()).isVisible()) { |         if (groupControlFactory.controlFor(g.getUUID()).isVisible() | ||||||
|  |             || (GroupBackends.isExactSuggestion(g, query) | ||||||
|  |                 && projectControl != null | ||||||
|  |                 && projectControl.isOwnerAnyRef())) { | ||||||
|           out.add(g); |           out.add(g); | ||||||
|           if (out.size() == n) { |           if (out.size() == n) { | ||||||
|             break; |             break; | ||||||
| @@ -238,7 +263,7 @@ class SuggestServiceImpl extends BaseServiceImplementation implements | |||||||
|           reviewer.add(new ReviewerInfo(a)); |           reviewer.add(new ReviewerInfo(a)); | ||||||
|         } |         } | ||||||
|         final List<GroupReference> suggestedAccountGroups = |         final List<GroupReference> suggestedAccountGroups = | ||||||
|             suggestAccountGroup(query, limit); |             suggestAccountGroup(changeControl.getProjectControl(), query, limit); | ||||||
|         for (final GroupReference g : suggestedAccountGroups) { |         for (final GroupReference g : suggestedAccountGroups) { | ||||||
|           if (suggestGroupAsReviewer(changeControl.getProject().getNameKey(), g)) { |           if (suggestGroupAsReviewer(changeControl.getProject().getNameKey(), g)) { | ||||||
|             reviewer.add(new ReviewerInfo(g)); |             reviewer.add(new ReviewerInfo(g)); | ||||||
|   | |||||||
| @@ -144,7 +144,7 @@ public class LdapGroupBackend implements GroupBackend { | |||||||
|  |  | ||||||
|       @Override |       @Override | ||||||
|       public boolean isVisibleToAll() { |       public boolean isVisibleToAll() { | ||||||
|         return true; |         return false; | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Colby Ranger
					Colby Ranger