SSH commands with user: create account if needed
SSH commands that accept a user as parameter (e.g. create-group, receive-pack) fail if for a specified user an account is not existing. With this change the command is not immediately failing, but if a user is specified that has no account it tries to authenticate the user and if the authentication is successful a user account is automatically created so that the SSH command can succeed. This is e.g. useful if you have an automated process that creates committer groups for new projects. Since it can happen that the users that should be assigned to the new committer group have never logged in into Gerrit, some of these users may not have a Gerrit account and so the group creation fails. However these users are all known in the used LDAP system and so a Gerrit account can be automatically created for them. With this the group creation can be successful even if some of the members did not log in into Gerrit before. Signed-off-by: Edwin Kempin <edwin.kempin@sap.com> Change-Id: Ic3bc7b802ab5c8b0da4953fe207e47a43c54bcf7
This commit is contained in:
@@ -24,6 +24,8 @@ import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.PeerDaemonUser;
|
||||
import com.google.gerrit.server.RemotePeer;
|
||||
import com.google.gerrit.server.account.AccountManager;
|
||||
import com.google.gerrit.server.account.ChangeUserName;
|
||||
import com.google.gerrit.server.config.FactoryModule;
|
||||
import com.google.gerrit.server.config.GerritRequestModule;
|
||||
import com.google.gerrit.server.git.TransferConfig;
|
||||
@@ -75,6 +77,8 @@ public class SshModule extends FactoryModule {
|
||||
bind(WorkQueue.Executor.class).annotatedWith(StreamCommandExecutor.class)
|
||||
.toProvider(StreamCommandExecutorProvider.class).in(SINGLETON);
|
||||
bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON);
|
||||
bind(AccountManager.class);
|
||||
factory(ChangeUserName.Factory.class);
|
||||
|
||||
bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
|
||||
bind(KeyPairProvider.class).toProvider(HostKeyProvider.class).in(SINGLETON);
|
||||
|
@@ -15,7 +15,11 @@
|
||||
package com.google.gerrit.sshd.args4j;
|
||||
|
||||
import com.google.gerrit.reviewdb.Account;
|
||||
import com.google.gerrit.server.account.AccountException;
|
||||
import com.google.gerrit.server.account.AccountManager;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.account.AuthRequest;
|
||||
import com.google.gerrit.server.account.AuthResult;
|
||||
import com.google.gwtorm.client.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
@@ -29,14 +33,17 @@ import org.kohsuke.args4j.spi.Setter;
|
||||
|
||||
public class AccountIdHandler extends OptionHandler<Account.Id> {
|
||||
private final AccountResolver accountResolver;
|
||||
private final AccountManager accountManager;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject
|
||||
public AccountIdHandler(final AccountResolver accountResolver,
|
||||
final AccountManager accountManager,
|
||||
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
|
||||
@Assisted final Setter setter) {
|
||||
super(parser, option, setter);
|
||||
this.accountResolver = accountResolver;
|
||||
this.accountManager = accountManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,10 +53,11 @@ public class AccountIdHandler extends OptionHandler<Account.Id> {
|
||||
final Account.Id accountId;
|
||||
try {
|
||||
final Account a = accountResolver.find(token);
|
||||
if (a == null) {
|
||||
throw new CmdLineException(owner, "\"" + token + "\" is not registered");
|
||||
if (a != null) {
|
||||
accountId = a.getId();
|
||||
} else {
|
||||
accountId = createAccountIfUserCanBeAuthenticated(token);
|
||||
}
|
||||
accountId = a.getId();
|
||||
} catch (OrmException e) {
|
||||
throw new CmdLineException(owner, "database is down");
|
||||
}
|
||||
@@ -57,6 +65,18 @@ public class AccountIdHandler extends OptionHandler<Account.Id> {
|
||||
return 1;
|
||||
}
|
||||
|
||||
private Account.Id createAccountIfUserCanBeAuthenticated(final String username)
|
||||
throws CmdLineException {
|
||||
try {
|
||||
final AuthRequest areq = AuthRequest.forUser(username);
|
||||
final AuthResult arsp = accountManager.authenticate(areq);
|
||||
return arsp.getAccountId();
|
||||
} catch (AccountException e) {
|
||||
throw new CmdLineException(owner, "Unable to authenticate user \""
|
||||
+ username + "\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getDefaultMetaVariable() {
|
||||
return "EMAIL";
|
||||
|
Reference in New Issue
Block a user