Add REST endpoint to retrieve groups
The '/groups/' REST endpoint lists the groups accessible by the caller. This is the same as using the ls-groups command over SSH, and accepts the same options as query parameters. Information for a certain group can be accessed by '/groups/uuid-<group-uuid>' or '/groups/<group-id>'. Change-Id: I8c21cd1618bdf593ebff7e55f25f31f1e32ae9c1 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
@@ -243,6 +243,78 @@ To retrieve only the default dashboard, add `default` to the URL:
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[[groups]]
|
||||||
|
/groups/ (List Groups)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Lists the groups accessible by the caller. This is the same as
|
||||||
|
using the link:cmd-ls-groups.html[ls-groups] command over SSH,
|
||||||
|
and accepts the same options as query parameters.
|
||||||
|
|
||||||
|
----
|
||||||
|
GET /groups/ HTTP/1.0
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Disposition: attachment
|
||||||
|
Content-Type: application/json;charset=UTF-8
|
||||||
|
|
||||||
|
)]}'
|
||||||
|
{
|
||||||
|
"Administrators": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-6a1e70e1a88782771a91808c8af9bbb7a9871389",
|
||||||
|
"uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389",
|
||||||
|
"group_id": 1,
|
||||||
|
"description": "Gerrit Site Administrators",
|
||||||
|
"is_visible_to_all": false,
|
||||||
|
"owner_uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389"
|
||||||
|
},
|
||||||
|
"Anonymous Users": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-global%3AAnonymous-Users",
|
||||||
|
"uuid": "global:Anonymous-Users",
|
||||||
|
"group_id": 2,
|
||||||
|
"description": "Any user, signed-in or not",
|
||||||
|
"is_visible_to_all": false,
|
||||||
|
"owner_uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389"
|
||||||
|
},
|
||||||
|
"MyProject_Committers": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-834ec36dd5e0ed21a2ff5d7e2255da082d63bbd7",
|
||||||
|
"uuid": "834ec36dd5e0ed21a2ff5d7e2255da082d63bbd7",
|
||||||
|
"group_id": 6,
|
||||||
|
"is_visible_to_all": true,
|
||||||
|
"owner_uuid": "834ec36dd5e0ed21a2ff5d7e2255da082d63bbd7"
|
||||||
|
},
|
||||||
|
"Non-Interactive Users": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-5057f3cbd3519d6ab69364429a89ffdffba50f73",
|
||||||
|
"uuid": "5057f3cbd3519d6ab69364429a89ffdffba50f73",
|
||||||
|
"group_id": 4,
|
||||||
|
"description": "Users who perform batch actions on Gerrit",
|
||||||
|
"is_visible_to_all": false,
|
||||||
|
"owner_uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389"
|
||||||
|
},
|
||||||
|
"Project Owners": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-global%3AProject-Owners",
|
||||||
|
"uuid": "global:Project-Owners",
|
||||||
|
"group_id": 5,
|
||||||
|
"description": "Any owner of the project",
|
||||||
|
"is_visible_to_all": false,
|
||||||
|
"owner_uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389"
|
||||||
|
},
|
||||||
|
"Registered Users": {
|
||||||
|
"kind": "gerritcodereview#group",
|
||||||
|
"id": "uuid-global%3ARegistered-Users",
|
||||||
|
"uuid": "global:Registered-Users",
|
||||||
|
"group_id": 3,
|
||||||
|
"description": "Any signed-in user",
|
||||||
|
"is_visible_to_all": false,
|
||||||
|
"owner_uuid": "6a1e70e1a88782771a91808c8af9bbb7a9871389"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
[[changes]]
|
[[changes]]
|
||||||
/changes/ (Query Changes)
|
/changes/ (Query Changes)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.google.gerrit.httpd.raw.ToolServlet;
|
|||||||
import com.google.gerrit.httpd.rpc.account.AccountsRestApiServlet;
|
import com.google.gerrit.httpd.rpc.account.AccountsRestApiServlet;
|
||||||
import com.google.gerrit.httpd.rpc.change.ChangesRestApiServlet;
|
import com.google.gerrit.httpd.rpc.change.ChangesRestApiServlet;
|
||||||
import com.google.gerrit.httpd.rpc.change.DeprecatedChangeQueryServlet;
|
import com.google.gerrit.httpd.rpc.change.DeprecatedChangeQueryServlet;
|
||||||
|
import com.google.gerrit.httpd.rpc.group.GroupsRestApiServlet;
|
||||||
import com.google.gerrit.httpd.rpc.project.ProjectsRestApiServlet;
|
import com.google.gerrit.httpd.rpc.project.ProjectsRestApiServlet;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
@@ -97,6 +98,7 @@ class UrlModule extends ServletModule {
|
|||||||
filter("/a/*").through(RequireIdentifiedUserFilter.class);
|
filter("/a/*").through(RequireIdentifiedUserFilter.class);
|
||||||
serveRegex("^/(?:a/)?accounts/(.*)$").with(AccountsRestApiServlet.class);
|
serveRegex("^/(?:a/)?accounts/(.*)$").with(AccountsRestApiServlet.class);
|
||||||
serveRegex("^/(?:a/)?changes/(.*)$").with(ChangesRestApiServlet.class);
|
serveRegex("^/(?:a/)?changes/(.*)$").with(ChangesRestApiServlet.class);
|
||||||
|
serveRegex("^/(?:a/)?groups/(.*)?$").with(GroupsRestApiServlet.class);
|
||||||
serveRegex("^/(?:a/)?projects/(.*)?$").with(ProjectsRestApiServlet.class);
|
serveRegex("^/(?:a/)?projects/(.*)?$").with(ProjectsRestApiServlet.class);
|
||||||
|
|
||||||
if (cfg.deprecatedQuery) {
|
if (cfg.deprecatedQuery) {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// 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.httpd.rpc.group;
|
||||||
|
|
||||||
|
import com.google.gerrit.httpd.restapi.RestApiServlet;
|
||||||
|
import com.google.gerrit.server.group.GroupsCollection;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class GroupsRestApiServlet extends RestApiServlet {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GroupsRestApiServlet(RestApiServlet.Globals globals,
|
||||||
|
Provider<GroupsCollection> groups) {
|
||||||
|
super(globals, groups);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,6 +84,10 @@ public class GroupControl {
|
|||||||
this(who, GroupDescriptions.forAccountGroup(ag));
|
this(who, GroupDescriptions.forAccountGroup(ag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GroupDescription.Basic getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
public CurrentUser getCurrentUser() {
|
public CurrentUser getCurrentUser() {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import com.google.gerrit.server.account.IncludingGroupMembership;
|
|||||||
import com.google.gerrit.server.account.InternalGroupBackend;
|
import com.google.gerrit.server.account.InternalGroupBackend;
|
||||||
import com.google.gerrit.server.account.Realm;
|
import com.google.gerrit.server.account.Realm;
|
||||||
import com.google.gerrit.server.account.UniversalGroupBackend;
|
import com.google.gerrit.server.account.UniversalGroupBackend;
|
||||||
|
import com.google.gerrit.server.account.VisibleGroups;
|
||||||
import com.google.gerrit.server.auth.AuthBackend;
|
import com.google.gerrit.server.auth.AuthBackend;
|
||||||
import com.google.gerrit.server.auth.InternalAuthBackend;
|
import com.google.gerrit.server.auth.InternalAuthBackend;
|
||||||
import com.google.gerrit.server.auth.UniversalAuthBackend;
|
import com.google.gerrit.server.auth.UniversalAuthBackend;
|
||||||
@@ -151,6 +152,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
factory(CapabilityControl.Factory.class);
|
factory(CapabilityControl.Factory.class);
|
||||||
factory(ChangeQueryBuilder.Factory.class);
|
factory(ChangeQueryBuilder.Factory.class);
|
||||||
factory(GroupInfoCacheFactory.Factory.class);
|
factory(GroupInfoCacheFactory.Factory.class);
|
||||||
|
factory(VisibleGroups.Factory.class);
|
||||||
factory(InternalUser.Factory.class);
|
factory(InternalUser.Factory.class);
|
||||||
factory(ProjectNode.Factory.class);
|
factory(ProjectNode.Factory.class);
|
||||||
factory(ProjectState.Factory.class);
|
factory(ProjectState.Factory.class);
|
||||||
@@ -194,6 +196,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
install(new AuditModule());
|
install(new AuditModule());
|
||||||
install(new com.google.gerrit.server.account.Module());
|
install(new com.google.gerrit.server.account.Module());
|
||||||
install(new com.google.gerrit.server.change.Module());
|
install(new com.google.gerrit.server.change.Module());
|
||||||
|
install(new com.google.gerrit.server.group.Module());
|
||||||
install(new com.google.gerrit.server.project.Module());
|
install(new com.google.gerrit.server.project.Module());
|
||||||
|
|
||||||
bind(GitReferenceUpdated.class);
|
bind(GitReferenceUpdated.class);
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ public class GerritRequestModule extends FactoryModule {
|
|||||||
factory(MergeFailSender.Factory.class);
|
factory(MergeFailSender.Factory.class);
|
||||||
factory(PerformCreateGroup.Factory.class);
|
factory(PerformCreateGroup.Factory.class);
|
||||||
factory(PerformRenameGroup.Factory.class);
|
factory(PerformRenameGroup.Factory.class);
|
||||||
factory(VisibleGroups.Factory.class);
|
|
||||||
factory(GroupDetailFactory.Factory.class);
|
factory(GroupDetailFactory.Factory.class);
|
||||||
factory(GroupMembers.Factory.class);
|
factory(GroupMembers.Factory.class);
|
||||||
factory(CreateProject.Factory.class);
|
factory(CreateProject.Factory.class);
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// 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.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 {
|
||||||
|
GroupDescription.Basic group = resource.getControl().getGroup();
|
||||||
|
GroupInfo info = new GroupInfo();
|
||||||
|
info.name = resource.getName();
|
||||||
|
info.uuid = resource.getGroupUUID().get();
|
||||||
|
info.isVisibleToAll = group.isVisibleToAll();
|
||||||
|
if (group instanceof GroupDescription.Internal) {
|
||||||
|
final AccountGroup internalGroup =
|
||||||
|
((GroupDescription.Internal) group).getAccountGroup();
|
||||||
|
info.description = Strings.emptyToNull(internalGroup.getDescription());
|
||||||
|
info.ownerUuid = internalGroup.getOwnerGroupUUID().get();
|
||||||
|
}
|
||||||
|
info.finish();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class GroupInfo {
|
||||||
|
final String kind = "gerritcodereview#group";
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
String uuid;
|
||||||
|
String description;
|
||||||
|
boolean isVisibleToAll;
|
||||||
|
String ownerUuid;
|
||||||
|
|
||||||
|
void finish() {
|
||||||
|
id = Url.encode(GroupsCollection.UUID_PREFIX + uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// 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.gerrit.extensions.restapi.RestResource;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
public class GroupResource implements RestResource {
|
||||||
|
public static final TypeLiteral<RestView<GroupResource>> GROUP_KIND =
|
||||||
|
new TypeLiteral<RestView<GroupResource>>() {};
|
||||||
|
|
||||||
|
private final GroupControl control;
|
||||||
|
|
||||||
|
GroupResource(GroupControl control) {
|
||||||
|
this.control = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return control.getGroup().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountGroup.UUID getGroupUUID() {
|
||||||
|
return control.getGroup().getGroupUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupControl getControl() {
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
// 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.gerrit.common.errors.NoSuchGroupException;
|
||||||
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
|
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestCollection;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
|
import com.google.gerrit.extensions.restapi.TopLevelResource;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
|
import com.google.gerrit.server.AnonymousUser;
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
|
import com.google.gerrit.server.account.GroupControl;
|
||||||
|
import com.google.gerrit.server.util.Url;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
public class GroupsCollection implements
|
||||||
|
RestCollection<TopLevelResource, GroupResource> {
|
||||||
|
public final static String UUID_PREFIX = "uuid-";
|
||||||
|
|
||||||
|
private final DynamicMap<RestView<GroupResource>> views;
|
||||||
|
private final Provider<ListGroups> list;
|
||||||
|
private final GroupControl.Factory groupControlFactory;
|
||||||
|
private final Provider<CurrentUser> self;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GroupsCollection(final DynamicMap<RestView<GroupResource>> views,
|
||||||
|
final Provider<ListGroups> list,
|
||||||
|
final GroupControl.Factory groupControlFactory,
|
||||||
|
final Provider<CurrentUser> self) {
|
||||||
|
this.views = views;
|
||||||
|
this.list = list;
|
||||||
|
this.groupControlFactory = groupControlFactory;
|
||||||
|
this.self = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestView<TopLevelResource> list() throws ResourceNotFoundException,
|
||||||
|
AuthException {
|
||||||
|
final CurrentUser user = self.get();
|
||||||
|
if (user instanceof AnonymousUser) {
|
||||||
|
throw new AuthException("Authentication required");
|
||||||
|
} else if(!(user instanceof IdentifiedUser)) {
|
||||||
|
throw new ResourceNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupResource parse(TopLevelResource parent, String id)
|
||||||
|
throws ResourceNotFoundException, Exception {
|
||||||
|
final CurrentUser user = self.get();
|
||||||
|
if (user instanceof AnonymousUser) {
|
||||||
|
throw new AuthException("Authentication required");
|
||||||
|
} else if(!(user instanceof IdentifiedUser)) {
|
||||||
|
throw new ResourceNotFoundException(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String decodedId = Url.decode(id);
|
||||||
|
final GroupControl ctl;
|
||||||
|
try {
|
||||||
|
if (decodedId.startsWith(UUID_PREFIX)) {
|
||||||
|
final String uuid = decodedId.substring(UUID_PREFIX.length());
|
||||||
|
ctl = groupControlFactory.controlFor(new AccountGroup.UUID(uuid));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
ctl = groupControlFactory.controlFor(
|
||||||
|
new AccountGroup.Id(Integer.parseInt(decodedId)));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ResourceNotFoundException(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchGroupException e) {
|
||||||
|
throw new ResourceNotFoundException(id);
|
||||||
|
}
|
||||||
|
if (!ctl.isVisible() && !ctl.isOwner()) {
|
||||||
|
throw new ResourceNotFoundException(id);
|
||||||
|
}
|
||||||
|
return new GroupResource(ctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicMap<RestView<GroupResource>> views() {
|
||||||
|
return views;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
// 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.collect.Maps;
|
||||||
|
import com.google.gerrit.common.data.GroupList;
|
||||||
|
import com.google.gerrit.common.errors.NoSuchGroupException;
|
||||||
|
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.extensions.restapi.TopLevelResource;
|
||||||
|
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.OutputFormat;
|
||||||
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
|
import com.google.gerrit.server.account.VisibleGroups;
|
||||||
|
import com.google.gerrit.server.ioutil.ColumnFormatter;
|
||||||
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
|
import com.google.gerrit.server.util.Url;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gwtorm.client.KeyUtil;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import org.kohsuke.args4j.Option;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** List groups visible to the calling user. */
|
||||||
|
public class ListGroups implements RestReadView<TopLevelResource> {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
private final VisibleGroups.Factory visibleGroupsFactory;
|
||||||
|
private final IdentifiedUser.GenericFactory userFactory;
|
||||||
|
|
||||||
|
@Option(name = "--project", aliases = {"-p"},
|
||||||
|
usage = "projects for which the groups should be listed")
|
||||||
|
private final List<ProjectControl> projects = new ArrayList<ProjectControl>();
|
||||||
|
|
||||||
|
@Option(name = "--visible-to-all", usage = "to list only groups that are visible to all registered users")
|
||||||
|
private boolean visibleToAll;
|
||||||
|
|
||||||
|
@Option(name = "--type", usage = "type of group")
|
||||||
|
private AccountGroup.Type groupType;
|
||||||
|
|
||||||
|
@Option(name = "--user", aliases = {"-u"},
|
||||||
|
usage = "user for which the groups should be listed")
|
||||||
|
private Account.Id user;
|
||||||
|
|
||||||
|
@Option(name = "--verbose", aliases = {"-v"},
|
||||||
|
usage = "verbose output format with tab-separated columns for the " +
|
||||||
|
"group name, UUID, description, type, owner group name, " +
|
||||||
|
"owner group UUID, and whether the group is visible to all")
|
||||||
|
private boolean verboseOutput;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ListGroups(final GroupCache groupCache,
|
||||||
|
final VisibleGroups.Factory visibleGroupsFactory,
|
||||||
|
final IdentifiedUser.GenericFactory userFactory) {
|
||||||
|
this.groupCache = groupCache;
|
||||||
|
this.visibleGroupsFactory = visibleGroupsFactory;
|
||||||
|
this.userFactory = userFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account.Id getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProjectControl> getProjects() {
|
||||||
|
return projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object apply(TopLevelResource resource) throws AuthException,
|
||||||
|
BadRequestException, ResourceConflictException, Exception {
|
||||||
|
return display(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement display(OutputStream displayOutputStream)
|
||||||
|
throws NoSuchGroupException {
|
||||||
|
PrintWriter stdout = null;
|
||||||
|
if (displayOutputStream != null) {
|
||||||
|
try {
|
||||||
|
stdout = new PrintWriter(new BufferedWriter(
|
||||||
|
new OutputStreamWriter(displayOutputStream, "UTF-8")));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("JVM lacks UTF-8 encoding", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final VisibleGroups visibleGroups = visibleGroupsFactory.create();
|
||||||
|
visibleGroups.setOnlyVisibleToAll(visibleToAll);
|
||||||
|
visibleGroups.setGroupType(groupType);
|
||||||
|
final GroupList groupList;
|
||||||
|
if (!projects.isEmpty()) {
|
||||||
|
groupList = visibleGroups.get(projects);
|
||||||
|
} else if (user != null) {
|
||||||
|
groupList = visibleGroups.get(userFactory.create(user));
|
||||||
|
} else {
|
||||||
|
groupList = visibleGroups.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stdout == null) {
|
||||||
|
final Map<String, GroupInfo> output = Maps.newTreeMap();
|
||||||
|
for (final AccountGroup g : groupList.getGroups()) {
|
||||||
|
final GroupInfo info = new GroupInfo();
|
||||||
|
info.name = g.getName();
|
||||||
|
info.groupId = g.getId().get();
|
||||||
|
info.setUuid(g.getGroupUUID());
|
||||||
|
info.description = g.getDescription();
|
||||||
|
info.isVisibleToAll = g.isVisibleToAll();
|
||||||
|
info.ownerUuid = g.getOwnerGroupUUID().get();
|
||||||
|
output.put(info.name, info);
|
||||||
|
}
|
||||||
|
return OutputFormat.JSON.newGson().toJsonTree(output,
|
||||||
|
new TypeToken<Map<String, GroupInfo>>() {}.getType());
|
||||||
|
} else {
|
||||||
|
final ColumnFormatter formatter = new ColumnFormatter(stdout, '\t');
|
||||||
|
for (final AccountGroup g : groupList.getGroups()) {
|
||||||
|
formatter.addColumn(g.getName());
|
||||||
|
if (verboseOutput) {
|
||||||
|
formatter.addColumn(KeyUtil.decode(g.getGroupUUID().toString()));
|
||||||
|
formatter.addColumn(
|
||||||
|
g.getDescription() != null ? g.getDescription() : "");
|
||||||
|
formatter.addColumn(g.getType().toString());
|
||||||
|
final AccountGroup owningGroup =
|
||||||
|
groupCache.get(g.getOwnerGroupUUID());
|
||||||
|
formatter.addColumn(
|
||||||
|
owningGroup != null ? owningGroup.getName() : "n/a");
|
||||||
|
formatter.addColumn(KeyUtil.decode(g.getOwnerGroupUUID().toString()));
|
||||||
|
formatter.addColumn(Boolean.toString(g.isVisibleToAll()));
|
||||||
|
}
|
||||||
|
formatter.nextLine();
|
||||||
|
}
|
||||||
|
formatter.finish();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (stdout != null) {
|
||||||
|
stdout.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class GroupInfo {
|
||||||
|
final String kind = "gerritcodereview#group";
|
||||||
|
|
||||||
|
transient String name;
|
||||||
|
String id;
|
||||||
|
String uuid;
|
||||||
|
int groupId;
|
||||||
|
String description;
|
||||||
|
boolean isVisibleToAll;
|
||||||
|
String ownerUuid;
|
||||||
|
|
||||||
|
void setUuid(AccountGroup.UUID u) {
|
||||||
|
uuid = u.get();
|
||||||
|
id = Url.encode(GroupsCollection.UUID_PREFIX + uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// 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 static com.google.gerrit.server.group.GroupResource.GROUP_KIND;
|
||||||
|
|
||||||
|
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||||
|
import com.google.gerrit.extensions.restapi.RestApiModule;
|
||||||
|
|
||||||
|
public class Module extends RestApiModule {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(GroupsCollection.class);
|
||||||
|
|
||||||
|
DynamicMap.mapOf(binder(), GROUP_KIND);
|
||||||
|
|
||||||
|
get(GROUP_KIND).to(GetGroup.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,93 +14,27 @@
|
|||||||
|
|
||||||
package com.google.gerrit.sshd.commands;
|
package com.google.gerrit.sshd.commands;
|
||||||
|
|
||||||
import com.google.gerrit.common.data.GroupList;
|
import com.google.gerrit.server.group.ListGroups;
|
||||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
import com.google.gerrit.sshd.BaseCommand;
|
||||||
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.account.GroupCache;
|
|
||||||
import com.google.gerrit.server.account.VisibleGroups;
|
|
||||||
import com.google.gerrit.server.ioutil.ColumnFormatter;
|
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
|
||||||
import com.google.gerrit.sshd.SshCommand;
|
|
||||||
import com.google.gwtorm.client.KeyUtil;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
import org.kohsuke.args4j.Option;
|
import org.apache.sshd.server.Environment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
public class ListGroupsCommand extends BaseCommand {
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ListGroupsCommand extends SshCommand {
|
|
||||||
@Inject
|
@Inject
|
||||||
private GroupCache groupCache;
|
private ListGroups impl;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private VisibleGroups.Factory visibleGroupsFactory;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private IdentifiedUser.GenericFactory userFactory;
|
|
||||||
|
|
||||||
@Option(name = "--project", aliases = {"-p"},
|
|
||||||
usage = "projects for which the groups should be listed")
|
|
||||||
private final List<ProjectControl> projects = new ArrayList<ProjectControl>();
|
|
||||||
|
|
||||||
@Option(name = "--visible-to-all", usage = "to list only groups that are visible to all registered users")
|
|
||||||
private boolean visibleToAll;
|
|
||||||
|
|
||||||
@Option(name = "--type", usage = "type of group")
|
|
||||||
private AccountGroup.Type groupType;
|
|
||||||
|
|
||||||
@Option(name = "--user", aliases = {"-u"},
|
|
||||||
usage = "user for which the groups should be listed")
|
|
||||||
private Account.Id user;
|
|
||||||
|
|
||||||
@Option(name = "--verbose", aliases = {"-v"},
|
|
||||||
usage = "verbose output format with tab-separated columns for the " +
|
|
||||||
"group name, UUID, description, type, owner group name, " +
|
|
||||||
"owner group UUID, and whether the group is visible to all")
|
|
||||||
private boolean verboseOutput;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws Failure {
|
public void start(final Environment env) {
|
||||||
try {
|
startThread(new CommandRunnable() {
|
||||||
if (user != null && !projects.isEmpty()) {
|
@Override
|
||||||
throw new UnloggedFailure(1, "fatal: --user and --project options are not compatible.");
|
public void run() throws Exception {
|
||||||
}
|
parseCommandLine(impl);
|
||||||
|
if (impl.getUser() != null && !impl.getProjects().isEmpty()) {
|
||||||
final VisibleGroups visibleGroups = visibleGroupsFactory.create();
|
throw new UnloggedFailure(1, "fatal: --user and --project options are not compatible.");
|
||||||
visibleGroups.setOnlyVisibleToAll(visibleToAll);
|
|
||||||
visibleGroups.setGroupType(groupType);
|
|
||||||
final GroupList groupList;
|
|
||||||
if (!projects.isEmpty()) {
|
|
||||||
groupList = visibleGroups.get(projects);
|
|
||||||
} else if (user != null) {
|
|
||||||
groupList = visibleGroups.get(userFactory.create(user));
|
|
||||||
} else {
|
|
||||||
groupList = visibleGroups.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ColumnFormatter formatter = new ColumnFormatter(stdout, '\t');
|
|
||||||
for (final AccountGroup g : groupList.getGroups()) {
|
|
||||||
formatter.addColumn(g.getName());
|
|
||||||
if (verboseOutput) {
|
|
||||||
formatter.addColumn(KeyUtil.decode(g.getGroupUUID().toString()));
|
|
||||||
formatter.addColumn(
|
|
||||||
g.getDescription() != null ? g.getDescription() : "");
|
|
||||||
formatter.addColumn(g.getType().toString());
|
|
||||||
final AccountGroup owningGroup =
|
|
||||||
groupCache.get(g.getOwnerGroupUUID());
|
|
||||||
formatter.addColumn(
|
|
||||||
owningGroup != null ? owningGroup.getName() : "n/a");
|
|
||||||
formatter.addColumn(KeyUtil.decode(g.getOwnerGroupUUID().toString()));
|
|
||||||
formatter.addColumn(Boolean.toString(g.isVisibleToAll()));
|
|
||||||
}
|
}
|
||||||
formatter.nextLine();
|
impl.display(out);
|
||||||
}
|
}
|
||||||
formatter.finish();
|
});
|
||||||
} catch (NoSuchGroupException e) {
|
|
||||||
throw die(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user