Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: chrome/browser/policy/user_policy_signin_service.cc

Issue 12189011: Split up chrome/browser/policy subdirectory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/policy/user_policy_signin_service.h"
6
7 #include "base/values.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/policy/browser_policy_connector.h"
10 #include "chrome/browser/policy/cloud_policy_service.h"
11 #include "chrome/browser/policy/user_cloud_policy_manager.h"
12 #include "chrome/browser/policy/user_cloud_policy_manager_factory.h"
13 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/signin/signin_manager.h"
16 #include "chrome/browser/signin/signin_manager_factory.h"
17 #include "chrome/browser/signin/token_service.h"
18 #include "chrome/browser/signin/token_service_factory.h"
19 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/pref_names.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_source.h"
23 #include "google_apis/gaia/gaia_constants.h"
24 #include "google_apis/gaia/gaia_urls.h"
25 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
26
27 namespace {
28 // Various OAuth service scopes required to do CloudPolicyClient registration.
29 const char kServiceScopeChromeOSDeviceManagement[] =
30 "https://www.googleapis.com/auth/chromeosdevicemanagement";
31 const char kServiceScopeGetUserInfo[] =
32 "https://www.googleapis.com/auth/userinfo.email";
33
34 // The key under which the hosted-domain value is stored in the UserInfo
35 // response.
36 const char kGetHostedDomainKey[] = "hd";
37 } // namespace
38
39 namespace policy {
40
41 UserPolicySigninService::UserPolicySigninService(
42 Profile* profile)
43 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
44 profile_(profile),
45 pending_fetch_(false) {
46
47 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableCloudPolicyOnSignin))
48 return;
49
50 // Initialize/shutdown the UserCloudPolicyManager when the user signs out.
51 registrar_.Add(this,
52 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
53 content::Source<Profile>(profile));
54
55 // Listen for an OAuth token to become available so we can register a client
56 // if for some reason the client is not already registered (for example, if
57 // the policy load failed during initial signin).
58 registrar_.Add(this,
59 chrome::NOTIFICATION_TOKEN_AVAILABLE,
60 content::Source<TokenService>(
61 TokenServiceFactory::GetForProfile(profile)));
62
63 // TokenService should not yet have loaded its tokens since this happens in
64 // the background after PKS initialization - so this service should always be
65 // created before the oauth token is available.
66 DCHECK(!TokenServiceFactory::GetForProfile(profile_)->HasOAuthLoginToken());
67
68 // Register a listener to be called back once the current profile has finished
69 // initializing, so we can startup the UserCloudPolicyManager.
70 registrar_.Add(this,
71 chrome::NOTIFICATION_PROFILE_ADDED,
72 content::Source<Profile>(profile));
73 }
74
75 UserPolicySigninService::~UserPolicySigninService() {}
76
77 void UserPolicySigninService::FetchPolicyForSignedInUser(
78 const std::string& oauth2_access_token,
79 const PolicyFetchCallback& callback) {
80 if (!ShouldLoadPolicyForSignedInUser()) {
81 callback.Run(false);
82 return;
83 }
84
85 // If the DeviceManagementService is not yet initialized, start it up now.
86 g_browser_process->browser_policy_connector()->
87 ScheduleServiceInitialization(0);
88
89 // The user has just signed in, so the UserCloudPolicyManager should not yet
90 // be initialized, and the client should not be registered because there
91 // should be no cached policy. This routine will proactively ask the client
92 // to register itself without waiting for the CloudPolicyService to finish
93 // initialization.
94 DCHECK(!GetManager()->core()->service());
95 InitializeUserCloudPolicyManager();
96 DCHECK(!GetManager()->IsClientRegistered());
97
98 DCHECK(!pending_fetch_);
99 pending_fetch_ = true;
100 pending_fetch_callback_ = callback;
101
102 // Register the client using this access token.
103 RegisterCloudPolicyService(oauth2_access_token);
104 }
105
106 void UserPolicySigninService::StopObserving() {
107 UserCloudPolicyManager* manager = GetManager();
108 if (manager) {
109 if (manager->core()->service())
110 manager->core()->service()->RemoveObserver(this);
111 if (manager->core()->client())
112 manager->core()->client()->RemoveObserver(this);
113 }
114 }
115
116 void UserPolicySigninService::StartObserving() {
117 UserCloudPolicyManager* manager = GetManager();
118 // Manager should be fully initialized by now.
119 DCHECK(manager);
120 DCHECK(manager->core()->service());
121 DCHECK(manager->core()->client());
122 manager->core()->service()->AddObserver(this);
123 manager->core()->client()->AddObserver(this);
124 }
125
126 void UserPolicySigninService::Observe(
127 int type,
128 const content::NotificationSource& source,
129 const content::NotificationDetails& details) {
130 // If using a TestingProfile with no SigninManager or UserCloudPolicyManager,
131 // skip initialization.
132 if (!GetManager() || !SigninManagerFactory::GetForProfile(profile_)) {
133 DVLOG(1) << "Skipping initialization for tests due to missing components.";
134 return;
135 }
136
137 switch (type) {
138 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
139 ShutdownUserCloudPolicyManager();
140 break;
141 case chrome::NOTIFICATION_PROFILE_ADDED: {
142 // A new profile has been loaded - if it's signed in, then initialize the
143 // UCPM, otherwise shut down the UCPM (which deletes any cached policy
144 // data). This must be done here instead of at constructor time because
145 // the Profile is not fully initialized when this object is constructed
146 // (DoFinalInit() has not yet been called, so ProfileIOData and
147 // SSLConfigServiceManager have not been created yet).
148 // TODO(atwilson): Switch to using a timer instead, to avoid contention
149 // with other services at startup (http://crbug.com/165468).
150 SigninManager* signin_manager =
151 SigninManagerFactory::GetForProfile(profile_);
152 if (signin_manager->GetAuthenticatedUsername().empty())
153 ShutdownUserCloudPolicyManager();
154 else
155 InitializeUserCloudPolicyManager();
156 break;
157 }
158 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
159 const TokenService::TokenAvailableDetails& token_details =
160 *(content::Details<const TokenService::TokenAvailableDetails>(
161 details).ptr());
162 if (token_details.service() ==
163 GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
164 // TokenService now has a refresh token (implying that the user is
165 // signed in) so initialize the UserCloudPolicyManager.
166 InitializeUserCloudPolicyManager();
167 }
168 break;
169 }
170 default:
171 NOTREACHED();
172 }
173 }
174
175 bool UserPolicySigninService::ShouldLoadPolicyForSignedInUser() {
176 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableCloudPolicyOnSignin))
177 return false; // Cloud policy is disabled.
178
179 const std::string& username = SigninManagerFactory::GetForProfile(profile_)->
180 GetAuthenticatedUsername();
181
182 if (username.empty())
183 return false; // Not signed in.
184
185 return !BrowserPolicyConnector::IsNonEnterpriseUser(username);
186 }
187
188 void UserPolicySigninService::InitializeUserCloudPolicyManager() {
189 if (!ShouldLoadPolicyForSignedInUser()) {
190 VLOG(1) << "Policy load not enabled for user: " <<
191 SigninManagerFactory::GetForProfile(profile_)->
192 GetAuthenticatedUsername();
193 return;
194 }
195
196 UserCloudPolicyManager* manager = GetManager();
197 DCHECK(!SigninManagerFactory::GetForProfile(profile_)->
198 GetAuthenticatedUsername().empty());
199 if (!manager->core()->service()) {
200 // If there is no cached DMToken then we can detect this below (or when
201 // the OnInitializationCompleted() callback is invoked).
202 BrowserPolicyConnector* connector =
203 g_browser_process->browser_policy_connector();
204 manager->Connect(g_browser_process->local_state(),
205 connector->device_management_service());
206 DCHECK(manager->core()->service());
207 StartObserving();
208 }
209
210 // If the CloudPolicyService is initialized, kick off registration. If the
211 // TokenService doesn't have an OAuth token yet (e.g. this is during initial
212 // signin, or when dynamically loading a signed-in policy) this does nothing
213 // until the OAuth token is loaded.
214 if (manager->core()->service()->IsInitializationComplete())
215 OnInitializationCompleted(manager->core()->service());
216 }
217
218 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
219 // Stop any in-progress token fetch.
220 oauth2_access_token_fetcher_.reset();
221 user_info_fetcher_.reset();
222 oauth_access_token_.clear();
223
224 StopObserving();
225 NotifyPendingFetchCallback(false);
226
227 UserCloudPolicyManager* manager = GetManager();
228 if (manager) // Can be null in unit tests.
229 manager->DisconnectAndRemovePolicy();
230 }
231
232 void UserPolicySigninService::OnInitializationCompleted(
233 CloudPolicyService* service) {
234 UserCloudPolicyManager* manager = GetManager();
235 DCHECK_EQ(service, manager->core()->service());
236 DCHECK(service->IsInitializationComplete());
237 // The service is now initialized - if the client is not yet registered, then
238 // it means that there is no cached policy and so we need to initiate a new
239 // client registration.
240 DVLOG_IF(1, manager->IsClientRegistered())
241 << "Client already registered - not fetching DMToken";
242 if (!manager->IsClientRegistered()) {
243 std::string token = TokenServiceFactory::GetForProfile(profile_)->
244 GetOAuth2LoginRefreshToken();
245 if (token.empty()) {
246 // No token yet - this class listens for NOTIFICATION_TOKEN_AVAILABLE
247 // and will re-attempt registration once the token is available.
248 DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
249 return;
250 }
251 RegisterCloudPolicyService(token);
252 }
253 }
254
255 void UserPolicySigninService::RegisterCloudPolicyService(
256 std::string login_token) {
257 DCHECK(!GetManager()->IsClientRegistered());
258 DVLOG(1) << "Fetching new DM Token";
259 // Do nothing if already starting the registration process.
260 if (oauth2_access_token_fetcher_.get() ||
261 user_info_fetcher_.get() ||
262 !oauth_access_token_.empty()) {
263 return;
264 }
265
266 // Start fetching an OAuth2 access token for the device management and
267 // userinfo services.
268 oauth2_access_token_fetcher_.reset(
269 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext()));
270 std::vector<std::string> scopes;
271 scopes.push_back(kServiceScopeChromeOSDeviceManagement);
272 scopes.push_back(kServiceScopeGetUserInfo);
273 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
274 oauth2_access_token_fetcher_->Start(
275 gaia_urls->oauth2_chrome_client_id(),
276 gaia_urls->oauth2_chrome_client_secret(),
277 login_token,
278 scopes);
279 }
280
281 void UserPolicySigninService::OnGetTokenFailure(
282 const GoogleServiceAuthError& error) {
283 DLOG(WARNING) << "Could not fetch access token for "
284 << kServiceScopeChromeOSDeviceManagement;
285 oauth2_access_token_fetcher_.reset();
286 // If there was a pending fetch request, let them know the fetch failed.
287 NotifyPendingFetchCallback(false);
288 }
289
290 void UserPolicySigninService::OnGetTokenSuccess(
291 const std::string& access_token,
292 const base::Time& expiration_time) {
293 oauth_access_token_ = access_token;
294 DVLOG(1) << "Fetched new scoped OAuth token:" << oauth_access_token_;
295 oauth2_access_token_fetcher_.reset();
296 // Now we've gotten our access token - contact GAIA to see if this is a
297 // hosted domain.
298 user_info_fetcher_.reset(new UserInfoFetcher(this,
299 profile_->GetRequestContext()));
300 user_info_fetcher_->Start(oauth_access_token_);
301 }
302
303 void UserPolicySigninService::OnGetUserInfoFailure(
304 const GoogleServiceAuthError& error) {
305 user_info_fetcher_.reset();
306 NotifyPendingFetchCallback(false);
307 }
308
309 void UserPolicySigninService::OnGetUserInfoSuccess(
310 const DictionaryValue* data) {
311 user_info_fetcher_.reset();
312 if (!data->HasKey(kGetHostedDomainKey)) {
313 VLOG(1) << "User not from a hosted domain - skipping registration";
314 NotifyPendingFetchCallback(false);
315 return;
316 }
317 VLOG(1) << "Registering CloudPolicyClient for user from hosted domain";
318 // The user is from a hosted domain, so it's OK to register the
319 // CloudPolicyClient and make requests from DMServer.
320 GetManager()->RegisterClient(oauth_access_token_);
321 }
322
323 void UserPolicySigninService::OnRegistrationStateChanged(
324 CloudPolicyClient* client) {
325 DCHECK_EQ(GetManager()->core()->client(), client);
326 if (pending_fetch_) {
327 UserCloudPolicyManager* manager = GetManager();
328 if (manager->IsClientRegistered()) {
329 // Request a policy fetch.
330 manager->core()->service()->RefreshPolicy(
331 base::Bind(
332 &UserPolicySigninService::NotifyPendingFetchCallback,
333 weak_factory_.GetWeakPtr()));
334 } else {
335 // Shouldn't be possible for the client to get unregistered.
336 NOTREACHED() << "Client unregistered while waiting for policy fetch";
337 }
338 }
339 }
340
341 void UserPolicySigninService::NotifyPendingFetchCallback(bool success) {
342 if (pending_fetch_) {
343 pending_fetch_ = false;
344 pending_fetch_callback_.Run(success);
345 }
346 }
347
348 void UserPolicySigninService::OnPolicyFetched(CloudPolicyClient* client) {
349 // Do nothing when policy is fetched - if the policy fetch is successful,
350 // NotifyPendingFetchCallback will be invoked.
351 }
352
353 void UserPolicySigninService::OnClientError(CloudPolicyClient* client) {
354 NotifyPendingFetchCallback(false);
355 }
356
357 void UserPolicySigninService::Shutdown() {
358 StopObserving();
359 }
360
361 UserCloudPolicyManager* UserPolicySigninService::GetManager() {
362 return UserCloudPolicyManagerFactory::GetForProfile(profile_);
363 }
364
365 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698