blob: 7fe0ef7d8e300b2298c793e9fd16d979452a4c96 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/signin/signin_utils_desktop.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/chrome_signin_client.h"
#include "chrome/browser/signin/investigator_dependency_provider.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/guest_view/browser/guest_view_manager.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/browser/signin_pref_names.h"
#include "ui/base/l10n/l10n_util.h"
bool CanOfferSignin(Profile* profile,
CanOfferSigninType can_offer,
const std::string& gaia_id,
const std::string& email,
std::string* error_message) {
if (error_message)
error_message->clear();
if (!profile)
return false;
SigninManager* manager = SigninManagerFactory::GetForProfile(profile);
if (manager && !manager->IsSigninAllowed())
return false;
if (!ChromeSigninClient::ProfileAllowsSigninCookies(profile))
return false;
if (!email.empty()) {
if (!manager)
return false;
// Make sure this username is not prohibited by policy.
if (!manager->IsAllowedUsername(email)) {
if (error_message) {
error_message->assign(
l10n_util::GetStringUTF8(IDS_SYNC_LOGIN_NAME_PROHIBITED));
}
return false;
}
if (can_offer == CAN_OFFER_SIGNIN_FOR_SECONDARY_ACCOUNT)
return true;
// If the signin manager already has an authenticated name, then this is a
// re-auth scenario. Make sure the email just signed in corresponds to
// the one sign in manager expects.
std::string current_email = manager->GetAuthenticatedAccountInfo().email;
const bool same_email = gaia::AreEmailsSame(current_email, email);
if (!current_email.empty() && !same_email) {
UMA_HISTOGRAM_ENUMERATION("Signin.Reauth",
signin_metrics::HISTOGRAM_ACCOUNT_MISSMATCH,
signin_metrics::HISTOGRAM_REAUTH_MAX);
if (error_message) {
error_message->assign(l10n_util::GetStringFUTF8(
IDS_SYNC_WRONG_EMAIL, base::UTF8ToUTF16(current_email)));
}
return false;
}
// If some profile, not just the current one, is already connected to this
// account, don't show the infobar.
if (g_browser_process && !same_email) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
if (profile_manager) {
std::vector<ProfileAttributesEntry*> entries =
profile_manager->GetProfileAttributesStorage()
.GetAllProfilesAttributes();
for (const ProfileAttributesEntry* entry : entries) {
// For backward compatibility, need to check also the username of the
// profile, since the GAIA ID may not have been set yet in the
// ProfileAttributesStorage. It will be set once the profile
// is opened.
std::string profile_gaia_id = entry->GetGAIAId();
std::string profile_email = base::UTF16ToUTF8(entry->GetUserName());
if (gaia_id == profile_gaia_id ||
gaia::AreEmailsSame(email, profile_email)) {
if (error_message) {
error_message->assign(
l10n_util::GetStringUTF8(IDS_SYNC_USER_NAME_IN_USE_ERROR));
}
return false;
}
}
}
}
// With force sign in enabled, cross account sign in is not allowed.
if (signin_util::IsForceSigninEnabled() &&
IsCrossAccountError(profile, email, gaia_id)) {
if (error_message) {
std::string last_email =
profile->GetPrefs()->GetString(prefs::kGoogleServicesLastUsername);
error_message->assign(l10n_util::GetStringFUTF8(
IDS_SYNC_USED_PROFILE_ERROR, base::UTF8ToUTF16(last_email)));
}
return false;
}
}
return true;
}
bool IsCrossAccountError(Profile* profile,
const std::string& email,
const std::string& gaia_id) {
InvestigatorDependencyProvider provider(profile);
InvestigatedScenario scenario =
SigninInvestigator(email, gaia_id, &provider).Investigate();
return scenario == InvestigatedScenario::DIFFERENT_ACCOUNT;
}