diff options
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java')
-rw-r--r-- | gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java index e738c6fab9..3dce94e9ef 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountResolver.java @@ -15,12 +15,14 @@ package com.google.gerrit.server.account; import com.google.gerrit.reviewdb.Account; +import com.google.gerrit.reviewdb.AccountExternalId; import com.google.gerrit.reviewdb.ReviewDb; import com.google.gwtorm.client.OrmException; -import com.google.gwtorm.client.ResultSet; import com.google.inject.Inject; import com.google.inject.Provider; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Matcher; @@ -52,28 +54,37 @@ public class AccountResolver { * there are multiple candidates. */ public Account find(final String nameOrEmail) throws OrmException { + Set<Account.Id> r = findAll(nameOrEmail); + return r.size() == 1 ? byId.get(r.iterator().next()).getAccount() : null; + } + + /** + * Locate exactly one account matching the name or name/email string. + * + * @param nameOrEmail a string of the format + * "Full Name <email@example>", just the email address + * ("email@example"), a full name ("Full Name"), an account id + * ("18419") or an user name ("username"). + * @return the accounts that match, empty collection if none. Never null. + */ + public Set<Account.Id> findAll(String nameOrEmail) throws OrmException { Matcher m = Pattern.compile("^.* \\(([1-9][0-9]*)\\)$").matcher(nameOrEmail); if (m.matches()) { - return byId.get(Account.Id.parse(m.group(1))).getAccount(); + return Collections.singleton(Account.Id.parse(m.group(1))); } if (nameOrEmail.matches("^[1-9][0-9]*$")) { - return byId.get(Account.Id.parse(nameOrEmail)).getAccount(); + return Collections.singleton(Account.Id.parse(nameOrEmail)); } if (nameOrEmail.matches(Account.USER_NAME_PATTERN)) { - Account who = findByUserName(nameOrEmail); + AccountState who = byId.getByUsername(nameOrEmail); if (who != null) { - return who; + return Collections.singleton(who.getAccount().getId()); } } - Account account = findByNameOrEmail(nameOrEmail); - if (account != null) { - return account; - } - - return null; + return findAllByNameOrEmail(nameOrEmail); } /** @@ -87,39 +98,61 @@ public class AccountResolver { */ public Account findByNameOrEmail(final String nameOrEmail) throws OrmException { + Set<Account.Id> r = findAllByNameOrEmail(nameOrEmail); + return r.size() == 1 ? byId.get(r.iterator().next()).getAccount() : null; + } + + /** + * Locate exactly one account matching the name or name/email string. + * + * @param nameOrEmail a string of the format + * "Full Name <email@example>", just the email address + * ("email@example"), a full name ("Full Name"). + * @return the accounts that match, empty collection if none. Never null. + */ + public Set<Account.Id> findAllByNameOrEmail(final String nameOrEmail) + throws OrmException { final int lt = nameOrEmail.indexOf('<'); final int gt = nameOrEmail.indexOf('>'); if (lt >= 0 && gt > lt && nameOrEmail.contains("@")) { - return findByEmail(nameOrEmail.substring(lt + 1, gt)); + return byEmail.get(nameOrEmail.substring(lt + 1, gt)); } if (nameOrEmail.contains("@")) { - return findByEmail(nameOrEmail); + return byEmail.get(nameOrEmail); } final Account.Id id = realm.lookup(nameOrEmail); if (id != null) { - return byId.get(id).getAccount(); + return Collections.singleton(id); } - return oneAccount(schema.get().accounts().byFullName(nameOrEmail)); - } - - private Account findByEmail(final String email) { - final Set<Account.Id> candidates = byEmail.get(email); - if (1 == candidates.size()) { - return byId.get(candidates.iterator().next()).getAccount(); + List<Account> m = schema.get().accounts().byFullName(nameOrEmail).toList(); + if (m.size() == 1) { + return Collections.singleton(m.get(0).getId()); } - return null; - } - - private static Account oneAccount(final ResultSet<Account> rs) { - final List<Account> r = rs.toList(); - return r.size() == 1 ? r.get(0) : null; - } - private Account findByUserName(final String userName) { - AccountState as = byId.getByUsername(userName); - return as != null ? as.getAccount() : null; + // At this point we have no clue. Just perform a whole bunch of suggestions + // and pray we come up with a reasonable result list. + // + Set<Account.Id> result = new HashSet<Account.Id>(); + String a = nameOrEmail; + String b = nameOrEmail + "\u9fa5"; + for (Account act : schema.get().accounts().suggestByFullName(a, b, 10)) { + result.add(act.getId()); + } + for (AccountExternalId extId : schema + .get() + .accountExternalIds() + .suggestByKey( + new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, a), + new AccountExternalId.Key(AccountExternalId.SCHEME_USERNAME, b), 10)) { + result.add(extId.getAccountId()); + } + for (AccountExternalId extId : schema.get().accountExternalIds() + .suggestByEmailAddress(a, b, 10)) { + result.add(extId.getAccountId()); + } + return result; } } |