summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Milanesio <luca.milanesio@gmail.com>2021-06-08 23:06:20 +0100
committerLuca Milanesio <luca.milanesio@gmail.com>2021-06-11 09:01:15 +0000
commit2794dd53c0346bf102b5146c5446e8201e5879a5 (patch)
tree294a0b178343fff55358e6352d9daaf436e4c1b9
parent8c741b0c81d2f8e80d4e874390e87b6d69ede802 (diff)
LocalUsernamesToLowerCase: manage duplication automatically
When having two external-ids that are different just in their case, the LocalUsernamesToLowerCase should automatically remove one of them and only keep the lowercase version. Example for the same account id: gerrit:MyUsername gerrit:MyUSERNAME The above two external-ids would have caused a DuplicateExternalIdKeyException which is not helpful as both identities are the same and associated with the same account id and have the same associated property values: - email - password Automatically remove one of the two (or more) identities in conflict and display a warning message explaining what has just happened and how the situation has been managed transparently. NOTE: The duplicates that are getting removed are identical once they are converted to lowercase. The ones that are getting deleted are not relevant: the only thing that is important is that only one of them is kept, as all the others are identical. To test this change: Positive use-case: -- Before the LocalUsernamesToLowerCase execution: [externalId "gerrit:johndoe"] accountId = 1000000 email = john@doe.org [externalId "gerrit:JohnDoe"] accountId = 1000000 email = JOHN@doe.org After the LocalUsernamesToLowerCase execution, there is a single entry: [externalId "gerrit:johndoe"] accountId = 1000000 email = john@doe.org OR [externalId "gerrit:johndoe"] accountId = 1000000 email = JOHN@doe.org Negative use-cases: [externalId "gerrit:johndoe"] accountId = 1000000 [externalId "gerrit:JohnDoe"] accountId = 1000000 email = JOHN@doe.org The LocalUsernamesToLowerCase execution fails with a duplicated ids exception and no changes are made on the external ids. [externalId "gerrit:johndoe"] accountId = 1000000 [externalId "gerrit:JohnDoe"] accountId = 1000001 The LocalUsernamesToLowerCase execution fails with a duplicated ids exception and no changes are made on the external ids. Bug: Issue 14645 Change-Id: I9832fbf0c8df947aab5494325169b9c726e40019
-rw-r--r--Documentation/pgm-LocalUsernamesToLowerCase.txt6
-rw-r--r--java/com/google/gerrit/pgm/BUILD1
-rw-r--r--java/com/google/gerrit/pgm/LocalUsernamesToLowerCase.java33
3 files changed, 39 insertions, 1 deletions
diff --git a/Documentation/pgm-LocalUsernamesToLowerCase.txt b/Documentation/pgm-LocalUsernamesToLowerCase.txt
index 53081a18ba..a526647624 100644
--- a/Documentation/pgm-LocalUsernamesToLowerCase.txt
+++ b/Documentation/pgm-LocalUsernamesToLowerCase.txt
@@ -28,10 +28,14 @@ Web UI.
Please be aware that the conversion of the local usernames to lower
case can't be undone.
-The program will produce errors if there are accounts that have the
+The program will produce errors if there are accounts with a different
+account-id or other properties (e.g. email, password) that have the
same local username, but with different case. In this case the local
username for these accounts is not converted to lower case.
+The program will automatically remove duplicates where the username
+differs only in case but all other attributes are identical.
+
After all usernames have been migrated, the link:pgm-reindex.html[
reindex] program is automatically invoked to reindex all accounts.
diff --git a/java/com/google/gerrit/pgm/BUILD b/java/com/google/gerrit/pgm/BUILD
index a57b37a505..2b1b83d643 100644
--- a/java/com/google/gerrit/pgm/BUILD
+++ b/java/com/google/gerrit/pgm/BUILD
@@ -46,6 +46,7 @@ java_library(
"//lib:servlet-api-without-neverlink",
"//lib/auto:auto-value",
"//lib/auto:auto-value-annotations",
+ "//lib/commons:lang",
"//lib/flogger:api",
"//lib/guice",
"//lib/guice:guice-assistedinject",
diff --git a/java/com/google/gerrit/pgm/LocalUsernamesToLowerCase.java b/java/com/google/gerrit/pgm/LocalUsernamesToLowerCase.java
index e6e091c360..8e2f70f5f0 100644
--- a/java/com/google/gerrit/pgm/LocalUsernamesToLowerCase.java
+++ b/java/com/google/gerrit/pgm/LocalUsernamesToLowerCase.java
@@ -36,6 +36,9 @@ import com.google.inject.Provider;
import java.io.IOException;
import java.util.Collection;
import java.util.Locale;
+import java.util.Optional;
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TextProgressMonitor;
@@ -108,8 +111,38 @@ public class LocalUsernamesToLowerCase extends SiteProgram {
extId.accountId(),
extId.email(),
extId.password());
+ replaceIfNotExists(extIdNotes, extId, extIdLowerCase);
+ }
+ }
+ }
+
+ private void replaceIfNotExists(
+ ExternalIdNotes extIdNotes, ExternalId extId, ExternalId extIdLowerCase) throws IOException {
+ try {
+ Optional<ExternalId> existingExternalId =
+ extIdNotes
+ .get(extIdLowerCase.key())
+ .filter(eid -> eid.accountId().equals(extIdLowerCase.accountId()))
+ .filter(eid -> StringUtils.equalsIgnoreCase(eid.email(), extId.email()))
+ .filter(eid -> StringUtils.equalsIgnoreCase(eid.password(), extId.password()));
+ if (existingExternalId.isPresent()) {
+ System.err.println(
+ "WARNING: external-id "
+ + extIdLowerCase
+ + " already exists with the same account-id "
+ + extId.accountId()
+ + " :"
+ + "removing the duplicate external-id "
+ + extId.key());
+ extIdNotes.delete(extId);
+ } else {
extIdNotes.replace(extId, extIdLowerCase);
}
+ } catch (ConfigInvalidException e) {
+ throw new IOException(
+ "Unable to parse external id definition when looking for current external-id "
+ + extIdLowerCase,
+ e);
}
}