Search in sources :

Example 1 with ExternalIdsUpdate

use of com.google.gerrit.server.account.externalids.ExternalIdsUpdate in project gerrit by GerritCodeReview.

the class ExternalIdIT method failAfterRetryerGivesUp.

@Test
public void failAfterRetryerGivesUp() throws Exception {
    ExternalId.Key[] extIdsKeys = { ExternalId.Key.create("foo", "foo"), ExternalId.Key.create("bar", "bar"), ExternalId.Key.create("baz", "baz") };
    final AtomicInteger bgCounter = new AtomicInteger(0);
    ExternalIdsUpdate update = new ExternalIdsUpdate(repoManager, allUsers, metricMaker, externalIds, new DisabledExternalIdCache(), serverIdent.get(), serverIdent.get(), () -> {
        try {
            extIdsUpdate.create().insert(ExternalId.create(extIdsKeys[bgCounter.getAndAdd(1)], admin.id));
        } catch (IOException | ConfigInvalidException | OrmException e) {
        // Ignore, the successful insertion of the external ID is asserted later
        }
    }, RetryerBuilder.<RefsMetaExternalIdsUpdate>newBuilder().retryIfException(e -> e instanceof LockFailureException).withStopStrategy(StopStrategies.stopAfterAttempt(extIdsKeys.length)).build());
    assertThat(bgCounter.get()).isEqualTo(0);
    try {
        update.insert(ExternalId.create(ExternalId.Key.create("abc", "abc"), admin.id));
        fail("expected LockFailureException");
    } catch (LockFailureException e) {
    // Ignore, expected
    }
    assertThat(bgCounter.get()).isEqualTo(extIdsKeys.length);
    for (ExternalId.Key extIdKey : extIdsKeys) {
        assertThat(externalIds.get(extIdKey)).isNotNull();
    }
}
Also used : AllUsersName(com.google.gerrit.server.config.AllUsersName) TypeToken(com.google.gson.reflect.TypeToken) OrmException(com.google.gwtorm.server.OrmException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) OBJ_BLOB(org.eclipse.jgit.lib.Constants.OBJ_BLOB) GlobalCapability(com.google.gerrit.common.data.GlobalCapability) Retryer(com.github.rholder.retry.Retryer) RetryerBuilder(com.github.rholder.retry.RetryerBuilder) Inject(com.google.inject.Inject) RestResponse(com.google.gerrit.acceptance.RestResponse) REGISTERED_USERS(com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS) BlockStrategy(com.github.rholder.retry.BlockStrategy) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Config(org.eclipse.jgit.lib.Config) SCHEME_USERNAME(com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME) ConsistencyProblemInfo(com.google.gerrit.extensions.api.config.ConsistencyCheckInfo.ConsistencyProblemInfo) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Locale(java.util.Locale) AuthException(com.google.gerrit.extensions.restapi.AuthException) Assert.fail(org.junit.Assert.fail) SCHEME_UUID(com.google.gerrit.server.account.externalids.ExternalId.SCHEME_UUID) NoteMap(org.eclipse.jgit.notes.NoteMap) CheckAccountExternalIdsInput(com.google.gerrit.extensions.api.config.ConsistencyCheckInput.CheckAccountExternalIdsInput) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Permission(com.google.gerrit.common.data.Permission) ConsistencyCheckInfo(com.google.gerrit.extensions.api.config.ConsistencyCheckInfo) Set(java.util.Set) ExternalIds(com.google.gerrit.server.account.externalids.ExternalIds) List(java.util.List) StopStrategies(com.github.rholder.retry.StopStrategies) RefNames(com.google.gerrit.reviewdb.client.RefNames) PushResult(org.eclipse.jgit.transport.PushResult) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) MetricMaker(com.google.gerrit.metrics.MetricMaker) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) GitUtil.fetch(com.google.gerrit.acceptance.GitUtil.fetch) Iterables(com.google.common.collect.Iterables) Status(org.eclipse.jgit.transport.RemoteRefUpdate.Status) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) InMemoryRepository(org.eclipse.jgit.internal.storage.dfs.InMemoryRepository) OrmDuplicateKeyException(com.google.gwtorm.server.OrmDuplicateKeyException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RefsMetaExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate) LockFailureException(com.google.gerrit.server.git.LockFailureException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) DisabledExternalIdCache(com.google.gerrit.server.account.externalids.DisabledExternalIdCache) ImmutableList(com.google.common.collect.ImmutableList) AccountExternalIdInfo(com.google.gerrit.extensions.common.AccountExternalIdInfo) Account(com.google.gerrit.reviewdb.client.Account) ConsistencyCheckInput(com.google.gerrit.extensions.api.config.ConsistencyCheckInput) GitUtil.pushHead(com.google.gerrit.acceptance.GitUtil.pushHead) TestRepository(org.eclipse.jgit.junit.TestRepository) Sandboxed(com.google.gerrit.acceptance.Sandboxed) UTF_8(java.nio.charset.StandardCharsets.UTF_8) ExternalIdReader(com.google.gerrit.server.account.externalids.ExternalIdReader) IOException(java.io.IOException) Test(org.junit.Test) Truth.assertThat(com.google.common.truth.Truth.assertThat) SCHEME_MAILTO(com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO) MutableInteger(org.eclipse.jgit.util.MutableInteger) ObjectId(org.eclipse.jgit.lib.ObjectId) TransportException(org.eclipse.jgit.api.errors.TransportException) Collectors.toList(java.util.stream.Collectors.toList) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) Collections(java.util.Collections) Repository(org.eclipse.jgit.lib.Repository) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) RefsMetaExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) RefsMetaExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) IOException(java.io.IOException) LockFailureException(com.google.gerrit.server.git.LockFailureException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) OrmException(com.google.gwtorm.server.OrmException) DisabledExternalIdCache(com.google.gerrit.server.account.externalids.DisabledExternalIdCache) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) Test(org.junit.Test)

