blob: 76406ef89cc9b133e9008e9574e99981baa2c398 [file] [log] [blame]
// Copyright (C) 2022 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 com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.kohsuke.args4j.Option;
@CommandMetaData(
name = "check-project-access",
description = "Check project readability for specified user(s)",
runsAt = MASTER_OR_SLAVE)
public class CheckProjectAccessCommand extends SshCommand {
@Inject private AccountResolver accountResolver;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject private PermissionBackend permissionBackend;
@Inject private Provider<CurrentUser> userProvider;
@Option(
name = "--project",
aliases = {"-p"},
metaVar = "PROJECT",
required = true,
usage = "project name to check")
private String projectName;
@Option(
name = "--user",
aliases = {"-u"},
metaVar = "USER",
required = true,
usage = "Account identifier used to find the user(s) for which to check access.")
private String userName;
@Override
protected void run() throws Failure, ConfigInvalidException, IOException {
PermissionBackend.WithUser userPermission = permissionBackend.user(userProvider.get());
boolean isAdmin = userPermission.testOrFalse(GlobalPermission.ADMINISTRATE_SERVER);
boolean canViewAccount = isAdmin || userPermission.testOrFalse(GlobalPermission.VIEW_ACCESS);
if (!user.hasSameAccountId(userProvider.get()) && !canViewAccount) {
throw die("This command requires 'view access' or 'administrate server' capabilities.");
}
try {
for (IdentifiedUser user : getUserList(userName)) {
stdout.println(
String.format(
"Username: '%s', Email: '%s', Full Name: '%s', Result: %b\n",
user.getLoggableName(),
user.getNameEmail()
.substring(
user.getNameEmail().indexOf("<") + 1, user.getNameEmail().indexOf(">")),
user.getName(),
permissionBackend
.user(user)
.project(Project.nameKey(projectName))
.test(ProjectPermission.READ)));
}
} catch (ConfigInvalidException
| ResourceNotFoundException
| IllegalArgumentException
| PermissionBackendException e) {
throw die(e);
}
}
private ImmutableSet<IdentifiedUser> getUserList(String userName)
throws ConfigInvalidException, IOException, ResourceNotFoundException {
return getIdList(userName).stream().map(userFactory::create).collect(toImmutableSet());
}
private ImmutableSet<Account.Id> getIdList(String userName)
throws ConfigInvalidException, IOException, ResourceNotFoundException {
ImmutableSet<Account.Id> idList = accountResolver.resolve(userName).asIdSet();
if (idList.isEmpty()) {
throw new ResourceNotFoundException(
"No accounts found for your query: \""
+ userName
+ "\""
+ " Tip: Try double-escaping spaces, for example: \"--user Last,\\\\ First\"");
}
return idList;
}
}