chrome_signin_client.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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. 4 5#include "chrome/browser/signin/chrome_signin_client.h" 6 7#include "chrome/browser/chrome_notification_types.h" 8#include "chrome/browser/content_settings/cookie_settings.h" 9#include "chrome/browser/net/chrome_cookie_notification_details.h" 10#include "chrome/browser/signin/local_auth.h" 11#include "chrome/browser/webdata/web_data_service_factory.h" 12#include "chrome/common/chrome_version_info.h" 13#include "components/signin/core/common/profile_management_switches.h" 14#include "content/public/browser/notification_details.h" 15#include "content/public/browser/notification_source.h" 16#include "content/public/browser/render_process_host.h" 17#include "content/public/common/child_process_host.h" 18#include "url/gurl.h" 19 20#if defined(ENABLE_MANAGED_USERS) 21#include "chrome/browser/managed_mode/managed_user_constants.h" 22#endif 23 24#if defined(OS_CHROMEOS) 25#include "chrome/browser/chromeos/login/users/user_manager.h" 26#endif 27 28using content::ChildProcessHost; 29using content::RenderProcessHost; 30 31namespace { 32 33const char kGoogleAccountsUrl[] = "https://accounts.google.com"; 34 35} // namespace 36 37ChromeSigninClient::ChromeSigninClient(Profile* profile) 38 : profile_(profile), signin_host_id_(ChildProcessHost::kInvalidUniqueID) {} 39 40ChromeSigninClient::~ChromeSigninClient() { 41 UnregisterForCookieChangedNotification(); 42 43 std::set<RenderProcessHost*>::iterator i; 44 for (i = signin_hosts_observed_.begin(); i != signin_hosts_observed_.end(); 45 ++i) { 46 (*i)->RemoveObserver(this); 47 } 48} 49 50// static 51bool ChromeSigninClient::ProfileAllowsSigninCookies(Profile* profile) { 52 CookieSettings* cookie_settings = 53 CookieSettings::Factory::GetForProfile(profile).get(); 54 return SettingsAllowSigninCookies(cookie_settings); 55} 56 57// static 58bool ChromeSigninClient::SettingsAllowSigninCookies( 59 CookieSettings* cookie_settings) { 60 return cookie_settings && 61 cookie_settings->IsSettingCookieAllowed(GURL(kGoogleAccountsUrl), 62 GURL(kGoogleAccountsUrl)); 63} 64 65void ChromeSigninClient::SetSigninProcess(int process_id) { 66 if (process_id == signin_host_id_) 67 return; 68 DLOG_IF(WARNING, signin_host_id_ != ChildProcessHost::kInvalidUniqueID) 69 << "Replacing in-use signin process."; 70 signin_host_id_ = process_id; 71 RenderProcessHost* host = RenderProcessHost::FromID(process_id); 72 DCHECK(host); 73 host->AddObserver(this); 74 signin_hosts_observed_.insert(host); 75} 76 77void ChromeSigninClient::ClearSigninProcess() { 78 signin_host_id_ = ChildProcessHost::kInvalidUniqueID; 79} 80 81bool ChromeSigninClient::IsSigninProcess(int process_id) const { 82 return process_id == signin_host_id_; 83} 84 85bool ChromeSigninClient::HasSigninProcess() const { 86 return signin_host_id_ != ChildProcessHost::kInvalidUniqueID; 87} 88 89void ChromeSigninClient::RenderProcessHostDestroyed(RenderProcessHost* host) { 90 // It's possible we're listening to a "stale" renderer because it was replaced 91 // with a new process by process-per-site. In either case, stop observing it, 92 // but only reset signin_host_id_ tracking if this was from the current signin 93 // process. 94 signin_hosts_observed_.erase(host); 95 if (signin_host_id_ == host->GetID()) 96 signin_host_id_ = ChildProcessHost::kInvalidUniqueID; 97} 98 99PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); } 100 101scoped_refptr<TokenWebData> ChromeSigninClient::GetDatabase() { 102 return WebDataServiceFactory::GetTokenWebDataForProfile( 103 profile_, Profile::EXPLICIT_ACCESS); 104} 105 106bool ChromeSigninClient::CanRevokeCredentials() { 107#if defined(OS_CHROMEOS) 108 // UserManager may not exist in unit_tests. 109 if (chromeos::UserManager::IsInitialized() && 110 chromeos::UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 111 // Don't allow revoking credentials for Chrome OS supervised users. 112 // See http://crbug.com/332032 113 LOG(ERROR) << "Attempt to revoke supervised user refresh " 114 << "token detected, ignoring."; 115 return false; 116 } 117#else 118 // Don't allow revoking credentials for supervised users. 119 // See http://crbug.com/332032 120 if (profile_->IsManaged()) { 121 LOG(ERROR) << "Attempt to revoke supervised user refresh " 122 << "token detected, ignoring."; 123 return false; 124 } 125#endif 126 return true; 127} 128 129net::URLRequestContextGetter* ChromeSigninClient::GetURLRequestContext() { 130 return profile_->GetRequestContext(); 131} 132 133bool ChromeSigninClient::ShouldMergeSigninCredentialsIntoCookieJar() { 134 // If inline sign in is enabled, but new profile management is not, the user's 135 // credentials should be merge into the cookie jar. 136 return !switches::IsEnableWebBasedSignin() && 137 !switches::IsNewProfileManagement(); 138} 139 140std::string ChromeSigninClient::GetProductVersion() { 141 chrome::VersionInfo chrome_version; 142 if (!chrome_version.is_valid()) 143 return "invalid"; 144 return chrome_version.CreateVersionString(); 145} 146 147void ChromeSigninClient::SetCookieChangedCallback( 148 const CookieChangedCallback& callback) { 149 if (callback_.Equals(callback)) 150 return; 151 152 // There should be only one callback active at a time. 153 DCHECK(callback.is_null() || callback_.is_null()); 154 callback_ = callback; 155 if (!callback_.is_null()) 156 RegisterForCookieChangedNotification(); 157 else 158 UnregisterForCookieChangedNotification(); 159} 160 161void ChromeSigninClient::GoogleSigninSucceeded(const std::string& username, 162 const std::string& password) { 163#if !defined(OS_ANDROID) 164 // Don't store password hash except for users of new profile features. 165 if (switches::IsNewProfileManagement()) 166 chrome::SetLocalAuthCredentials(profile_, password); 167#endif 168} 169 170void ChromeSigninClient::Observe(int type, 171 const content::NotificationSource& source, 172 const content::NotificationDetails& details) { 173 switch (type) { 174 case chrome::NOTIFICATION_COOKIE_CHANGED: { 175 DCHECK(!callback_.is_null()); 176 const net::CanonicalCookie* cookie = 177 content::Details<ChromeCookieDetails>(details).ptr()->cookie; 178 callback_.Run(cookie); 179 break; 180 } 181 default: 182 NOTREACHED(); 183 break; 184 } 185} 186 187void ChromeSigninClient::RegisterForCookieChangedNotification() { 188 content::Source<Profile> source(profile_); 189 DCHECK(!registrar_.IsRegistered( 190 this, chrome::NOTIFICATION_COOKIE_CHANGED, source)); 191 registrar_.Add(this, chrome::NOTIFICATION_COOKIE_CHANGED, source); 192} 193 194void ChromeSigninClient::UnregisterForCookieChangedNotification() { 195 // Note that it's allowed to call this method multiple times without an 196 // intervening call to |RegisterForCookieChangedNotification()|. 197 content::Source<Profile> source(profile_); 198 if (!registrar_.IsRegistered( 199 this, chrome::NOTIFICATION_COOKIE_CHANGED, source)) 200 return; 201 registrar_.Remove(this, chrome::NOTIFICATION_COOKIE_CHANGED, source); 202} 203