From e04a97ffd22d2dbc39329ad9fe8e6c85daf8b99c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 3 Sep 2009 11:36:49 -0700 Subject: [PATCH] Allow users to see what groups they are members of Knowing what groups a user is in may help a site administrator debug a specific user's access problems, and it may also help a project owner to decide which group they want to give out some access for. Bug: GERRIT-276 Change-Id: Ic06d8d5ba9d96354e47e8eda751c40b1fc360374 Signed-off-by: Shawn O. Pearce --- .../java/com/google/gerrit/client/Link.java | 1 + .../client/account/AccountConstants.java | 1 + .../account/AccountConstants.properties | 1 + .../client/account/AccountSecurity.java | 4 ++ .../client/account/AccountSettings.java | 8 +++ .../gerrit/client/account/MyGroupsPanel.java | 50 ++++++++++++++++ .../gerrit/client/admin/GroupListScreen.java | 2 +- .../gerrit/client/admin/GroupTable.java | 18 ++++-- .../server/rpc/account/AccountModule.java | 1 + .../rpc/account/AccountSecurityImpl.java | 11 +++- .../server/rpc/account/MyGroupsFactory.java | 59 +++++++++++++++++++ 11 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/google/gerrit/client/account/MyGroupsPanel.java create mode 100644 src/main/java/com/google/gerrit/server/rpc/account/MyGroupsFactory.java diff --git a/src/main/java/com/google/gerrit/client/Link.java b/src/main/java/com/google/gerrit/client/Link.java index 5c814d2fef..b586691702 100644 --- a/src/main/java/com/google/gerrit/client/Link.java +++ b/src/main/java/com/google/gerrit/client/Link.java @@ -51,6 +51,7 @@ public class Link implements ValueChangeHandler { public static final String SETTINGS = "settings"; public static final String SETTINGS_SSHKEYS = "settings,ssh-keys"; public static final String SETTINGS_WEBIDENT = "settings,web-identities"; + public static final String SETTINGS_MYGROUPS = "settings,group-memberships"; public static final String SETTINGS_AGREEMENTS = "settings,agreements"; public static final String SETTINGS_CONTACT = "settings,contact"; public static final String SETTINGS_PROJECTS = "settings,projects"; diff --git a/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/src/main/java/com/google/gerrit/client/account/AccountConstants.java index 6e00d31fb3..1dc2a62622 100644 --- a/src/main/java/com/google/gerrit/client/account/AccountConstants.java +++ b/src/main/java/com/google/gerrit/client/account/AccountConstants.java @@ -35,6 +35,7 @@ public interface AccountConstants extends Constants { String tabContactInformation(); String tabSshKeys(); String tabWebIdentities(); + String tabMyGroups(); String tabAgreements(); String buttonShowAddSshKey(); diff --git a/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/src/main/java/com/google/gerrit/client/account/AccountConstants.properties index bca0b69c39..b76a0aa084 100644 --- a/src/main/java/com/google/gerrit/client/account/AccountConstants.properties +++ b/src/main/java/com/google/gerrit/client/account/AccountConstants.properties @@ -15,6 +15,7 @@ tabPreferences = Preferences tabContactInformation = Contact Information tabSshKeys = SSH Keys tabWebIdentities = Identities +tabMyGroups = Groups tabAgreements = Agreements buttonShowAddSshKey = Add Key ... diff --git a/src/main/java/com/google/gerrit/client/account/AccountSecurity.java b/src/main/java/com/google/gerrit/client/account/AccountSecurity.java index f1ac0ef675..83bcb840a6 100644 --- a/src/main/java/com/google/gerrit/client/account/AccountSecurity.java +++ b/src/main/java/com/google/gerrit/client/account/AccountSecurity.java @@ -16,6 +16,7 @@ package com.google.gerrit.client.account; import com.google.gerrit.client.reviewdb.Account; import com.google.gerrit.client.reviewdb.AccountExternalId; +import com.google.gerrit.client.reviewdb.AccountGroup; import com.google.gerrit.client.reviewdb.AccountSshKey; import com.google.gerrit.client.reviewdb.ContactInformation; import com.google.gerrit.client.reviewdb.ContributorAgreement; @@ -44,6 +45,9 @@ public interface AccountSecurity extends RemoteJsonService { @SignInRequired void myExternalIds(AsyncCallback> callback); + @SignInRequired + void myGroups(AsyncCallback> callback); + @SignInRequired void deleteExternalIds(Set keys, AsyncCallback> callback); diff --git a/src/main/java/com/google/gerrit/client/account/AccountSettings.java b/src/main/java/com/google/gerrit/client/account/AccountSettings.java index 56e4348f8a..718e0b604a 100644 --- a/src/main/java/com/google/gerrit/client/account/AccountSettings.java +++ b/src/main/java/com/google/gerrit/client/account/AccountSettings.java @@ -128,6 +128,14 @@ public class AccountSettings extends AccountScreen { }, Util.C.tabWebIdentities()); tabTokens.add(Link.SETTINGS_WEBIDENT); + tabs.add(new LazyPanel() { + @Override + protected MyGroupsPanel createWidget() { + return new MyGroupsPanel(); + } + }, Util.C.tabMyGroups()); + tabTokens.add(Link.SETTINGS_MYGROUPS); + if (Gerrit.getConfig().isUseContributorAgreements()) { tabs.add(new LazyPanel() { @Override diff --git a/src/main/java/com/google/gerrit/client/account/MyGroupsPanel.java b/src/main/java/com/google/gerrit/client/account/MyGroupsPanel.java new file mode 100644 index 0000000000..6e7e32bb8c --- /dev/null +++ b/src/main/java/com/google/gerrit/client/account/MyGroupsPanel.java @@ -0,0 +1,50 @@ +// Copyright (C) 2009 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.client.account; + +import com.google.gerrit.client.admin.GroupTable; +import com.google.gerrit.client.reviewdb.AccountGroup; +import com.google.gerrit.client.rpc.GerritCallback; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; + +import java.util.List; + +class MyGroupsPanel extends Composite { + private GroupTable groups; + + MyGroupsPanel() { + final FlowPanel body = new FlowPanel(); + + groups = new GroupTable(false /* do not hyperlink to admin */); + body.add(groups); + + initWidget(body); + } + + @Override + protected void onLoad() { + super.onLoad(); + refresh(); + } + + private void refresh() { + Util.ACCOUNT_SEC.myGroups(new GerritCallback>() { + public void onSuccess(final List result) { + groups.display(result); + } + }); + } +} diff --git a/src/main/java/com/google/gerrit/client/admin/GroupListScreen.java b/src/main/java/com/google/gerrit/client/admin/GroupListScreen.java index 849975bc55..5bd5a87043 100644 --- a/src/main/java/com/google/gerrit/client/admin/GroupListScreen.java +++ b/src/main/java/com/google/gerrit/client/admin/GroupListScreen.java @@ -53,7 +53,7 @@ public class GroupListScreen extends AccountScreen { super.onInitUI(); setPageTitle(Util.C.groupListTitle()); - groups = new GroupTable(Link.ADMIN_GROUPS); + groups = new GroupTable(true /* hyperlink to admin */, Link.ADMIN_GROUPS); add(groups); final VerticalPanel fp = new VerticalPanel(); diff --git a/src/main/java/com/google/gerrit/client/admin/GroupTable.java b/src/main/java/com/google/gerrit/client/admin/GroupTable.java index 920424fbc2..613a4056af 100644 --- a/src/main/java/com/google/gerrit/client/admin/GroupTable.java +++ b/src/main/java/com/google/gerrit/client/admin/GroupTable.java @@ -29,11 +29,15 @@ import java.util.List; public class GroupTable extends NavigationTable { - public GroupTable() { - this(null); + private final boolean enableLink; + + public GroupTable(final boolean enableLink) { + this(enableLink, null); } - public GroupTable(final String pointerId) { + public GroupTable(final boolean enableLink, final String pointerId) { + this.enableLink = enableLink; + setSavePointerId(pointerId); keysNavigation.add(new PrevKeyCommand(0, 'k', Util.C.groupListPrev())); keysNavigation.add(new NextKeyCommand(0, 'j', Util.C.groupListNext())); @@ -82,8 +86,12 @@ public class GroupTable extends NavigationTable { } void populate(final int row, final AccountGroup k) { - table.setWidget(row, 1, new Hyperlink(k.getName(), Link.toAccountGroup(k - .getId()))); + if (enableLink) { + table.setWidget(row, 1, new Hyperlink(k.getName(), Link.toAccountGroup(k + .getId()))); + } else { + table.setText(row, 1, k.getName()); + } table.setText(row, 2, k.getDescription()); final FlexCellFormatter fmt = table.getFlexCellFormatter(); diff --git a/src/main/java/com/google/gerrit/server/rpc/account/AccountModule.java b/src/main/java/com/google/gerrit/server/rpc/account/AccountModule.java index 7ac9aa339c..ea56108688 100644 --- a/src/main/java/com/google/gerrit/server/rpc/account/AccountModule.java +++ b/src/main/java/com/google/gerrit/server/rpc/account/AccountModule.java @@ -31,6 +31,7 @@ public class AccountModule extends RpcServletModule { factory(AgreementInfoFactory.Factory.class); factory(ExternalIdDetailFactory.Factory.class); factory(GroupDetailFactory.Factory.class); + factory(MyGroupsFactory.Factory.class); } }); rpc(AccountSecurityImpl.class); diff --git a/src/main/java/com/google/gerrit/server/rpc/account/AccountSecurityImpl.java b/src/main/java/com/google/gerrit/server/rpc/account/AccountSecurityImpl.java index 6186a58c05..d9f4db8d93 100644 --- a/src/main/java/com/google/gerrit/server/rpc/account/AccountSecurityImpl.java +++ b/src/main/java/com/google/gerrit/server/rpc/account/AccountSecurityImpl.java @@ -18,6 +18,7 @@ import com.google.gerrit.client.account.AccountSecurity; import com.google.gerrit.client.reviewdb.Account; import com.google.gerrit.client.reviewdb.AccountAgreement; import com.google.gerrit.client.reviewdb.AccountExternalId; +import com.google.gerrit.client.reviewdb.AccountGroup; import com.google.gerrit.client.reviewdb.AccountSshKey; import com.google.gerrit.client.reviewdb.ContactInformation; import com.google.gerrit.client.reviewdb.ContributorAgreement; @@ -78,6 +79,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements private final boolean useContactInfo; private final ExternalIdDetailFactory.Factory externalIdDetailFactory; + private final MyGroupsFactory.Factory myGroupsFactory; @Inject AccountSecurityImpl(final Provider schema, @@ -86,7 +88,8 @@ class AccountSecurityImpl extends BaseServiceImplementation implements final RegisterNewEmailSender.Factory esf, final SshKeyCache skc, final AccountByEmailCache abec, final AccountCache uac, final AccountManager am, - final ExternalIdDetailFactory.Factory externalIdDetailFactory) { + final ExternalIdDetailFactory.Factory externalIdDetailFactory, + final MyGroupsFactory.Factory myGroupsFactory) { super(schema, currentUser); contactStore = cs; authConfig = ac; @@ -100,6 +103,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements useContactInfo = contactStore != null && contactStore.isEnabled(); this.externalIdDetailFactory = externalIdDetailFactory; + this.myGroupsFactory = myGroupsFactory; } public void mySshKeys(final AsyncCallback> callback) { @@ -220,6 +224,11 @@ class AccountSecurityImpl extends BaseServiceImplementation implements externalIdDetailFactory.create().to(callback); } + @Override + public void myGroups(final AsyncCallback> callback) { + myGroupsFactory.create().to(callback); + } + public void deleteExternalIds(final Set keys, final AsyncCallback> callback) { run(callback, new Action>() { diff --git a/src/main/java/com/google/gerrit/server/rpc/account/MyGroupsFactory.java b/src/main/java/com/google/gerrit/server/rpc/account/MyGroupsFactory.java new file mode 100644 index 0000000000..68574bc458 --- /dev/null +++ b/src/main/java/com/google/gerrit/server/rpc/account/MyGroupsFactory.java @@ -0,0 +1,59 @@ +// Copyright (C) 2009 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.server.rpc.account; + +import com.google.gerrit.client.reviewdb.AccountGroup; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.rpc.Handler; +import com.google.inject.Inject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +class MyGroupsFactory extends Handler> { + interface Factory { + MyGroupsFactory create(); + } + + private final GroupCache groupCache; + private final IdentifiedUser user; + + @Inject + MyGroupsFactory(final GroupCache groupCache, final IdentifiedUser user) { + this.groupCache = groupCache; + this.user = user; + } + + @Override + public List call() throws Exception { + final Set effective = user.getEffectiveGroups(); + final int cnt = effective.size(); + final List groupList = new ArrayList(cnt); + for (final AccountGroup.Id groupId : effective) { + groupList.add(groupCache.get(groupId)); + } + Collections.sort(groupList, new Comparator() { + @Override + public int compare(AccountGroup a, AccountGroup b) { + return a.getName().compareTo(b.getName()); + } + }); + return groupList; + } +}