Always update accounts atomically
This prevents that we unintentionally overwrite concurrent updates, e.g. updates that were done by a racing request or updates we didn't see because we read from a stale cache. Change-Id: I4dfc7726c9324f06806919590d3ef83555bd44a4 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
		@@ -37,7 +37,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
				
			|||||||
import com.google.gerrit.server.CurrentUser;
 | 
					import com.google.gerrit.server.CurrentUser;
 | 
				
			||||||
import com.google.gerrit.server.IdentifiedUser;
 | 
					import com.google.gerrit.server.IdentifiedUser;
 | 
				
			||||||
import com.google.gerrit.server.account.AccountManager;
 | 
					import com.google.gerrit.server.account.AccountManager;
 | 
				
			||||||
import com.google.gerrit.server.account.Accounts;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.account.AccountsUpdate;
 | 
					import com.google.gerrit.server.account.AccountsUpdate;
 | 
				
			||||||
import com.google.gerrit.server.account.AuthRequest;
 | 
					import com.google.gerrit.server.account.AuthRequest;
 | 
				
			||||||
import com.google.gerrit.server.account.externalids.ExternalId;
 | 
					import com.google.gerrit.server.account.externalids.ExternalId;
 | 
				
			||||||
@@ -71,8 +70,6 @@ import org.junit.Test;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/** Unit tests for {@link GerritPublicKeyChecker}. */
 | 
					/** Unit tests for {@link GerritPublicKeyChecker}. */
 | 
				
			||||||
public class GerritPublicKeyCheckerTest {
 | 
					public class GerritPublicKeyCheckerTest {
 | 
				
			||||||
  @Inject private Accounts accounts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @Inject private AccountsUpdate.Server accountsUpdate;
 | 
					  @Inject private AccountsUpdate.Server accountsUpdate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Inject private AccountManager accountManager;
 | 
					  @Inject private AccountManager accountManager;
 | 
				