Example 2 with ExternalIdsUpdate

use of com.google.gerrit.server.account.externalids.ExternalIdsUpdate in project gerrit by GerritCodeReview.

the class ExternalIdIT method retryOnLockFailure.

@Test
public void retryOnLockFailure() throws Exception {
    Retryer<RefsMetaExternalIdsUpdate> retryer = ExternalIdsUpdate.retryerBuilder().withBlockStrategy(new BlockStrategy() {

        @Override
        public void block(long sleepTime) {
        // Don't sleep in tests.
        }
    }).build();
    ExternalId.Key fooId = ExternalId.Key.create("foo", "foo");
    ExternalId.Key barId = ExternalId.Key.create("bar", "bar");
    final AtomicBoolean doneBgUpdate = new AtomicBoolean(false);
    ExternalIdsUpdate update = new ExternalIdsUpdate(repoManager, allUsers, metricMaker, externalIds, new DisabledExternalIdCache(), serverIdent.get(), serverIdent.get(), () -> {
        if (!doneBgUpdate.getAndSet(true)) {
            try {
                extIdsUpdate.create().insert(ExternalId.create(barId, admin.id));
            } catch (IOException | ConfigInvalidException | OrmException e) {
            // Ignore, the successful insertion of the external ID is asserted later
            }
        }
    }, retryer);
    assertThat(doneBgUpdate.get()).isFalse();
    update.insert(ExternalId.create(fooId, admin.id));
    assertThat(doneBgUpdate.get()).isTrue();
    assertThat(externalIds.get(fooId)).isNotNull();
    assertThat(externalIds.get(barId)).isNotNull();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) RefsMetaExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate) OrmException(com.google.gwtorm.server.OrmException) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) RefsMetaExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate) IOException(java.io.IOException) BlockStrategy(com.github.rholder.retry.BlockStrategy) DisabledExternalIdCache(com.google.gerrit.server.account.externalids.DisabledExternalIdCache) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) Test(org.junit.Test)

Example 3 with ExternalIdsUpdate

use of com.google.gerrit.server.account.externalids.ExternalIdsUpdate in project gerrit by GerritCodeReview.

the class ChangeUserName method call.

@Override
public VoidResult call() throws OrmException, NameAlreadyUsedException, InvalidUserNameException, IOException, ConfigInvalidException {
    Collection<ExternalId> old = externalIds.byAccount(user.getAccountId(), SCHEME_USERNAME);
    if (!old.isEmpty()) {
        throw new IllegalStateException(USERNAME_CANNOT_BE_CHANGED);
    }
    ExternalIdsUpdate externalIdsUpdate = externalIdsUpdateFactory.create();
    if (newUsername != null && !newUsername.isEmpty()) {
        if (!USER_NAME_PATTERN.matcher(newUsername).matches()) {
            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(ExternalId.create(key, user.getAccountId(), null, password));
        } catch (OrmDuplicateKeyException dupeErr) {
            // If we are using this identity, don't report the exception.
            //
            ExternalId other = externalIds.get(key);
            if (other != null && other.accountId().equals(user.getAccountId())) {
                return VoidResult.INSTANCE;
            }
            //
            throw new NameAlreadyUsedException(newUsername);
        }
    }
    // If we have any older user names, remove them.
    //
    externalIdsUpdate.delete(old);
    for (ExternalId extId : old) {
        sshKeyCache.evict(extId.key().id());
        accountCache.evictByUsername(extId.key().id());
    }
    accountCache.evict(user.getAccountId());
    accountCache.evictByUsername(newUsername);
    sshKeyCache.evict(newUsername);
    return VoidResult.INSTANCE;
}
Also used : OrmDuplicateKeyException(com.google.gwtorm.server.OrmDuplicateKeyException) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) NameAlreadyUsedException(com.google.gerrit.common.errors.NameAlreadyUsedException)

Example 4 with ExternalIdsUpdate

use of com.google.gerrit.server.account.externalids.ExternalIdsUpdate in project gerrit by GerritCodeReview.

the class CreateAccount method apply.

