• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/supervised_user/supervised_user_constants.h"
22 #endif
23 
24 #if defined(OS_CHROMEOS)
25 #include "chrome/browser/chromeos/login/users/user_manager.h"
26 #endif
27 
28 using content::ChildProcessHost;
29 using content::RenderProcessHost;
30 
31 namespace {
32 
33 const char kGoogleAccountsUrl[] = "https://accounts.google.com";
34 
35 }  // namespace
36 
ChromeSigninClient(Profile * profile)37 ChromeSigninClient::ChromeSigninClient(Profile* profile)
38     : profile_(profile), signin_host_id_(ChildProcessHost::kInvalidUniqueID) {}
39 
~ChromeSigninClient()40 ChromeSigninClient::~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
ProfileAllowsSigninCookies(Profile * profile)51 bool ChromeSigninClient::ProfileAllowsSigninCookies(Profile* profile) {
52   CookieSettings* cookie_settings =
53       CookieSettings::Factory::GetForProfile(profile).get();
54   return SettingsAllowSigninCookies(cookie_settings);
55 }
56 
57 // static
SettingsAllowSigninCookies(CookieSettings * cookie_settings)58 bool ChromeSigninClient::SettingsAllowSigninCookies(
59     CookieSettings* cookie_settings) {
60   return cookie_settings &&
61          cookie_settings->IsSettingCookieAllowed(GURL(kGoogleAccountsUrl),
62                                                  GURL(kGoogleAccountsUrl));
63 }
64 
SetSigninProcess(int process_id)65 void 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 
ClearSigninProcess()77 void ChromeSigninClient::ClearSigninProcess() {
78   signin_host_id_ = ChildProcessHost::kInvalidUniqueID;
79 }
80 
IsSigninProcess(int process_id) const81 bool ChromeSigninClient::IsSigninProcess(int process_id) const {
82   return process_id == signin_host_id_;
83 }
84 
HasSigninProcess() const85 bool ChromeSigninClient::HasSigninProcess() const {
86   return signin_host_id_ != ChildProcessHost::kInvalidUniqueID;
87 }
88 
RenderProcessHostDestroyed(RenderProcessHost * host)89 void 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 
GetPrefs()99 PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); }
100 
GetDatabase()101 scoped_refptr<TokenWebData> ChromeSigninClient::GetDatabase() {
102   return WebDataServiceFactory::GetTokenWebDataForProfile(
103       profile_, Profile::EXPLICIT_ACCESS);
104 }
105 
CanRevokeCredentials()106 bool 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_->IsSupervised()) {
121     LOG(ERROR) << "Attempt to revoke supervised user refresh "
122                << "token detected, ignoring.";
123     return false;
124   }
125 #endif
126   return true;
127 }
128 
GetURLRequestContext()129 net::URLRequestContextGetter* ChromeSigninClient::GetURLRequestContext() {
130   return profile_->GetRequestContext();
131 }
132 
ShouldMergeSigninCredentialsIntoCookieJar()133 bool 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 
GetProductVersion()140 std::string ChromeSigninClient::GetProductVersion() {
141   chrome::VersionInfo chrome_version;
142   if (!chrome_version.is_valid())
143     return "invalid";
144   return chrome_version.CreateVersionString();
145 }
146 
SetCookieChangedCallback(const CookieChangedCallback & callback)147 void 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 
GoogleSigninSucceeded(const std::string & username,const std::string & password)161 void 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 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)170 void 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 
RegisterForCookieChangedNotification()187 void 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 
UnregisterForCookieChangedNotification()194 void 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