			||||||
@@ -117,10 +114,8 @@ public class GerritPublicKeyCheckerTest {
 | 
				
			|||||||
    db = schemaFactory.open();
 | 
					    db = schemaFactory.open();
 | 
				
			||||||
    schemaCreator.create(db);
 | 
					    schemaCreator.create(db);
 | 
				
			||||||
    userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
 | 
					    userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
 | 
				
			||||||
    Account userAccount = accounts.get(db, userId);
 | 
					 | 
				
			||||||
    // Note: does not match any key in TestKeys.
 | 
					    // Note: does not match any key in TestKeys.
 | 
				
			||||||
    userAccount.setPreferredEmail("user@example.com");
 | 
					    accountsUpdate.create().atomicUpdate(db, userId, a -> a.setPreferredEmail("user@example.com"));
 | 
				
			||||||
    accountsUpdate.create().update(db, userAccount);
 | 
					 | 
				
			||||||
    user = reloadUser();
 | 
					    user = reloadUser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    requestContext.setContext(
 | 
					    requestContext.setContext(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,10 +38,13 @@ import com.google.inject.Inject;
 | 
				
			|||||||
import com.google.inject.Provider;
 | 
					import com.google.inject.Provider;
 | 
				
			||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
					import java.util.concurrent.atomic.AtomicBoolean;
 | 
				
			||||||
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
					import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
				
			||||||
import org.eclipse.jgit.lib.Config;
 | 
					import org.eclipse.jgit.lib.Config;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
@@ -149,7 +152,7 @@ public class AccountManager {
 | 
				
			|||||||
  private void update(ReviewDb db, AuthRequest who, ExternalId extId)
 | 
					  private void update(ReviewDb db, AuthRequest who, ExternalId extId)
 | 
				
			||||||
      throws OrmException, IOException, ConfigInvalidException {
 | 
					      throws OrmException, IOException, ConfigInvalidException {
 | 
				
			||||||
    IdentifiedUser user = userFactory.create(extId.accountId());
 | 
					    IdentifiedUser user = userFactory.create(extId.accountId());
 | 
				
			||||||
    Account toUpdate = null;
 | 
					    List<Consumer<Account>> accountUpdates = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If the email address was modified by the authentication provider,
 | 
					    // If the email address was modified by the authentication provider,
 | 
				
			||||||
    // update our records to match the changed email.
 | 
					    // update our records to match the changed email.
 | 
				
			||||||
@@ -158,8 +161,7 @@ public class AccountManager {
 | 
				
			|||||||
    String oldEmail = extId.email();
 | 
					    String oldEmail = extId.email();
 | 
				
			||||||
    if (newEmail != null && !newEmail.equals(oldEmail)) {
 | 
					    if (newEmail != null && !newEmail.equals(oldEmail)) {
 | 
				
			||||||
      if (oldEmail != null && oldEmail.equals(user.getAccount().getPreferredEmail())) {
 | 
					      if (oldEmail != null && oldEmail.equals(user.getAccount().getPreferredEmail())) {
 | 
				
			||||||
        toUpdate = load(toUpdate, user.getAccountId(), db);
 | 
					        accountUpdates.add(a -> a.setPreferredEmail(newEmail));
 | 
				
			||||||
        toUpdate.setPreferredEmail(newEmail);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      externalIdsUpdateFactory
 | 
					      externalIdsUpdateFactory
 | 
				
			||||||
@@ -171,8 +173,7 @@ public class AccountManager {
 | 
				
			|||||||
    if (!realm.allowsEdit(AccountFieldName.FULL_NAME)
 | 
					    if (!realm.allowsEdit(AccountFieldName.FULL_NAME)
 | 
				
			||||||
        && !Strings.isNullOrEmpty(who.getDisplayName())
 | 
					        && !Strings.isNullOrEmpty(who.getDisplayName())
 | 
				
			||||||
        && !eq(user.getAccount().getFullName(), who.getDisplayName())) {
 | 
					        && !eq(user.getAccount().getFullName(), who.getDisplayName())) {
 | 
				
			||||||
      toUpdate = load(toUpdate, user.getAccountId(), db);
 | 
					      accountUpdates.add(a -> a.setFullName(who.getDisplayName()));
 | 
				
			||||||
      toUpdate.setFullName(who.getDisplayName());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!realm.allowsEdit(AccountFieldName.USER_NAME)
 | 
					    if (!realm.allowsEdit(AccountFieldName.USER_NAME)
 | 
				
			||||||
@@ -183,8 +184,12 @@ public class AccountManager {
 | 
				
			|||||||
              "Not changing already set username %s to %s", user.getUserName(), who.getUserName()));
 | 
					              "Not changing already set username %s to %s", user.getUserName(), who.getUserName()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (toUpdate != null) {
 | 
					    if (!accountUpdates.isEmpty()) {
 | 
				
			||||||
      accountsUpdateFactory.create().update(db, toUpdate);
 | 
					      Account account =
 | 
				
			||||||
 | 
					          accountsUpdateFactory.create().atomicUpdate(db, user.getAccountId(), accountUpdates);
 | 
				
			||||||
 | 
					      if (account == null) {
 | 
				
			||||||
 | 
					        throw new OrmException("Account " + user.getAccountId() + " has been deleted");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (newEmail != null && !newEmail.equals(oldEmail)) {
 | 
					    if (newEmail != null && !newEmail.equals(oldEmail)) {
 | 
				
			||||||
@@ -193,17 +198,6 @@ public class AccountManager {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private Account load(Account toUpdate, Account.Id accountId, ReviewDb db)
 | 
					 | 
				
			||||||
      throws OrmException, IOException, ConfigInvalidException {
 | 
					 | 
				
			||||||
    if (toUpdate == null) {
 | 
					 | 
				
			||||||
      toUpdate = accounts.get(db, accountId);
 | 
					 | 
				
			||||||
      if (toUpdate == null) {
 | 
					 | 
				
			||||||
        throw new OrmException("Account " + accountId + " has been deleted");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return toUpdate;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private static boolean eq(String a, String b) {
 | 
					  private static boolean eq(String a, String b) {
 | 
				
			||||||
    return (a == null && b == null) || (a != null && a.equals(b));
 | 
					    return (a == null && b == null) || (a != null && a.equals(b));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -369,11 +363,16 @@ public class AccountManager {
 | 
				
			|||||||
            .insert(ExternalId.createWithEmail(who.getExternalIdKey(), to, who.getEmailAddress()));
 | 
					            .insert(ExternalId.createWithEmail(who.getExternalIdKey(), to, who.getEmailAddress()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (who.getEmailAddress() != null) {
 | 
					        if (who.getEmailAddress() != null) {
 | 
				
			||||||
          Account a = accounts.get(db, to);
 | 
					          accountsUpdateFactory
 | 
				
			||||||
          if (a.getPreferredEmail() == null) {
 | 
					              .create()
 | 
				
			||||||
            a.setPreferredEmail(who.getEmailAddress());
 | 
					              .atomicUpdate(
 | 
				
			||||||
            accountsUpdateFactory.create().update(db, a);
 | 
					                  db,
 | 
				
			||||||
          }
 | 
					                  to,
 | 
				
			||||||
 | 
					                  a -> {
 | 
				
			||||||
 | 
					                    if (a.getPreferredEmail() == null) {
 | 
				
			||||||
 | 
					                      a.setPreferredEmail(who.getEmailAddress());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  });
 | 
				
			||||||
          byEmailCache.evict(who.getEmailAddress());
 | 
					          byEmailCache.evict(who.getEmailAddress());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -433,12 +432,17 @@ public class AccountManager {
 | 
				
			|||||||
        externalIdsUpdateFactory.create().delete(extId);
 | 
					        externalIdsUpdateFactory.create().delete(extId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (who.getEmailAddress() != null) {
 | 
					        if (who.getEmailAddress() != null) {
 | 
				
			||||||
          Account a = accounts.get(db, from);
 | 
					          accountsUpdateFactory
 | 
				
			||||||
          if (a.getPreferredEmail() != null
 | 
					              .create()
 | 
				
			||||||
              && a.getPreferredEmail().equals(who.getEmailAddress())) {
 | 
					              .atomicUpdate(
 | 
				
			||||||
            a.setPreferredEmail(null);
 | 
					                  db,
 | 
				
			||||||
            accountsUpdateFactory.create().update(db, a);
 | 
					                  from,
 | 
				
			||||||
          }
 | 
					                  a -> {
 | 
				
			||||||
 | 
					                    if (a.getPreferredEmail() != null
 | 
				
			||||||
 | 
					                        && a.getPreferredEmail().equals(who.getEmailAddress())) {
 | 
				
			||||||
 | 
					                      a.setPreferredEmail(null);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  });
 | 
				
			||||||
          byEmailCache.evict(who.getEmailAddress());
 | 
					          byEmailCache.evict(who.getEmailAddress());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ package com.google.gerrit.server.account;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import static com.google.common.base.Preconditions.checkNotNull;
 | 
					import static com.google.common.base.Preconditions.checkNotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.common.collect.ImmutableList;
 | 
				
			||||||
import com.google.common.collect.ImmutableSet;
 | 
					import com.google.common.collect.ImmutableSet;
 | 
				
			||||||
import com.google.gerrit.common.Nullable;
 | 
					import com.google.gerrit.common.Nullable;
 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Account;
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
@@ -37,6 +38,7 @@ import com.google.inject.Provider;
 | 
				
			|||||||
import com.google.inject.Singleton;
 | 
					import com.google.inject.Singleton;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.sql.Timestamp;
 | 
					import java.sql.Timestamp;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.function.Consumer;
 | 
					import java.util.function.Consumer;
 | 
				
			||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
					import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
				
			||||||
import org.eclipse.jgit.lib.CommitBuilder;
 | 
					import org.eclipse.jgit.lib.CommitBuilder;
 | 
				
			||||||
@@ -251,20 +253,41 @@ public class AccountsUpdate {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  public Account atomicUpdate(ReviewDb db, Account.Id accountId, Consumer<Account> consumer)
 | 
					  public Account atomicUpdate(ReviewDb db, Account.Id accountId, Consumer<Account> consumer)
 | 
				
			||||||
      throws OrmException, IOException, ConfigInvalidException {
 | 
					      throws OrmException, IOException, ConfigInvalidException {
 | 
				
			||||||
 | 
					    return atomicUpdate(db, accountId, ImmutableList.of(consumer));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Gets the account and updates it atomically.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * <p>Changing the registration date of an account is not supported.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param db ReviewDb
 | 
				
			||||||
 | 
					   * @param accountId ID of the account
 | 
				
			||||||
 | 
					   * @param consumers consumers to update the account, only invoked if the account exists
 | 
				
			||||||
 | 
					   * @return the updated account, {@code null} if the account doesn't exist
 | 
				
			||||||
 | 
					   * @throws OrmException if updating the account fails
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public Account atomicUpdate(ReviewDb db, Account.Id accountId, List<Consumer<Account>> consumers)
 | 
				
			||||||
 | 
					      throws OrmException, IOException, ConfigInvalidException {
 | 
				
			||||||
 | 
					    if (consumers.isEmpty()) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update in ReviewDb
 | 
					    // Update in ReviewDb
 | 
				
			||||||
    db.accounts()
 | 
					    db.accounts()
 | 
				
			||||||
        .atomicUpdate(
 | 
					        .atomicUpdate(
 | 
				
			||||||
            accountId,
 | 
					            accountId,
 | 
				
			||||||
            a -> {
 | 
					            a -> {
 | 
				
			||||||
              consumer.accept(a);
 | 
					              consumers.stream().forEach(c -> c.accept(a));
 | 
				
			||||||
              return a;
 | 
					              return a;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update in NoteDb
 | 
					    // Update in NoteDb
 | 
				
			||||||
    AccountConfig accountConfig = read(accountId);
 | 
					    AccountConfig accountConfig = read(accountId);
 | 
				
			||||||
    Account account = accountConfig.getAccount();
 | 
					    Account account = accountConfig.getAccount();
 | 
				
			||||||
    consumer.accept(account);
 | 
					    consumers.stream().forEach(c -> c.accept(account));
 | 
				
			||||||
    commit(accountConfig);
 | 
					    commit(accountConfig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return account;
 | 
					    return account;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,7 +84,6 @@ import com.google.gerrit.server.IdentifiedUser;
 | 
				
			|||||||
import com.google.gerrit.server.PatchSetUtil;
 | 
					import com.google.gerrit.server.PatchSetUtil;
 | 
				
			||||||
import com.google.gerrit.server.Sequences;
 | 
					import com.google.gerrit.server.Sequences;
 | 
				
			||||||
import com.google.gerrit.server.account.AccountResolver;
 | 
					import com.google.gerrit.server.account.AccountResolver;
 | 
				
			||||||
import com.google.gerrit.server.account.Accounts;
 | 
					 | 
				
			||||||
import com.google.gerrit.server.account.AccountsUpdate;
 | 
					import com.google.gerrit.server.account.AccountsUpdate;
 | 
				
			||||||
import com.google.gerrit.server.change.ChangeInserter;
 | 
					import com.google.gerrit.server.change.ChangeInserter;
 | 
				
			||||||
import com.google.gerrit.server.change.SetHashtagsOp;
 | 
					import com.google.gerrit.server.change.SetHashtagsOp;
 | 
				
			||||||
@@ -302,7 +301,6 @@ public class ReceiveCommits {
 | 
				
			|||||||
  private final Sequences seq;
 | 
					  private final Sequences seq;
 | 
				
			||||||
  private final Provider<InternalChangeQuery> queryProvider;
 | 
					  private final Provider<InternalChangeQuery> queryProvider;
 | 
				
			||||||
  private final ChangeNotes.Factory notesFactory;
 | 
					  private final ChangeNotes.Factory notesFactory;
 | 
				
			||||||
  private final Accounts accounts;
 | 
					 | 
				
			||||||
  private final AccountsUpdate.Server accountsUpdate;
 | 
					  private final AccountsUpdate.Server accountsUpdate;
 | 
				
			||||||
  private final AccountResolver accountResolver;
 | 
					  private final AccountResolver accountResolver;
 | 
				
			||||||
  private final PermissionBackend permissionBackend;
 | 
					  private final PermissionBackend permissionBackend;
 | 
				
			||||||
@@ -377,7 +375,6 @@ public class ReceiveCommits {
 | 
				
			|||||||
      Sequences seq,
 | 
					      Sequences seq,
 | 
				
			||||||
      Provider<InternalChangeQuery> queryProvider,
 | 
					      Provider<InternalChangeQuery> queryProvider,
 | 
				
			||||||
      ChangeNotes.Factory notesFactory,
 | 
					      ChangeNotes.Factory notesFactory,
 | 
				
			||||||
      Accounts accounts,
 | 
					 | 
				
			||||||
      AccountsUpdate.Server accountsUpdate,
 | 
					      AccountsUpdate.Server accountsUpdate,
 | 
				
			||||||
      AccountResolver accountResolver,
 | 
					      AccountResolver accountResolver,
 | 
				
			||||||
      PermissionBackend permissionBackend,
 | 
					      PermissionBackend permissionBackend,
 | 
				
			||||||
@@ -417,7 +414,6 @@ public class ReceiveCommits {
 | 
				
			|||||||
    this.seq = seq;
 | 
					    this.seq = seq;
 | 
				
			||||||
    this.queryProvider = queryProvider;
 | 
					    this.queryProvider = queryProvider;
 | 
				
			||||||
    this.notesFactory = notesFactory;
 | 
					    this.notesFactory = notesFactory;
 | 
				
			||||||
    this.accounts = accounts;
 | 
					 | 
				
			||||||
    this.accountsUpdate = accountsUpdate;
 | 
					    this.accountsUpdate = accountsUpdate;
 | 
				
			||||||
    this.accountResolver = accountResolver;
 | 
					    this.accountResolver = accountResolver;
 | 
				
			||||||
    this.permissionBackend = permissionBackend;
 | 
					    this.permissionBackend = permissionBackend;
 | 
				
			||||||
@@ -2788,11 +2784,20 @@ public class ReceiveCommits {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (defaultName && user.hasEmailAddress(c.getCommitterIdent().getEmailAddress())) {
 | 
					        if (defaultName && user.hasEmailAddress(c.getCommitterIdent().getEmailAddress())) {
 | 
				
			||||||
          try {
 | 
					          try {
 | 
				
			||||||
            Account a = accounts.get(db, user.getAccountId());
 | 
					            String committerName = c.getCommitterIdent().getName();
 | 
				
			||||||
            if (a != null && Strings.isNullOrEmpty(a.getFullName())) {
 | 
					            Account account =
 | 
				
			||||||
              a.setFullName(c.getCommitterIdent().getName());
 | 
					                accountsUpdate
 | 
				
			||||||
              accountsUpdate.create().update(db, a);
 | 
					                    .create()
 | 
				
			||||||
              user.getAccount().setFullName(a.getFullName());
 | 
					                    .atomicUpdate(
 | 
				
			||||||
 | 
					                        db,
 | 
				
			||||||
 | 
					                        user.getAccountId(),
 | 
				
			||||||
 | 
					                        a -> {
 | 
				
			||||||
 | 
					                          if (Strings.isNullOrEmpty(a.getFullName())) {
 | 
				
			||||||
 | 
					                            a.setFullName(committerName);
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					            if (account != null && Strings.isNullOrEmpty(account.getFullName())) {
 | 
				
			||||||
 | 
					              user.getAccount().setFullName(account.getFullName());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          } catch (OrmException | IOException | ConfigInvalidException e) {
 | 
					          } catch (OrmException | IOException | ConfigInvalidException e) {
 | 
				
			||||||
            logWarn("Cannot default full_name", e);
 | 
					            logWarn("Cannot default full_name", e);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -496,11 +496,16 @@ public abstract class AbstractQueryAccountsTest extends GerritServerTests {
 | 
				
			|||||||
      if (email != null) {
 | 
					      if (email != null) {
 | 
				
			||||||
        accountManager.link(id, AuthRequest.forEmail(email));
 | 
					        accountManager.link(id, AuthRequest.forEmail(email));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Account a = accounts.get(db, id);
 | 
					      accountsUpdate
 | 
				
			||||||
      a.setFullName(fullName);
 | 
					          .create()
 | 
				
			||||||
      a.setPreferredEmail(email);
 | 
					          .atomicUpdate(
 | 
				
			||||||
      a.setActive(active);
 | 
					              db,
 | 
				
			||||||
      accountsUpdate.create().update(db, a);
 | 
					              id,
 | 
				
			||||||
 | 
					              a -> {
 | 
				
			||||||
 | 
					                a.setFullName(fullName);
 | 
				
			||||||
 | 
					                a.setPreferredEmail(email);
 | 
				
			||||||
 | 
					                a.setActive(active);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
      return id;
 | 
					      return id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -208,13 +208,11 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
 | 
				
			|||||||
    db = schemaFactory.open();
 | 
					    db = schemaFactory.open();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
 | 
					    userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
 | 
				
			||||||
    Account userAccount = accounts.get(db, userId);
 | 
					 | 
				
			||||||
    String email = "user@example.com";
 | 
					    String email = "user@example.com";
 | 
				
			||||||
    externalIdsUpdate.create().insert(ExternalId.createEmail(userId, email));
 | 
					    externalIdsUpdate.create().insert(ExternalId.createEmail(userId, email));
 | 
				
			||||||
    userAccount.setPreferredEmail(email);
 | 
					    accountsUpdate.create().atomicUpdate(db, userId, a -> a.setPreferredEmail(email));
 | 
				
			||||||
    accountsUpdate.create().update(db, userAccount);
 | 
					 | 
				
			||||||
    user = userFactory.create(userId);
 | 
					    user = userFactory.create(userId);
 | 
				
			||||||
    requestContext.setContext(newRequestContext(userAccount.getId()));
 | 
					    requestContext.setContext(newRequestContext(userId));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected RequestContext newRequestContext(Account.Id requestUserId) {
 | 
					  protected RequestContext newRequestContext(Account.Id requestUserId) {
 | 
				
			||||||
@@ -2340,11 +2338,16 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
 | 
				
			|||||||
      if (email != null) {
 | 
					      if (email != null) {
 | 
				
			||||||
        accountManager.link(id, AuthRequest.forEmail(email));
 | 
					        accountManager.link(id, AuthRequest.forEmail(email));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Account a = accounts.get(db, id);
 | 
					      accountsUpdate
 | 
				
			||||||
      a.setFullName(fullName);
 | 
					          .create()
 | 
				
			||||||
      a.setPreferredEmail(email);
 | 
					          .atomicUpdate(
 | 
				
			||||||
      a.setActive(active);
 | 
					              db,
 | 
				
			||||||
      accountsUpdate.create().update(db, a);
 | 
					              id,
 | 
				
			||||||
 | 
					              a -> {
 | 
				
			||||||
 | 
					                a.setFullName(fullName);
 | 
				
			||||||
 | 
					                a.setPreferredEmail(email);
 | 
				
			||||||
 | 
					                a.setActive(active);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
      return id;
 | 
					      return id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -319,11 +319,16 @@ public abstract class AbstractQueryGroupsTest extends GerritServerTests {
 | 
				
			|||||||
      if (email != null) {
 | 
					      if (email != null) {
 | 
				
			||||||
        accountManager.link(id, AuthRequest.forEmail(email));
 | 
					        accountManager.link(id, AuthRequest.forEmail(email));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Account a = accounts.get(db, id);
 | 
					      accountsUpdate
 | 
				
			||||||
      a.setFullName(fullName);
 | 
					          .create()
 | 
				
			||||||
      a.setPreferredEmail(email);
 | 
					          .atomicUpdate(
 | 
				
			||||||
      a.setActive(active);
 | 
					              db,
 | 
				
			||||||
      accountsUpdate.create().update(db, a);
 | 
					              id,
 | 
				
			||||||
 | 
					              a -> {
 | 
				
			||||||
 | 
					                a.setFullName(fullName);
 | 
				
			||||||
 | 
					                a.setPreferredEmail(email);
 | 
				
			||||||
 | 
					                a.setActive(active);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
      return id;
 | 
					      return id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user