Add --generate-http-password to ssh set-account

To bring the ssh command more in-line with the REST API for a user, it
is now possible to generate a new http-password which does not require
global admin (unlike direct set).

This allows ordinary users to set a new http password via ssh when they
cannot log in to the web ui (e.g. due to being a service account.)

The next commit will change the access restriction so that setting
your own account details does not require MODIFY_ACCOUNT. The REST API
does not need this, and granting it to someone allows them to set *any*
account details, e.g. even deactivating admin accounts.

Change-Id: Ic6102da9e483d07175cdc772930f25608dce12d4
This commit is contained in:
Richard Christie 2018-06-28 12:33:51 +01:00
parent 24d04f4a14
commit efa38be397
2 changed files with 28 additions and 4 deletions

View File

@ -12,6 +12,7 @@ _ssh_ -p <port> <host> _gerrit set-account_
[--preferred-email <EMAIL>]
[--add-ssh-key - | <KEY>]
[--delete-ssh-key - | <KEY> | ALL]
[--generate-http-password]
[--http-password <PASSWORD>]
[--clear-http-password] <USER>
--
@ -93,6 +94,11 @@ This most likely requires double quoting the value, for example
May be supplied more than once to delete multiple SSH
keys in a single command execution.
--generate-http-password::
Generate a new random HTTP password for the user account
similar to the web ui. The password will be output to the
user on success with a line: `New password: <PASSWORD>`.
--http-password::
Set the HTTP password for the user account.

View File

@ -26,6 +26,7 @@ import com.google.gerrit.extensions.common.EmailInfo;
import com.google.gerrit.extensions.common.SshKeyInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountSshKey;
@ -113,6 +114,9 @@ final class SetAccountCommand extends SshCommand {
@Option(name = "--clear-http-password", usage = "clear HTTP password for the account")
private boolean clearHttpPassword;
@Option(name = "--generate-http-password", usage = "generate a new HTTP password for the account")
private boolean generateHttpPassword;
@Inject private IdentifiedUser.GenericFactory genericUserFactory;
@Inject private CreateEmail.Factory createEmailFactory;
@ -150,8 +154,16 @@ final class SetAccountCommand extends SshCommand {
if (active && inactive) {
throw die("--active and --inactive options are mutually exclusive.");
}
if (clearHttpPassword && !Strings.isNullOrEmpty(httpPassword)) {
throw die("--http-password and --clear-http-password options are mutually exclusive.");
if (generateHttpPassword && clearHttpPassword) {
throw die("--generate-http-password and --clear-http-password are mutually exclusive.");
}
if (!Strings.isNullOrEmpty(httpPassword)) { // gave --http-password
if (generateHttpPassword) {
throw die("--http-password and --generate-http-password options are mutually exclusive.");
}
if (clearHttpPassword) {
throw die("--http-password and --clear-http-password options are mutually exclusive.");
}
}
if (addSshKeys.contains("-") && deleteSshKeys.contains("-")) {
throw die("Only one option may use the stdin");
@ -193,10 +205,16 @@ final class SetAccountCommand extends SshCommand {
putName.apply(rsrc, in);
}
if (httpPassword != null || clearHttpPassword) {
if (httpPassword != null || clearHttpPassword || generateHttpPassword) {
PutHttpPassword.Input in = new PutHttpPassword.Input();
in.httpPassword = httpPassword;
putHttpPassword.apply(rsrc, in);
if (generateHttpPassword) {
in.generate = true;
}
Response<String> resp = putHttpPassword.apply(rsrc, in);
if (generateHttpPassword) {
stdout.print("New password: " + resp.value() + "\n");
}
}
if (active) {