Line data Source code
1 : // Copyright (C) 2010 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.sshd.commands; 16 : 17 : import static java.util.stream.Collectors.toList; 18 : 19 : import com.google.gerrit.common.data.GlobalCapability; 20 : import com.google.gerrit.entities.Account; 21 : import com.google.gerrit.entities.AccountGroup; 22 : import com.google.gerrit.extensions.annotations.RequiresCapability; 23 : import com.google.gerrit.extensions.api.groups.GroupInput; 24 : import com.google.gerrit.extensions.common.GroupInfo; 25 : import com.google.gerrit.extensions.restapi.IdString; 26 : import com.google.gerrit.extensions.restapi.RestApiException; 27 : import com.google.gerrit.extensions.restapi.TopLevelResource; 28 : import com.google.gerrit.server.group.GroupResource; 29 : import com.google.gerrit.server.permissions.PermissionBackendException; 30 : import com.google.gerrit.server.restapi.group.AddMembers; 31 : import com.google.gerrit.server.restapi.group.AddSubgroups; 32 : import com.google.gerrit.server.restapi.group.CreateGroup; 33 : import com.google.gerrit.server.restapi.group.GroupsCollection; 34 : import com.google.gerrit.sshd.CommandMetaData; 35 : import com.google.gerrit.sshd.SshCommand; 36 : import com.google.inject.Inject; 37 : import java.io.IOException; 38 : import java.util.HashSet; 39 : import java.util.Set; 40 : import org.eclipse.jgit.errors.ConfigInvalidException; 41 : import org.kohsuke.args4j.Argument; 42 : import org.kohsuke.args4j.Option; 43 : 44 : /** 45 : * Creates a new group. 46 : * 47 : * <p>Optionally, puts an initial set of user in the newly created group. 48 : */ 49 : @RequiresCapability(GlobalCapability.CREATE_GROUP) 50 : @CommandMetaData(name = "create-group", description = "Create a new account group") 51 1 : final class CreateGroupCommand extends SshCommand { 52 : @Option( 53 : name = "--owner", 54 : aliases = {"-o"}, 55 : metaVar = "GROUP", 56 : usage = "owning group, if not specified the group will be self-owning") 57 : private AccountGroup.Id ownerGroupId; 58 : 59 1 : @Option( 60 : name = "--description", 61 : aliases = {"-d"}, 62 : metaVar = "DESC", 63 : usage = "description of group") 64 : private String groupDescription = ""; 65 : 66 : @Argument(index = 0, required = true, metaVar = "GROUP", usage = "name of group to be created") 67 : private String groupName; 68 : 69 1 : private final Set<Account.Id> initialMembers = new HashSet<>(); 70 : 71 : @Option( 72 : name = "--member", 73 : aliases = {"-m"}, 74 : metaVar = "USERNAME", 75 : usage = "initial set of users to become members of the group") 76 : void addMember(Account.Id id) { 77 0 : initialMembers.add(id); 78 0 : } 79 : 80 : @Option(name = "--visible-to-all", usage = "to make the group visible to all registered users") 81 : private boolean visibleToAll; 82 : 83 1 : private final Set<AccountGroup.UUID> initialGroups = new HashSet<>(); 84 : 85 : @Option( 86 : name = "--group", 87 : aliases = "-g", 88 : metaVar = "GROUP", 89 : usage = "initial set of groups to be included in the group") 90 : void addGroup(AccountGroup.UUID id) { 91 0 : initialGroups.add(id); 92 0 : } 93 : 94 : @Inject private CreateGroup createGroup; 95 : 96 : @Inject private GroupsCollection groups; 97 : 98 : @Inject private AddMembers addMembers; 99 : 100 : @Inject private AddSubgroups addSubgroups; 101 : 102 : @Override 103 : protected void run() 104 : throws Failure, IOException, ConfigInvalidException, PermissionBackendException { 105 0 : enableGracefulStop(); 106 : try { 107 0 : GroupResource rsrc = createGroup(); 108 : 109 0 : if (!initialMembers.isEmpty()) { 110 0 : addMembers(rsrc); 111 : } 112 : 113 0 : if (!initialGroups.isEmpty()) { 114 0 : addSubgroups(rsrc); 115 : } 116 0 : } catch (RestApiException e) { 117 0 : throw die(e); 118 0 : } catch (Exception e) { 119 0 : throw new Failure(1, "unavailable", e); 120 0 : } 121 0 : } 122 : 123 : private GroupResource createGroup() 124 : throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { 125 0 : GroupInput input = new GroupInput(); 126 0 : input.description = groupDescription; 127 0 : input.visibleToAll = visibleToAll; 128 : 129 0 : if (ownerGroupId != null) { 130 0 : input.ownerId = String.valueOf(ownerGroupId.get()); 131 : } 132 : 133 0 : GroupInfo group = 134 : createGroup 135 0 : .apply(TopLevelResource.INSTANCE, IdString.fromDecoded(groupName), input) 136 0 : .value(); 137 0 : return groups.parse(TopLevelResource.INSTANCE, IdString.fromUrl(group.id)); 138 : } 139 : 140 : private void addMembers(GroupResource rsrc) 141 : throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { 142 0 : AddMembers.Input input = 143 0 : AddMembers.Input.fromMembers( 144 0 : initialMembers.stream().map(Object::toString).collect(toList())); 145 0 : addMembers.apply(rsrc, input); 146 0 : } 147 : 148 : private void addSubgroups(GroupResource rsrc) 149 : throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException { 150 0 : AddSubgroups.Input input = 151 0 : AddSubgroups.Input.fromGroups( 152 0 : initialGroups.stream().map(AccountGroup.UUID::get).collect(toList())); 153 0 : addSubgroups.apply(rsrc, input); 154 0 : } 155 : }