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

com.google.gerrit.server.account.ChangeUserName Maven / Gradle / Ivy

There is a newer version: 3.10.0-rc4
Show newest version
// Copyright (C) 2009 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.server.account;

import static com.google.gerrit.server.account.ExternalId.SCHEME_USERNAME;
import static java.util.stream.Collectors.toSet;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.gwtjsonrpc.common.VoidResult;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.Callable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Operation to change the username of an account. */
public class ChangeUserName implements Callable {
  private static final Logger log = LoggerFactory.getLogger(ChangeUserName.class);

  public static final String USERNAME_CANNOT_BE_CHANGED = "Username cannot be changed.";

  /** Generic factory to change any user's username. */
  public interface Factory {
    ChangeUserName create(ReviewDb db, IdentifiedUser user, String newUsername);
  }

  private final AccountCache accountCache;
  private final SshKeyCache sshKeyCache;
  private final ExternalIdsUpdate.Server externalIdsUpdateFactory;

  private final ReviewDb db;
  private final IdentifiedUser user;
  private final String newUsername;

  @Inject
  ChangeUserName(
      AccountCache accountCache,
      SshKeyCache sshKeyCache,
      ExternalIdsUpdate.Server externalIdsUpdateFactory,
      @Assisted ReviewDb db,
      @Assisted IdentifiedUser user,
      @Nullable @Assisted String newUsername) {
    this.accountCache = accountCache;
    this.sshKeyCache = sshKeyCache;
    this.externalIdsUpdateFactory = externalIdsUpdateFactory;
    this.db = db;
    this.user = user;
    this.newUsername = newUsername;
  }

  @Override
  public VoidResult call()
      throws OrmException, NameAlreadyUsedException, InvalidUserNameException, IOException,
          ConfigInvalidException {
    Collection old =
        ExternalId.from(db.accountExternalIds().byAccount(user.getAccountId()).toList())
            .stream()
            .filter(e -> e.isScheme(SCHEME_USERNAME))
            .collect(toSet());
    if (!old.isEmpty()) {
      log.error(
          "External id with scheme \"username:\" already exists for the user {}",
          user.getAccountId());
      throw new IllegalStateException(USERNAME_CANNOT_BE_CHANGED);
    }

    ExternalIdsUpdate externalIdsUpdate = externalIdsUpdateFactory.create();
    if (newUsername != null && !newUsername.isEmpty()) {
      if (!ExternalId.isValidUsername(newUsername)) {
        throw new InvalidUserNameException();
      }

      ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, newUsername);
      try {
        String password = null;
        for (ExternalId i : old) {
          if (i.password() != null) {
            password = i.password();
          }
        }
        externalIdsUpdate.insert(db, ExternalId.create(key, user.getAccountId(), null, password));
        log.info("Created the new external Id with key: {}", key);
      } catch (OrmDuplicateKeyException dupeErr) {
        // If we are using this identity, don't report the exception.
        //
        ExternalId other =
            ExternalId.from(db.accountExternalIds().get(key.asAccountExternalIdKey()));
        if (other != null && other.accountId().equals(user.getAccountId())) {
          return VoidResult.INSTANCE;
        }

        // Otherwise, someone else has this identity.
        //
        throw new NameAlreadyUsedException(newUsername);
      }
    }

    // If we have any older user names, remove them.
    //
    externalIdsUpdate.delete(db, old);
    for (ExternalId extId : old) {
      sshKeyCache.evict(extId.key().id());
      accountCache.evictByUsername(extId.key().id());
    }

    accountCache.evictByUsername(newUsername);
    sshKeyCache.evict(newUsername);
    return VoidResult.INSTANCE;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy