All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.sshd.commands.SetAccountCommand Maven / Gradle / Ivy

// Copyright (C) 2012 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 com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AddSshKey;
import com.google.gerrit.server.account.CreateEmail;
import com.google.gerrit.server.account.DeleteActive;
import com.google.gerrit.server.account.DeleteEmail;
import com.google.gerrit.server.account.DeleteSshKey;
import com.google.gerrit.server.account.GetEmails;
import com.google.gerrit.server.account.GetEmails.EmailInfo;
import com.google.gerrit.server.account.GetSshKeys;
import com.google.gerrit.server.account.GetSshKeys.SshKeyInfo;
import com.google.gerrit.server.account.PutActive;
import com.google.gerrit.server.account.PutHttpPassword;
import com.google.gerrit.server.account.PutName;
import com.google.gerrit.sshd.BaseCommand;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.apache.sshd.server.Environment;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Set a user's account settings. **/
@CommandMetaData(name = "set-account", description = "Change an account's settings")
final class SetAccountCommand extends BaseCommand {

  @Argument(index = 0, required = true, metaVar = "USER", usage = "full name, email-address, ssh username or account id")
  private Account.Id id;

  @Option(name = "--full-name", metaVar = "NAME", usage = "display name of the account")
  private String fullName;

  @Option(name = "--active", usage = "set account's state to active")
  private boolean active;

  @Option(name = "--inactive", usage = "set account's state to inactive")
  private boolean inactive;

  @Option(name = "--add-email", metaVar = "EMAIL", usage = "email addresses to add to the account")
  private List addEmails = new ArrayList<>();

  @Option(name = "--delete-email", metaVar = "EMAIL", usage = "email addresses to delete from the account")
  private List deleteEmails = new ArrayList<>();

  @Option(name = "--add-ssh-key", metaVar = "-|KEY", usage = "public keys to add to the account")
  private List addSshKeys = new ArrayList<>();

  @Option(name = "--delete-ssh-key", metaVar = "-|KEY", usage = "public keys to delete from the account")
  private List deleteSshKeys = new ArrayList<>();

  @Option(name = "--http-password", metaVar = "PASSWORD", usage = "password for HTTP authentication for the account")
  private String httpPassword;

  @Inject
  private IdentifiedUser currentUser;

  @Inject
  private IdentifiedUser.GenericFactory genericUserFactory;

  @Inject
  private CreateEmail.Factory createEmailFactory;

  @Inject
  private Provider getEmailsProvider;

  @Inject
  private Provider deleteEmailProvider;

  @Inject
  private Provider putNameProvider;

  @Inject
  private Provider putHttpPasswordProvider;

  @Inject
  private Provider putActiveProvider;

  @Inject
  private Provider deleteActiveProvider;

  @Inject
  private Provider addSshKeyProvider;

  @Inject
  private Provider getSshKeysProvider;

  @Inject
  private Provider deleteSshKeyProvider;

  private IdentifiedUser user;
  private AccountResource rsrc;

  @Override
  public void start(final Environment env) {
    startThread(new CommandRunnable() {
      @Override
      public void run() throws Exception {
        if (!currentUser.getCapabilities().canAdministrateServer()) {
          String msg =
              String.format(
                  "fatal: %s does not have \"Administrator\" capability.",
                  currentUser.getUserName());
          throw new UnloggedFailure(1, msg);
        }
        parseCommandLine();
        validate();
        setAccount();
      }
    });
  }

  private void validate() throws UnloggedFailure {
    if (active && inactive) {
      throw new UnloggedFailure(1,
          "--active and --inactive options are mutually exclusive.");
    }
    if (addSshKeys.contains("-") && deleteSshKeys.contains("-")) {
      throw new UnloggedFailure(1, "Only one option may use the stdin");
    }
    if (deleteSshKeys.contains("ALL")) {
      deleteSshKeys = Collections.singletonList("ALL");
    }
    if (deleteEmails.contains("ALL")) {
      deleteEmails = Collections.singletonList("ALL");
    }
  }

