Reland of: Only store leading 13 bits of password hash.
[chromium-blink-merge.git] / chrome / browser / signin / chrome_signin_client.cc
blob3315642feb9a65d863c68396308cd8c2147ae100
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/signin/chrome_signin_client.h"
7 #include "base/command_line.h"
8 #include "base/guid.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/content_settings/cookie_settings.h"
13 #include "chrome/browser/net/chrome_cookie_notification_details.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/profiles/profile_metrics.h"
17 #include "chrome/browser/profiles/profile_window.h"
18 #include "chrome/browser/signin/local_auth.h"
19 #include "chrome/browser/signin/signin_cookie_changed_subscription.h"
20 #include "chrome/browser/webdata/web_data_service_factory.h"
21 #include "chrome/common/chrome_version_info.h"
22 #include "components/metrics/metrics_service.h"
23 #include "components/signin/core/common/profile_management_switches.h"
24 #include "components/signin/core/common/signin_pref_names.h"
25 #include "components/signin/core/common/signin_switches.h"
26 #include "content/public/browser/render_process_host.h"
27 #include "content/public/common/child_process_host.h"
28 #include "net/url_request/url_request_context_getter.h"
29 #include "url/gurl.h"
31 #if defined(ENABLE_SUPERVISED_USERS)
32 #include "chrome/browser/supervised_user/supervised_user_constants.h"
33 #endif
35 #if defined(OS_CHROMEOS)
36 #include "components/user_manager/user_manager.h"
37 #endif
39 #if !defined(OS_ANDROID)
40 #include "chrome/browser/first_run/first_run.h"
41 #endif
43 using content::ChildProcessHost;
44 using content::RenderProcessHost;
46 namespace {
48 const char kGoogleAccountsUrl[] = "https://accounts.google.com";
50 } // namespace
52 ChromeSigninClient::ChromeSigninClient(
53 Profile* profile, SigninErrorController* signin_error_controller)
54 : profile_(profile),
55 signin_error_controller_(signin_error_controller),
56 signin_host_id_(ChildProcessHost::kInvalidUniqueID) {
57 signin_error_controller_->AddObserver(this);
60 ChromeSigninClient::~ChromeSigninClient() {
61 signin_error_controller_->RemoveObserver(this);
62 std::set<RenderProcessHost*>::iterator i;
63 for (i = signin_hosts_observed_.begin(); i != signin_hosts_observed_.end();
64 ++i) {
65 (*i)->RemoveObserver(this);
69 // static
70 bool ChromeSigninClient::ProfileAllowsSigninCookies(Profile* profile) {
71 CookieSettings* cookie_settings =
72 CookieSettings::Factory::GetForProfile(profile).get();
73 return SettingsAllowSigninCookies(cookie_settings);
76 // static
77 bool ChromeSigninClient::SettingsAllowSigninCookies(
78 CookieSettings* cookie_settings) {
79 return cookie_settings &&
80 cookie_settings->IsSettingCookieAllowed(GURL(kGoogleAccountsUrl),
81 GURL(kGoogleAccountsUrl));
84 void ChromeSigninClient::SetSigninProcess(int process_id) {
85 if (process_id == signin_host_id_)
86 return;
87 DLOG_IF(WARNING, signin_host_id_ != ChildProcessHost::kInvalidUniqueID)
88 << "Replacing in-use signin process.";
89 signin_host_id_ = process_id;
90 RenderProcessHost* host = RenderProcessHost::FromID(process_id);
91 DCHECK(host);
92 host->AddObserver(this);
93 signin_hosts_observed_.insert(host);
96 void ChromeSigninClient::ClearSigninProcess() {
97 signin_host_id_ = ChildProcessHost::kInvalidUniqueID;
100 bool ChromeSigninClient::IsSigninProcess(int process_id) const {
101 return process_id != ChildProcessHost::kInvalidUniqueID &&
102 process_id == signin_host_id_;
105 bool ChromeSigninClient::HasSigninProcess() const {
106 return signin_host_id_ != ChildProcessHost::kInvalidUniqueID;
109 void ChromeSigninClient::RenderProcessHostDestroyed(RenderProcessHost* host) {
110 // It's possible we're listening to a "stale" renderer because it was replaced
111 // with a new process by process-per-site. In either case, stop observing it,
112 // but only reset signin_host_id_ tracking if this was from the current signin
113 // process.
114 signin_hosts_observed_.erase(host);
115 if (signin_host_id_ == host->GetID())
116 signin_host_id_ = ChildProcessHost::kInvalidUniqueID;
119 PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); }
121 scoped_refptr<TokenWebData> ChromeSigninClient::GetDatabase() {
122 return WebDataServiceFactory::GetTokenWebDataForProfile(
123 profile_, ServiceAccessType::EXPLICIT_ACCESS);
126 bool ChromeSigninClient::CanRevokeCredentials() {
127 #if defined(OS_CHROMEOS)
128 // UserManager may not exist in unit_tests.
129 if (user_manager::UserManager::IsInitialized() &&
130 user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) {
131 // Don't allow revoking credentials for Chrome OS supervised users.
132 // See http://crbug.com/332032
133 LOG(ERROR) << "Attempt to revoke supervised user refresh "
134 << "token detected, ignoring.";
135 return false;
137 #else
138 // Don't allow revoking credentials for legacy supervised users.
139 // See http://crbug.com/332032
140 if (profile_->IsLegacySupervised()) {
141 LOG(ERROR) << "Attempt to revoke supervised user refresh "
142 << "token detected, ignoring.";
143 return false;
145 #endif
146 return true;
149 std::string ChromeSigninClient::GetSigninScopedDeviceId() {
150 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
151 switches::kDisableSigninScopedDeviceId)) {
152 return std::string();
155 std::string signin_scoped_device_id =
156 GetPrefs()->GetString(prefs::kGoogleServicesSigninScopedDeviceId);
157 if (signin_scoped_device_id.empty()) {
158 // If device_id doesn't exist then generate new and save in prefs.
159 signin_scoped_device_id = base::GenerateGUID();
160 DCHECK(!signin_scoped_device_id.empty());
161 GetPrefs()->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
162 signin_scoped_device_id);
164 return signin_scoped_device_id;
167 void ChromeSigninClient::OnSignedOut() {
168 GetPrefs()->ClearPref(prefs::kGoogleServicesSigninScopedDeviceId);
169 ProfileInfoCache& cache =
170 g_browser_process->profile_manager()->GetProfileInfoCache();
171 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
172 cache.SetLocalAuthCredentialsOfProfileAtIndex(index, std::string());
173 cache.SetUserNameOfProfileAtIndex(index, base::string16());
174 cache.SetProfileSigninRequiredAtIndex(index, false);
177 net::URLRequestContextGetter* ChromeSigninClient::GetURLRequestContext() {
178 return profile_->GetRequestContext();
181 bool ChromeSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() {
182 // If inline sign in is enabled, but account consistency is not, the user's
183 // credentials should be merge into the cookie jar.
184 return !switches::IsEnableWebBasedSignin() &&
185 !switches::IsEnableAccountConsistency();
188 std::string ChromeSigninClient::GetProductVersion() {
189 chrome::VersionInfo chrome_version;
190 return chrome_version.CreateVersionString();
193 bool ChromeSigninClient::IsFirstRun() const {
194 #if defined(OS_ANDROID)
195 return false;
196 #else
197 return first_run::IsChromeFirstRun();
198 #endif
201 base::Time ChromeSigninClient::GetInstallDate() {
202 return base::Time::FromTimeT(
203 g_browser_process->metrics_service()->GetInstallDate());
206 bool ChromeSigninClient::AreSigninCookiesAllowed() {
207 return ProfileAllowsSigninCookies(profile_);
210 void ChromeSigninClient::AddContentSettingsObserver(
211 content_settings::Observer* observer) {
212 profile_->GetHostContentSettingsMap()->AddObserver(observer);
215 void ChromeSigninClient::RemoveContentSettingsObserver(
216 content_settings::Observer* observer) {
217 profile_->GetHostContentSettingsMap()->RemoveObserver(observer);
220 scoped_ptr<SigninClient::CookieChangedSubscription>
221 ChromeSigninClient::AddCookieChangedCallback(
222 const GURL& url,
223 const std::string& name,
224 const net::CookieStore::CookieChangedCallback& callback) {
225 scoped_refptr<net::URLRequestContextGetter> context_getter =
226 profile_->GetRequestContext();
227 DCHECK(context_getter.get());
228 scoped_ptr<SigninCookieChangedSubscription> subscription(
229 new SigninCookieChangedSubscription(context_getter, url, name, callback));
230 return subscription.Pass();
233 void ChromeSigninClient::OnSignedIn(const std::string& account_id,
234 const std::string& username,
235 const std::string& password) {
236 ProfileManager* profile_manager = g_browser_process->profile_manager();
237 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
238 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
239 if (index != std::string::npos) {
240 cache.SetUserNameOfProfileAtIndex(index, base::UTF8ToUTF16(username));
241 ProfileMetrics::UpdateReportedProfilesStatistics(profile_manager);
245 void ChromeSigninClient::PostSignedIn(const std::string& account_id,
246 const std::string& username,
247 const std::string& password) {
248 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
249 // Don't store password hash except when lock is available for the user.
250 if (!password.empty() && profiles::IsLockAvailable(profile_))
251 LocalAuth::SetLocalAuthCredentials(profile_, password);
252 #endif
255 void ChromeSigninClient::OnErrorChanged() {
256 // Some tests don't have a ProfileManager.
257 if (g_browser_process->profile_manager() == nullptr)
258 return;
260 ProfileInfoCache& cache = g_browser_process->profile_manager()->
261 GetProfileInfoCache();
262 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
263 if (index == std::string::npos)
264 return;
266 cache.SetProfileIsAuthErrorAtIndex(index,
267 signin_error_controller_->HasError());