@Override
public Response<AccountInfo> apply(TopLevelResource rsrc, AccountInput input) throws BadRequestException, ResourceConflictException, UnprocessableEntityException, OrmException, IOException, ConfigInvalidException {
    if (input == null) {
        input = new AccountInput();
    }
    if (input.username != null && !username.equals(input.username)) {
        throw new BadRequestException("username must match URL");
    }
    if (!username.matches(Account.USER_NAME_PATTERN)) {
        throw new BadRequestException("Username '" + username + "' must contain only letters, numbers, _, - or .");
    }
    Set<AccountGroup.Id> groups = parseGroups(input.groups);
    Account.Id id = new Account.Id(db.nextAccountId());
    ExternalId extUser = ExternalId.createUsername(username, id, input.httpPassword);
    if (externalIds.get(extUser.key()) != null) {
        throw new ResourceConflictException("username '" + username + "' already exists");
    }
    if (input.email != null) {
        if (externalIds.get(ExternalId.Key.create(SCHEME_MAILTO, input.email)) != null) {
            throw new UnprocessableEntityException("email '" + input.email + "' already exists");
        }
        if (!validator.isValid(input.email)) {
            throw new BadRequestException("invalid email address");
        }
    }
    List<ExternalId> extIds = new ArrayList<>();
    extIds.add(extUser);
    for (AccountExternalIdCreator c : externalIdCreators) {
        extIds.addAll(c.create(id, username, input.email));
    }
    ExternalIdsUpdate externalIdsUpdate = externalIdsUpdateFactory.create();
    try {
        externalIdsUpdate.insert(extIds);
    } catch (OrmDuplicateKeyException duplicateKey) {
        throw new ResourceConflictException("username '" + username + "' already exists");
    }
    if (input.email != null) {
        try {
            externalIdsUpdate.insert(ExternalId.createEmail(id, input.email));
        } catch (OrmDuplicateKeyException duplicateKey) {
            try {
                externalIdsUpdate.delete(extUser);
            } catch (IOException | ConfigInvalidException cleanupError) {
            // Ignored
            }
            throw new UnprocessableEntityException("email '" + input.email + "' already exists");
        }
    }
    Account a = new Account(id, TimeUtil.nowTs());
    a.setFullName(input.name);
    a.setPreferredEmail(input.email);
    accountsUpdate.create().insert(db, a);
    for (AccountGroup.Id groupId : groups) {
        AccountGroupMember m = new AccountGroupMember(new AccountGroupMember.Key(id, groupId));
        auditService.dispatchAddAccountsToGroup(currentUser.get().getAccountId(), Collections.singleton(m));
        db.accountGroupMembers().insert(Collections.singleton(m));
    }
    if (input.sshKey != null) {
        try {
            authorizedKeys.addKey(id, input.sshKey);
            sshKeyCache.evict(username);
        } catch (InvalidSshKeyException e) {
            throw new BadRequestException(e.getMessage());
        }
    }
    accountCache.evictByUsername(username);
    byEmailCache.evict(input.email);
    indexer.index(id);
    AccountLoader loader = infoLoader.create(true);
    AccountInfo info = loader.get(id);
    loader.fill();
    return Response.created(info);
}
Also used : Account(com.google.gerrit.reviewdb.client.Account) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) AccountGroupMember(com.google.gerrit.reviewdb.client.AccountGroupMember) OrmDuplicateKeyException(com.google.gwtorm.server.OrmDuplicateKeyException) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) ExternalIdsUpdate(com.google.gerrit.server.account.externalids.ExternalIdsUpdate) ArrayList(java.util.ArrayList) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) AccountExternalIdCreator(com.google.gerrit.server.api.accounts.AccountExternalIdCreator) InvalidSshKeyException(com.google.gerrit.common.errors.InvalidSshKeyException) AccountGroup(com.google.gerrit.reviewdb.client.AccountGroup) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) AccountInput(com.google.gerrit.extensions.api.accounts.AccountInput) AccountInfo(com.google.gerrit.extensions.common.AccountInfo)

Aggregations

ExternalId (com.google.gerrit.server.account.externalids.ExternalId)4 ExternalIdsUpdate (com.google.gerrit.server.account.externalids.ExternalIdsUpdate)4 OrmDuplicateKeyException (com.google.gwtorm.server.OrmDuplicateKeyException)3 BlockStrategy (com.github.rholder.retry.BlockStrategy)2 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)2 Account (com.google.gerrit.reviewdb.client.Account)2 DisabledExternalIdCache (com.google.gerrit.server.account.externalids.DisabledExternalIdCache)2 RefsMetaExternalIdsUpdate (com.google.gerrit.server.account.externalids.ExternalIdsUpdate.RefsMetaExternalIdsUpdate)2 OrmException (com.google.gwtorm.server.OrmException)2 IOException (java.io.IOException)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)2 Test (org.junit.Test)2 Retryer (com.github.rholder.retry.Retryer)1 RetryerBuilder (com.github.rholder.retry.RetryerBuilder)1 StopStrategies (com.github.rholder.retry.StopStrategies)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Iterables (com.google.common.collect.Iterables)1 Truth.assertThat (com.google.common.truth.Truth.assertThat)1