  private void setAccount() throws OrmException, IOException, UnloggedFailure {
    user = genericUserFactory.create(id);
    rsrc = new AccountResource(user);
    try {
      for (String email : addEmails) {
        addEmail(email);
      }

      for (String email : deleteEmails) {
        deleteEmail(email);
      }

      if (fullName != null) {
        PutName.Input in = new PutName.Input();
        in.name = fullName;
        putNameProvider.get().apply(rsrc, in);
      }

      if (httpPassword != null) {
        PutHttpPassword.Input in = new PutHttpPassword.Input();
        in.httpPassword = httpPassword;
        putHttpPasswordProvider.get().apply(rsrc, in);
      }

      if (active) {
        putActiveProvider.get().apply(rsrc, null);
      } else if (inactive) {
        try {
          deleteActiveProvider.get().apply(rsrc, null);
        } catch (ResourceNotFoundException e) {
          // user is already inactive
        }
      }

      addSshKeys = readSshKey(addSshKeys);
      if (!addSshKeys.isEmpty()) {
        addSshKeys(addSshKeys);
      }

      deleteSshKeys = readSshKey(deleteSshKeys);
      if (!deleteSshKeys.isEmpty()) {
        deleteSshKeys(deleteSshKeys);
      }
    } catch (RestApiException e) {
      throw die(e.getMessage());
    }
  }

  private void addSshKeys(List sshKeys) throws RestApiException,
      UnloggedFailure, OrmException, IOException {
    for (final String sshKey : sshKeys) {
      AddSshKey.Input in = new AddSshKey.Input();
      in.raw = new RawInput() {
        @Override
        public InputStream getInputStream() throws IOException {
          return new ByteArrayInputStream(sshKey.getBytes("UTF-8"));
        }

        @Override
        public String getContentType() {
          return "plain/text";
        }

        @Override
        public long getContentLength() {
          return sshKey.length();
        }
      };
      addSshKeyProvider.get().apply(rsrc, in);
    }
  }

  private void deleteSshKeys(List sshKeys) throws RestApiException,
      OrmException {
    List infos = getSshKeysProvider.get().apply(rsrc);
    if (sshKeys.contains("ALL")) {
      for (SshKeyInfo i : infos) {
        deleteSshKey(i);
      }
    } else {
      for (String sshKey : sshKeys) {
        for (SshKeyInfo i : infos) {
          if (sshKey.trim().equals(i.sshPublicKey)
              || sshKey.trim().equals(i.comment)) {
            deleteSshKey(i);
          }
        }
      }
    }
  }

  private void deleteSshKey(SshKeyInfo i) throws OrmException {
    AccountSshKey sshKey = new AccountSshKey(
        new AccountSshKey.Id(user.getAccountId(), i.seq), i.sshPublicKey);
    deleteSshKeyProvider.get().apply(
        new AccountResource.SshKey(user, sshKey), null);
  }

  private void addEmail(String email) throws UnloggedFailure, RestApiException,
      OrmException {
    CreateEmail.Input in = new CreateEmail.Input();
    in.email = email;
    in.noConfirmation = true;
    try {
      createEmailFactory.create(email).apply(rsrc, in);
    } catch (EmailException e) {
      throw die(e.getMessage());
    }
  }

  private void deleteEmail(String email) throws UnloggedFailure,
      RestApiException, OrmException {
    if (email.equals("ALL")) {
      List emails = getEmailsProvider.get().apply(rsrc);
      DeleteEmail deleteEmail = deleteEmailProvider.get();
      for (EmailInfo e : emails) {
        deleteEmail.apply(new AccountResource.Email(user, e.email),
            new DeleteEmail.Input());
      }
    } else {
      deleteEmailProvider.get().apply(new AccountResource.Email(user, email),
          new DeleteEmail.Input());
    }
  }

  private List readSshKey(final List sshKeys)
      throws UnsupportedEncodingException, IOException {
    if (!sshKeys.isEmpty()) {
      String sshKey;
      int idx = sshKeys.indexOf("-");
      if (idx >= 0) {
        sshKey = "";
        BufferedReader br =
            new BufferedReader(new InputStreamReader(in, "UTF-8"));
        String line;
        while ((line = br.readLine()) != null) {
          sshKey += line + "\n";
        }
        sshKeys.set(idx, sshKey);
      }
    }
    return sshKeys;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy