| // 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.Function; |
| import com.google.common.base.Joiner; |
| import com.google.common.base.MoreObjects; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.gerrit.extensions.restapi.IdString; |
| 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.account.AccountCache; |
| import com.google.gerrit.server.account.GroupCache; |
| import com.google.gerrit.server.group.AddIncludedGroups; |
| import com.google.gerrit.server.group.AddMembers; |
| import com.google.gerrit.server.group.DeleteIncludedGroups; |
| import com.google.gerrit.server.group.DeleteMembers; |
| import com.google.gerrit.server.group.GroupResource; |
| import com.google.gerrit.server.group.GroupsCollection; |
| import com.google.gerrit.sshd.CommandMetaData; |
| import com.google.gerrit.sshd.SshCommand; |
| import com.google.inject.Inject; |
| import com.google.inject.Provider; |
| |
| import org.kohsuke.args4j.Argument; |
| import org.kohsuke.args4j.Option; |
| |
| import java.io.IOException; |
| import java.io.UnsupportedEncodingException; |
| import java.util.List; |
| |
| @CommandMetaData(name = "set-members", description = "Modify members of specific group or number of groups") |
| public class SetMembersCommand extends SshCommand { |
| |
| @Option(name = "--add", aliases = {"-a"}, metaVar = "USER", usage = "users that should be added as group member") |
| private List<Account.Id> accountsToAdd = Lists.newArrayList(); |
| |
| @Option(name = "--remove", aliases = {"-r"}, metaVar = "USER", usage = "users that should be removed from the group") |
| private List<Account.Id> accountsToRemove = Lists.newArrayList(); |
| |
| @Option(name = "--include", aliases = {"-i"}, metaVar = "GROUP", usage = "group that should be included as group member") |
| private List<AccountGroup.UUID> groupsToInclude = Lists.newArrayList(); |
| |
| @Option(name = "--exclude", aliases = {"-e"}, metaVar = "GROUP", usage = "group that should be excluded from the group") |
| private List<AccountGroup.UUID> groupsToRemove = Lists.newArrayList(); |
| |
| @Argument(index = 0, required = true, multiValued = true, metaVar = "GROUP", usage = "groups to modify") |
| private List<AccountGroup.UUID> groups = Lists.newArrayList(); |
| |
| @Inject |
| private Provider<AddMembers> addMembers; |
| |
| @Inject |
| private Provider<DeleteMembers> deleteMembers; |
| |
| @Inject |
| private Provider<AddIncludedGroups> addIncludedGroups; |
| |
| @Inject |
| private Provider<DeleteIncludedGroups> deleteIncludedGroups; |
| |
| @Inject |
| private GroupsCollection groupsCollection; |
| |
| @Inject |
| private GroupCache groupCache; |
| |
| @Inject |
| private AccountCache accountCache; |
| |
| @Override |
| protected void run() throws UnloggedFailure, Failure, Exception { |
| for (AccountGroup.UUID groupUuid : groups) { |
| GroupResource resource = |
| groupsCollection.parse(TopLevelResource.INSTANCE, |
| IdString.fromUrl(groupUuid.get())); |
| if (!accountsToRemove.isEmpty()) { |
| deleteMembers.get().apply(resource, fromMembers(accountsToRemove)); |
| reportMembersAction("removed from", resource, accountsToRemove); |
| } |
| if (!groupsToRemove.isEmpty()) { |
| deleteIncludedGroups.get().apply(resource, fromGroups(groupsToRemove)); |
| reportGroupsAction("excluded from", resource, groupsToRemove); |
| } |
| if (!accountsToAdd.isEmpty()) { |
| addMembers.get().apply(resource, fromMembers(accountsToAdd)); |
| reportMembersAction("added to", resource, accountsToAdd); |
| } |
| if (!groupsToInclude.isEmpty()) { |
| addIncludedGroups.get().apply(resource, fromGroups(groupsToInclude)); |
| reportGroupsAction("included to", resource, groupsToInclude); |
| } |
| } |
| } |
| |
| private void reportMembersAction(String action, GroupResource group, |
| List<Account.Id> accountIdList) throws UnsupportedEncodingException, |
| IOException { |
| out.write(String.format( |
| "Members %s group %s: %s\n", |
| action, |
| group.getName(), |
| Joiner.on(", ").join( |
| Iterables.transform(accountIdList, |
| new Function<Account.Id, String>() { |
| @Override |
| public String apply(Account.Id accountId) { |
| return MoreObjects.firstNonNull(accountCache.get(accountId) |
| .getAccount().getPreferredEmail(), "n/a"); |
| } |
| }))).getBytes(ENC)); |
| } |
| |
| private void reportGroupsAction(String action, GroupResource group, |
| List<AccountGroup.UUID> groupUuidList) |
| throws UnsupportedEncodingException, IOException { |
| out.write(String.format( |
| "Groups %s group %s: %s\n", |
| action, |
| group.getName(), |
| Joiner.on(", ").join( |
| Iterables.transform(groupUuidList, |
| new Function<AccountGroup.UUID, String>() { |
| @Override |
| public String apply(AccountGroup.UUID uuid) { |
| return groupCache.get(uuid).getName(); |
| } |
| }))).getBytes(ENC)); |
| } |
| |
| private AddIncludedGroups.Input fromGroups(List<AccountGroup.UUID> accounts) { |
| return AddIncludedGroups.Input.fromGroups(Lists.newArrayList(Iterables |
| .transform(accounts, new Function<AccountGroup.UUID, String>() { |
| @Override |
| public String apply(AccountGroup.UUID uuid) { |
| return uuid.toString(); |
| } |
| }))); |
| } |
| |
| private AddMembers.Input fromMembers(List<Account.Id> accounts) { |
| return AddMembers.Input.fromMembers(Lists.newArrayList(Iterables.transform( |
| accounts, new Function<Account.Id, String>() { |
| @Override |
| public String apply(Account.Id id) { |
| return id.toString(); |
| } |
| }))); |
| } |
| } |