summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInderjot Kaur Ratol <inderjot.kaur.ratol@ericsson.com>2018-02-23 09:20:41 -0500
committerDavid Pursehouse <dpursehouse@collab.net>2018-03-12 10:57:36 +0900
commitfcc90699fdec17b941a473221d228c832a533fc0 (patch)
treea63fe1b0ce749ab763bb0b6229328cf92e9bf742
parente0072fdd7a6a1e8ca90d0546cf5817c651f658af (diff)
Fix the missing DB entry in Gerrit DBv2.14.7
Due to an unknown reason (still under investigation), a few of the new LDAP users were not able to login after first time because the Gerrit DB was missing one of the two entries needed to authenticate the user (the second entry is only needed for the users with non-null usernames). The entry with external Id - "gerrit:abc" was never inserted to DB in such cases whereas the entry with external id - "username:abc" was created resulting in an account creation for the user. This causes inconsistency in the DB. An account gets created in first login attempt and second attempt fails to create missing external id because the "username:abc" entry already exists causing the DB action to rollback. As this bug is very infrequent and hard to replicate, this change provides an after-fix for the issue i.e. fixes the problem when an entry is missing in Gerrit DB. It checks if there exists an account already for the given username and links the newly created external ID to that account. It prevents the need to manually enter the missing entries in DB to solve the issue. Bug: Issue 7652 Change-Id: Icd2fbf77971f00783277f88fa085ea1bc761878f
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java18
1 files changed, 18 insertions, 0 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
index cb06c66c86..38ffeb82c2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
@@ -14,6 +14,7 @@
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.common.base.Strings;
@@ -107,8 +108,22 @@ public class AccountManager {
try (ReviewDb db = schema.open()) {
ExternalId id = findExternalId(db, who.getExternalIdKey());
if (id == null) {
+ if (who.getUserName() != null) {
+ ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, who.getUserName());
+ ExternalId existingId = findExternalId(db, key);
+ if (existingId != null) {
+ // An inconsistency is detected in the database, having a record for scheme "username:"
+ // but no record for scheme "gerrit:". Try to recover by linking
+ // "gerrit:" identity to the existing account.
+ log.warn(
+ "User {} already has an account; link new identity to the existing account.",
+ who.getUserName());
+ return link(existingId.accountId(), who);
+ }
+ }
// New account, automatically create and return.
//
+ log.info("External ID not found. Attempting to create new account.");
return create(db, who);
}
@@ -348,13 +363,16 @@ public class AccountManager {
public AuthResult link(Account.Id to, AuthRequest who)
throws AccountException, OrmException, IOException {
try (ReviewDb db = schema.open()) {
+ log.info("Link another authentication identity to an existing account");
ExternalId extId = findExternalId(db, who.getExternalIdKey());
if (extId != null) {
if (!extId.accountId().equals(to)) {
throw new AccountException("Identity in use by another account");
}
+ log.info("Updating existing external ID data");
update(db, who, extId);
} else {
+ log.info("Linking new external ID to the existing account");
externalIdsUpdateFactory
.create()
.insert(