GET /accounts/{id}/groups
Obtain the list of groups a target user is a member of from
within the user resource, rather than /groups/?user={id} query.
This is a different projection of essentially the same data,
but I think it makes sense to allow a user to ask for their
groups within their account.
A nice benefit is we can now ask /accounts/self/groups to see
our own groups at any time, whereas /groups/?user={id} does not
accept self as an argument.
Unlike /groups/?user={id} query any user can see a subset of
another user's groups if two things are true:
- The caller can see the other user.
Often true when both users have a group in common.
- The caller can see the group.
True when the caller is an owner of that group, or
the group is visible to everyone.
- The caller can see the members of the group.
True if the caller is an owner, or the group
is visible to everyone.
Change-Id: I43d43f2f774dafb1f77fd047b50b6fa050f82d07
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.client.admin.GroupTable;
|
||||
import com.google.gerrit.client.groups.GroupMap;
|
||||
import com.google.gerrit.client.groups.GroupList;
|
||||
import com.google.gerrit.client.rpc.ScreenLoadCallback;
|
||||
|
||||
public class MyGroupsScreen extends SettingsScreen {
|
||||
@@ -31,9 +31,9 @@ public class MyGroupsScreen extends SettingsScreen {
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
GroupMap.my(new ScreenLoadCallback<GroupMap>(this) {
|
||||
GroupList.my(new ScreenLoadCallback<GroupList>(this) {
|
||||
@Override
|
||||
protected void preDisplay(final GroupMap result) {
|
||||
protected void preDisplay(GroupList result) {
|
||||
groups.display(result);
|
||||
groups.finishDisplay();
|
||||
}});
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.google.gerrit.client.admin;
|
||||
import com.google.gerrit.client.Dispatcher;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.groups.GroupInfo;
|
||||
import com.google.gerrit.client.groups.GroupList;
|
||||
import com.google.gerrit.client.groups.GroupMap;
|
||||
import com.google.gerrit.client.ui.HighlightingInlineHyperlink;
|
||||
import com.google.gerrit.client.ui.NavigationTable;
|
||||
@@ -76,15 +77,18 @@ public class GroupTable extends NavigationTable<GroupInfo> {
|
||||
History.newItem(Dispatcher.toGroup(getRowItem(row).getGroupId()));
|
||||
}
|
||||
|
||||
public void display(final GroupMap groups) {
|
||||
display(groups, null);
|
||||
public void display(GroupMap groups, String toHighlight) {
|
||||
display(groups.values().asList(), toHighlight);
|
||||
}
|
||||
|
||||
public void display(final GroupMap groups, final String toHighlight) {
|
||||
public void display(GroupList groups) {
|
||||
display(groups.asList(), null);
|
||||
}
|
||||
|
||||
public void display(List<GroupInfo> list, String toHighlight) {
|
||||
while (1 < table.getRowCount())
|
||||
table.removeRow(table.getRowCount() - 1);
|
||||
|
||||
List<GroupInfo> list = groups.values().asList();
|
||||
Collections.sort(list, new Comparator<GroupInfo>() {
|
||||
@Override
|
||||
public int compare(GroupInfo a, GroupInfo b) {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2013 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.groups;
|
||||
|
||||
import com.google.gerrit.client.rpc.NativeList;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
|
||||
/** Groups available from {@code /groups/} or {@code /accounts/{id}/groups}. */
|
||||
public class GroupList extends NativeList<GroupInfo> {
|
||||
public static void my(AsyncCallback<GroupList> callback) {
|
||||
new RestApi("/accounts/self/groups").get(callback);
|
||||
}
|
||||
|
||||
protected GroupList() {
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package com.google.gerrit.client.groups;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.rpc.NativeMap;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
@@ -26,12 +25,6 @@ public class GroupMap extends NativeMap<GroupInfo> {
|
||||
.get(NativeMap.copyKeysIntoChildren(callback));
|
||||
}
|
||||
|
||||
public static void my(AsyncCallback<GroupMap> callback) {
|
||||
new RestApi("/groups/")
|
||||
.addParameter("user", Gerrit.getUserAccount().getId().get())
|
||||
.get(NativeMap.copyKeysIntoChildren(callback));
|
||||
}
|
||||
|
||||
public static void match(String match, AsyncCallback<GroupMap> cb) {
|
||||
if (match == null || "".equals(match)) {
|
||||
all(cb);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (C) 2013 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.account;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.group.GroupInfo;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class GetGroups implements RestReadView<AccountResource> {
|
||||
private final GroupControl.Factory groupControlFactory;
|
||||
|
||||
@Inject
|
||||
GetGroups(GroupControl.Factory groupControlFactory) {
|
||||
this.groupControlFactory = groupControlFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GroupInfo> apply(AccountResource resource) {
|
||||
IdentifiedUser user = resource.getUser();
|
||||
Account.Id userId = user.getAccountId();
|
||||
List<GroupInfo> groups = Lists.newArrayList();
|
||||
for (AccountGroup.UUID uuid : user.getEffectiveGroups().getKnownGroups()) {
|
||||
GroupControl ctl;
|
||||
try {
|
||||
ctl = groupControlFactory.controlFor(uuid);
|
||||
} catch (NoSuchGroupException e) {
|
||||
continue;
|
||||
}
|
||||
if (ctl.isVisible() && ctl.canSeeMember(userId)) {
|
||||
groups.add(new GroupInfo(ctl.getGroup()));
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ public class Module extends RestApiModule {
|
||||
DynamicMap.mapOf(binder(), CAPABILITY_KIND);
|
||||
|
||||
child(ACCOUNT_KIND, "capabilities").to(Capabilities.class);
|
||||
get(ACCOUNT_KIND, "groups").to(GetGroups.class);
|
||||
get(CAPABILITY_KIND).to(GetCapabilities.CheckOne.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,50 +14,15 @@
|
||||
|
||||
package com.google.gerrit.server.group;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.common.data.GroupDescription;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.util.Url;
|
||||
|
||||
class GetGroup implements RestReadView<GroupResource> {
|
||||
|
||||
@Override
|
||||
public Object apply(GroupResource resource) throws AuthException,
|
||||
BadRequestException, ResourceConflictException, Exception {
|
||||
return new GroupInfo(resource.getControl().getGroup());
|
||||
}
|
||||
|
||||
public static class GroupInfo {
|
||||
final String kind = "gerritcodereview#group";
|
||||
String id;
|
||||
String name;
|
||||
Boolean visibleToAll;
|
||||
|
||||
// These fields are only supplied for internal groups.
|
||||
String description;
|
||||
Integer groupId;
|
||||
String ownerId;
|
||||
|
||||
GroupInfo(GroupDescription.Basic group) {
|
||||
id = Url.encode(group.getGroupUUID().get());
|
||||
name = Strings.emptyToNull(group.getName());
|
||||
visibleToAll = group.isVisibleToAll() ? true : null;
|
||||
|
||||
if (group instanceof GroupDescription.Internal) {
|
||||
set(((GroupDescription.Internal) group).getAccountGroup());
|
||||
}
|
||||
}
|
||||
|
||||
private void set(AccountGroup d) {
|
||||
description = Strings.emptyToNull(d.getDescription());
|
||||
groupId = d.getId().get();
|
||||
ownerId = d.getOwnerGroupUUID() != null
|
||||
? Url.encode(d.getOwnerGroupUUID().get())
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
package com.google.gerrit.server.group;
|
||||
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.server.group.GetGroup.GroupInfo;
|
||||
|
||||
public class GetIncludedGroup implements RestReadView<IncludedGroupResource> {
|
||||
@Override
|
||||
public GroupInfo apply(IncludedGroupResource rsrc) {
|
||||
return new GetGroup.GroupInfo(rsrc.getGroup());
|
||||
return new GroupInfo(rsrc.getGroup());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2013 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.group;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.common.data.GroupDescription;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.util.Url;
|
||||
|
||||
public class GroupInfo {
|
||||
final String kind = "gerritcodereview#group";
|
||||
public String id;
|
||||
public String name;
|
||||
Boolean visibleToAll;
|
||||
|
||||
// These fields are only supplied for internal groups.
|
||||
String description;
|
||||
Integer groupId;
|
||||
String ownerId;
|
||||
|
||||
public GroupInfo(GroupDescription.Basic group) {
|
||||
id = Url.encode(group.getGroupUUID().get());
|
||||
name = Strings.emptyToNull(group.getName());
|
||||
visibleToAll = group.isVisibleToAll() ? true : null;
|
||||
|
||||
if (group instanceof GroupDescription.Internal) {
|
||||
set(((GroupDescription.Internal) group).getAccountGroup());
|
||||
}
|
||||
}
|
||||
|
||||
private void set(AccountGroup d) {
|
||||
description = Strings.emptyToNull(d.getDescription());
|
||||
groupId = d.getId().get();
|
||||
ownerId = d.getOwnerGroupUUID() != null
|
||||
? Url.encode(d.getOwnerGroupUUID().get())
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.OutputFormat;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.account.VisibleGroups;
|
||||
import com.google.gerrit.server.group.GetGroup.GroupInfo;
|
||||
import com.google.gerrit.server.ioutil.ColumnFormatter;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.account.GroupControl;
|
||||
import com.google.gerrit.server.group.GetGroup.GroupInfo;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
@@ -63,7 +62,7 @@ public class ListIncludedGroups implements RestReadView<GroupResource> {
|
||||
try {
|
||||
GroupControl i = controlFactory.controlFor(u.getIncludeUUID());
|
||||
if (ownerOfParent || i.isVisible()) {
|
||||
included.add(new GetGroup.GroupInfo(i.getGroup()));
|
||||
included.add(new GroupInfo(i.getGroup()));
|
||||
}
|
||||
} catch (NoSuchGroupException notFound) {
|
||||
log.warn(String.format("Group %s no longer available, included into ",
|
||||
|
||||
Reference in New Issue
Block a user