| // Copyright (C) 2010 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 static java.util.stream.Collectors.toList; | |
| import com.google.gerrit.common.data.GlobalCapability; | |
| import com.google.gerrit.entities.Account; | |
| import com.google.gerrit.entities.AccountGroup; | |
| import com.google.gerrit.extensions.annotations.RequiresCapability; | |
| import com.google.gerrit.extensions.api.groups.GroupInput; | |
| import com.google.gerrit.extensions.common.GroupInfo; | |
| import com.google.gerrit.extensions.restapi.IdString; | |
| import com.google.gerrit.extensions.restapi.RestApiException; | |
| import com.google.gerrit.extensions.restapi.TopLevelResource; | |
| import com.google.gerrit.server.group.GroupResource; | |
| import com.google.gerrit.server.permissions.PermissionBackendException; | |
| import com.google.gerrit.server.restapi.group.AddMembers; | |
| import com.google.gerrit.server.restapi.group.AddSubgroups; | |
| import com.google.gerrit.server.restapi.group.CreateGroup; | |
| import com.google.gerrit.server.restapi.group.GroupsCollection; | |
| import com.google.gerrit.sshd.CommandMetaData; | |
| import com.google.gerrit.sshd.SshCommand; | |
| import com.google.inject.Inject; | |
| import java.io.IOException; | |
| import java.util.HashSet; | |
| import java.util.Set; | |
| import org.eclipse.jgit.errors.ConfigInvalidException; | |
| import org.kohsuke.args4j.Argument; | |
| import org.kohsuke.args4j.Option; | |
| /** | |
| * Creates a new group. | |
| * | |
| * <p>Optionally, puts an initial set of user in the newly created group. | |
| */ | |
| @RequiresCapability(GlobalCapability.CREATE_GROUP) | |
| @CommandMetaData(name = "create-group", description = "Create a new account group") | |
| final class CreateGroupCommand extends SshCommand { | |
| @Option( | |
| name = "--owner", | |
| aliases = {"-o"}, | |
| metaVar = "GROUP", | |
| usage = "owning group, if not specified the group will be self-owning") | |
| private AccountGroup.Id ownerGroupId; | |
| @Option( | |
| name = "--description", | |
| aliases = {"-d"}, | |
| metaVar = "DESC", | |
| usage = "description of group") | |
| private String groupDescription = ""; | |
| @Argument(index = 0, required = true, metaVar = "GROUP", usage = "name of group to be created") | |
| private String groupName; | |
| private final Set<Account.Id> initialMembers = new HashSet<>(); | |
| @Option( | |
| name = "--member", | |
| aliases = {"-m"}, | |
| metaVar = "USERNAME", | |
| usage = "initial set of users to become members of the group") | |
| void addMember(Account.Id id) { | |
| initialMembers.add(id); | |
| } | |
| @Option(name = "--visible-to-all", usage = "to make the group visible to all registered users") | |
| private boolean visibleToAll; | |
| private final Set<AccountGroup.UUID> initialGroups = new HashSet<>(); | |
| @Option( | |
| name = "--group", | |
| aliases = "-g", | |
| metaVar = "GROUP", | |
| usage = "initial set of groups to be included in the group") | |
| void addGroup(AccountGroup.UUID id) { | |
| initialGroups.add(id); | |
| } | |
| @Inject private CreateGroup createGroup; | |
| @Inject private GroupsCollection groups; | |
| @Inject private AddMembers addMembers; | |
| @Inject private AddSubgroups addSubgroups; | |
| @Override | |
| protected void run() | |
| throws Failure, IOException, ConfigInvalidException, PermissionBackendException { | |
| enableGracefulStop(); | |
| try { | |
| GroupResource rsrc = createGroup(); | |
| if (!initialMembers.isEmpty()) { | |
| addMembers(rsrc); | |
| } | |
| if (!initialGroups.isEmpty()) { | |
| addSubgroups(rsrc); | |
| } | |
| } catch (RestApiException e) { | |
| throw die(e); | |
| } catch (Exception e) { | |
| throw new Failure(1, "unavailable", e); | |
| } | |
| } | |
| private GroupResource createGroup() | |
| throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { | |
| GroupInput input = new GroupInput(); | |
| input.description = groupDescription; | |
| input.visibleToAll = visibleToAll; | |
| if (ownerGroupId != null) { | |
| input.ownerId = String.valueOf(ownerGroupId.get()); | |
| } | |
| GroupInfo group = | |
| createGroup | |
| .apply(TopLevelResource.INSTANCE, IdString.fromDecoded(groupName), input) | |
| .value(); | |
| return groups.parse(TopLevelResource.INSTANCE, IdString.fromUrl(group.id)); | |
| } | |
| private void addMembers(GroupResource rsrc) | |
| throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { | |
| AddMembers.Input input = | |
| AddMembers.Input.fromMembers( | |
| initialMembers.stream().map(Object::toString).collect(toList())); | |
| addMembers.apply(rsrc, input); | |
| } | |
| private void addSubgroups(GroupResource rsrc) | |
| throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { | |
| AddSubgroups.Input input = | |
| AddSubgroups.Input.fromGroups( | |
| initialGroups.stream().map(AccountGroup.UUID::get).collect(toList())); | |
| addSubgroups.apply(rsrc, input); | |
| } | |
| } |