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();
}
}
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();
}
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;
}
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);
}
Aggregations