Merge "Added a ls-members command to the ssh daemon."
This commit is contained in:
@@ -60,6 +60,9 @@ link:cmd-ban-commit.html[gerrit ban-commit]::
|
||||
link:cmd-ls-groups.html[gerrit ls-groups]::
|
||||
List groups visible to the caller.
|
||||
|
||||
link:cmd-ls-members.html[gerrit ls-members]::
|
||||
List the membership of a group visible to the caller.
|
||||
|
||||
link:cmd-ls-projects.html[gerrit ls-projects]::
|
||||
List projects visible to the caller.
|
||||
|
||||
|
||||
64
Documentation/cmd-ls-members.txt
Normal file
64
Documentation/cmd-ls-members.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
gerrit ls-members
|
||||
================
|
||||
|
||||
NAME
|
||||
----
|
||||
gerrit ls-members - Show members of a given group
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'ssh' -p <port> <host> 'gerrit ls-members GROUPNAME'
|
||||
[--recursive]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Displays the members of the given group, one per line, so long as the given
|
||||
group is visible to the user. The users' id, username, full name and email are
|
||||
shown tab-separated.
|
||||
|
||||
ACCESS
|
||||
------
|
||||
Any user who has configured an SSH key.
|
||||
|
||||
SCRIPTING
|
||||
---------
|
||||
This command is intended to be used in scripts. Output is either an error
|
||||
message or a heading followed by zero or more lines, one for each member of the
|
||||
group. If any field is not set, or if the field is the user's full name and the
|
||||
name is empty, "n/a" is emitted as the field value.
|
||||
|
||||
All non-printable characters (ASCII value 31 or less) are escaped
|
||||
according to the conventions used in languages like C, Python, and Perl,
|
||||
employing standard sequences like `\n` and `\t`, and `\xNN` for all
|
||||
others. In shell scripts, the `printf` command can be used to unescape
|
||||
the output.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--recursive::
|
||||
If a member of the group is itself a group, the sub-group's
|
||||
members are included in the list. Otherwise members of any sub-group
|
||||
are not shown and no indication is given that a sub-group is present
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
List members of the Administrators group:
|
||||
=====
|
||||
$ ssh -p 29418 review.example.com gerrit ls-members Administrators
|
||||
id username full name email
|
||||
100000 jim Jim Bob somebody@example.com
|
||||
100001 johnny John Smith n/a
|
||||
100002 mrnoname n/a someoneelse@example.com
|
||||
=====
|
||||
|
||||
List members of a non-existent group:
|
||||
=====
|
||||
$ ssh -p 29418 review.example.com gerrit ls-members BadlySpelledGroup
|
||||
Group not found or not visible
|
||||
=====
|
||||
|
||||
GERRIT
|
||||
------
|
||||
Part of link:index.html[Gerrit Code Review]
|
||||
@@ -31,7 +31,8 @@ Returns an account as an link:#account-info[AccountInfo] entity.
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
}
|
||||
----
|
||||
|
||||
@@ -459,6 +460,8 @@ Only set if detailed account information is requested.
|
||||
|`email` |optional|
|
||||
The email address the user prefers to be contacted through. +
|
||||
Only set if detailed account information is requested.
|
||||
|`username` |optional|The username of the user. +
|
||||
Only set if detailed account information is requested.
|
||||
|===========================
|
||||
|
||||
[[account-input]]
|
||||
|
||||
@@ -293,12 +293,14 @@ describes the group.
|
||||
{
|
||||
"_account_id": 1000097,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com"
|
||||
"email": "jane.roe@example.com",
|
||||
"username": "jane"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"username": "john"
|
||||
}
|
||||
],
|
||||
"includes": []
|
||||
@@ -620,12 +622,14 @@ full name, preferred email and id.
|
||||
{
|
||||
"_account_id": 1000097,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com"
|
||||
"email": "jane.roe@example.com",
|
||||
"username": "jane"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -657,17 +661,20 @@ are not visible to the calling user are ignored.
|
||||
{
|
||||
"_account_id": 1000097,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com"
|
||||
"email": "jane.roe@example.com",
|
||||
"username": "jane"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000098,
|
||||
"name": "Richard Roe",
|
||||
"email": "richard.roe@example.com"
|
||||
"email": "richard.roe@example.com",
|
||||
"username": "rroe"
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -698,7 +705,8 @@ AccountInfo] entity is returned that describes the group member.
|
||||
{
|
||||
"_account_id": 1000096,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
}
|
||||
----
|
||||
|
||||
@@ -728,7 +736,8 @@ AccountInfo] entity is returned that describes the group member.
|
||||
{
|
||||
"_account_id": 1000037,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
}
|
||||
----
|
||||
|
||||
@@ -782,12 +791,14 @@ already a member of the group.
|
||||
{
|
||||
"_account_id": 1000057,
|
||||
"name": "Jane Roe",
|
||||
"email": "jane.roe@example.com"
|
||||
"email": "jane.roe@example.com",
|
||||
"username": "jane"
|
||||
},
|
||||
{
|
||||
"_account_id": 1000037,
|
||||
"name": "John Doe",
|
||||
"email": "john.doe@example.com"
|
||||
"email": "john.doe@example.com",
|
||||
"username": "john"
|
||||
}
|
||||
]
|
||||
----
|
||||
|
||||
@@ -112,12 +112,14 @@ public class AccountInfo {
|
||||
public Integer _account_id;
|
||||
public String name;
|
||||
public String email;
|
||||
public String username;
|
||||
|
||||
private void fill(Account account, boolean detailed) {
|
||||
name = account.getFullName();
|
||||
if (detailed) {
|
||||
_account_id = account.getId().get();
|
||||
email = account.getPreferredEmail();
|
||||
username = account.getUserName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ListMembers implements RestReadView<GroupResource> {
|
||||
private boolean recursive;
|
||||
|
||||
@Inject
|
||||
ListMembers(GroupCache groupCache,
|
||||
protected ListMembers(GroupCache groupCache,
|
||||
GroupDetailFactory.Factory groupDetailFactory,
|
||||
AccountInfo.Loader.Factory accountLoaderFactory) {
|
||||
this.groupCache = groupCache;
|
||||
@@ -63,8 +63,19 @@ public class ListMembers implements RestReadView<GroupResource> {
|
||||
if (resource.toAccountGroup() == null) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
|
||||
return apply(resource.getGroupUUID());
|
||||
}
|
||||
|
||||
public List<AccountInfo> apply(AccountGroup group)
|
||||
throws MethodNotAllowedException, OrmException {
|
||||
return apply(group.getGroupUUID());
|
||||
}
|
||||
|
||||
public List<AccountInfo> apply(AccountGroup.UUID groupId)
|
||||
throws MethodNotAllowedException, OrmException {
|
||||
final Map<Account.Id, AccountInfo> members =
|
||||
getMembers(resource.getGroupUUID(), new HashSet<AccountGroup.UUID>());
|
||||
getMembers(groupId, new HashSet<AccountGroup.UUID>());
|
||||
final List<AccountInfo> memberInfos = Lists.newArrayList(members.values());
|
||||
Collections.sort(memberInfos, new Comparator<AccountInfo>() {
|
||||
@Override
|
||||
|
||||
@@ -39,6 +39,7 @@ public class DefaultCommandModule extends CommandModule {
|
||||
command(gerrit, BanCommitCommand.class);
|
||||
command(gerrit, FlushCaches.class);
|
||||
command(gerrit, ListProjectsCommand.class);
|
||||
command(gerrit, ListMembersCommand.class);
|
||||
command(gerrit, ListGroupsCommand.class);
|
||||
command(gerrit, LsUserRefs.class);
|
||||
command(gerrit, Query.class);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// 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.sshd.commands;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.account.AccountCache;
|
||||
import com.google.gerrit.server.account.AccountInfo;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.account.GroupDetailFactory.Factory;
|
||||
import com.google.gerrit.server.group.ListMembers;
|
||||
import com.google.gerrit.server.ioutil.ColumnFormatter;
|
||||
import com.google.gerrit.sshd.BaseCommand;
|
||||
import com.google.gerrit.sshd.CommandMetaData;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import org.apache.sshd.server.Environment;
|
||||
import org.kohsuke.args4j.Argument;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Implements a command that allows the user to see the members of a group.
|
||||
*/
|
||||
@CommandMetaData(name = "ls-members", descr = "Lists the members of a given group")
|
||||
public class ListMembersCommand extends BaseCommand {
|
||||
@Inject
|
||||
ListMembersCommandImpl impl;
|
||||
|
||||
@Override
|
||||
public void start(Environment env) {
|
||||
startThread(new CommandRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
parseCommandLine(impl);
|
||||
final PrintWriter stdout = toPrintWriter(out);
|
||||
try {
|
||||
impl.display(stdout);
|
||||
} finally {
|
||||
stdout.flush();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ListMembersCommandImpl extends ListMembers {
|
||||
@Argument(required = true, usage = "the name of the group", metaVar = "GROUPNAME")
|
||||
private String name;
|
||||
|
||||
private final GroupCache groupCache;
|
||||
|
||||
@Inject
|
||||
protected ListMembersCommandImpl(GroupCache groupCache,
|
||||
Factory groupDetailFactory,
|
||||
AccountInfo.Loader.Factory accountLoaderFactory,
|
||||
AccountCache accountCache) {
|
||||
super(groupCache, groupDetailFactory, accountLoaderFactory);
|
||||
this.groupCache = groupCache;
|
||||
}
|
||||
|
||||
void display(PrintWriter writer) throws UnloggedFailure, OrmException {
|
||||
AccountGroup group = groupCache.get(new AccountGroup.NameKey(name));
|
||||
String errorText = "Group not found or not visible\n";
|
||||
|
||||
if (group == null) {
|
||||
writer.write(errorText);
|
||||
writer.flush();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
List<AccountInfo> members = apply(group.getGroupUUID());
|
||||
ColumnFormatter formatter = new ColumnFormatter(writer, '\t');
|
||||
formatter.addColumn("id");
|
||||
formatter.addColumn("username");
|
||||
formatter.addColumn("full name");
|
||||
formatter.addColumn("email");
|
||||
formatter.nextLine();
|
||||
for (AccountInfo member : members) {
|
||||
if (member == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
formatter.addColumn(member._id.toString());
|
||||
formatter.addColumn(Objects.firstNonNull(member.username, "n/a"));
|
||||
formatter.addColumn(Objects.firstNonNull(
|
||||
Strings.emptyToNull(member.name), "n/a"));
|
||||
formatter.addColumn(Objects.firstNonNull(member.email, "n/a"));
|
||||
formatter.nextLine();
|
||||
}
|
||||
|
||||
formatter.finish();
|
||||
} catch (MethodNotAllowedException e) {
|
||||
writer.write(errorText);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user