All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.query.account.InternalAccountQuery Maven / Gradle / Ivy

The newest version!
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.query.account;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.UsedAt;
import com.google.gerrit.entities.Project;
import com.google.gerrit.index.IndexConfig;
import com.google.gerrit.index.query.InternalQuery;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdKeyFactory;
import com.google.gerrit.server.config.AccountConfig;
import com.google.gerrit.server.index.account.AccountIndexCollection;
import com.google.inject.Inject;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
 * Query wrapper for the account index.
 *
 * 

Instances are one-time-use. Other singleton classes should inject a Provider rather than * holding on to a single instance. */ public class InternalAccountQuery extends InternalQuery { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final AccountConfig accountConfig; private final ExternalIdKeyFactory externalIdKeyFactory; @Inject InternalAccountQuery( AccountQueryProcessor queryProcessor, AccountIndexCollection indexes, IndexConfig indexConfig, ExternalIdKeyFactory externalIdKeyFactory, AccountConfig accountConfig) { super(queryProcessor, indexes, indexConfig); this.accountConfig = accountConfig; this.externalIdKeyFactory = externalIdKeyFactory; } public List byDefault(String query, boolean canSeeSecondaryEmails) { return query(AccountPredicates.defaultPredicate(schema(), canSeeSecondaryEmails, query)); } public List byExternalId(String scheme, String id) { return byExternalId(externalIdKeyFactory.create(scheme, id)); } public List byExternalId(ExternalId.Key externalId) { return query(AccountPredicates.externalIdIncludingSecondaryEmails(externalId.toString())); } @Nullable @UsedAt(UsedAt.Project.COLLABNET) public AccountState oneByExternalId(ExternalId.Key externalId) { List accountStates = byExternalId(externalId); if (accountStates.size() == 1) { return accountStates.get(0); } else if (!accountStates.isEmpty()) { StringBuilder msg = new StringBuilder(); msg.append("Ambiguous external ID ").append(externalId).append(" for accounts: "); Joiner.on(", ") .appendTo( msg, accountStates.stream().map(a -> a.account().id().toString()).collect(toList())); logger.atWarning().log("%s", msg); } return null; } public List byFullName(String fullName) { return query(AccountPredicates.fullName(fullName)); } /** * Queries for accounts that have a preferred email that matches the given email. * *

The local part of the email is compared either in a case-insensitive or case-sensitive * manner, depending on the configuration parameter {@code accounts.caseInsensitiveLocalPart}. * Check the configuration documentation for more details. * * @param email preferred email by which accounts should be found * @return list of accounts that have a preferred email that exactly matches the given email */ public List byPreferredEmail(String email) { return query(getPreferredEmailPredicate(email)).stream() .filter(a -> normalizeEmail(a.account().preferredEmail()).equals(normalizeEmail(email))) .collect(toList()); } /** * Makes multiple queries for accounts by preferred email. * *

The local part of the email is compared either in a case-insensitive or case-sensitive * manner, depending on the configuration parameter {@code accounts.caseInsensitiveLocalPart}. * Check the configuration documentation for more details. * * @param emails preferred emails by which accounts should be found * @return multimap of the given emails to accounts that have a preferred email that exactly * matches this email */ public Multimap byPreferredEmail(List emails) { List> r = query(emails.stream().map(email -> getPreferredEmailPredicate(email)).collect(toList())); ListMultimap accountsByEmail = ArrayListMultimap.create(); for (int i = 0; i < emails.size(); i++) { String email = emails.get(i); Set matchingAccounts = r.get(i).stream() .filter( a -> normalizeEmail(a.account().preferredEmail()).equals(normalizeEmail(email))) .collect(toSet()); accountsByEmail.putAll(email, matchingAccounts); } return accountsByEmail; } public List byWatchedProject(Project.NameKey project) { return query(AccountPredicates.watchedProject(project)); } private Predicate getPreferredEmailPredicate(String email) { return useCaseInsensitiveLocalParts(email) ? AccountPredicates.preferredEmail(normalizeEmail(email)) : AccountPredicates.preferredEmailExact(email); } private String normalizeEmail(String email) { return useCaseInsensitiveLocalParts(email) ? email.toLowerCase(Locale.US) : email; } private boolean useCaseInsensitiveLocalParts(String email) { return Arrays.asList(accountConfig.getCaseInsensitiveLocalParts()) .contains(getLowerCaseEmailDomain(email)); } private String getLowerCaseEmailDomain(String email) { String[] parts = email.split("@", 2); // The caller method byPreferredEmail can be invoked with the local part // of the email only. Handle this case by just returning it. if (parts.length != 2) { return email; } return parts[1].toLowerCase(Locale.US); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy