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

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

Issue 11444029: Added UserPolicySigninService::FetchPolicyForSignedInUser(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/user_policy_signin_service.h" 5 #include "chrome/browser/policy/user_policy_signin_service.h"
6 6
7 #include "chrome/browser/browser_process.h" 7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/policy/browser_policy_connector.h" 8 #include "chrome/browser/policy/browser_policy_connector.h"
9 #include "chrome/browser/policy/cloud_policy_service.h" 9 #include "chrome/browser/policy/cloud_policy_service.h"
10 #include "chrome/browser/policy/user_cloud_policy_manager.h" 10 #include "chrome/browser/policy/user_cloud_policy_manager.h"
(...skipping 19 matching lines...) Expand all
30 30
31 // How long to delay before starting device policy network requests. Set to a 31 // How long to delay before starting device policy network requests. Set to a
32 // few seconds to alleviate contention during initial startup. 32 // few seconds to alleviate contention during initial startup.
33 const int64 kPolicyServiceInitializationDelayMilliseconds = 2000; 33 const int64 kPolicyServiceInitializationDelayMilliseconds = 2000;
34 } // namespace 34 } // namespace
35 35
36 namespace policy { 36 namespace policy {
37 37
38 UserPolicySigninService::UserPolicySigninService( 38 UserPolicySigninService::UserPolicySigninService(
39 Profile* profile) 39 Profile* profile)
40 : profile_(profile) { 40 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
41 profile_(profile),
42 pending_fetch_(false) {
41 43
42 // Initialize/shutdown the UserCloudPolicyManager when the user signs in or 44 if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin))
43 // out. 45 return;
46
47 // Initialize/shutdown the UserCloudPolicyManager when the user signs out.
44 registrar_.Add(this, 48 registrar_.Add(this,
45 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 49 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
46 content::Source<Profile>(profile)); 50 content::Source<Profile>(profile));
51
52 // Listen for an OAuth token to become available so we can register a client
53 // if for some reason the client is not already registered (for example, if
54 // the policy load failed during initial signin).
47 registrar_.Add(this, 55 registrar_.Add(this,
48 chrome::NOTIFICATION_TOKEN_AVAILABLE, 56 chrome::NOTIFICATION_TOKEN_AVAILABLE,
49 content::Source<TokenService>( 57 content::Source<TokenService>(
50 TokenServiceFactory::GetForProfile(profile))); 58 TokenServiceFactory::GetForProfile(profile)));
51 59
52 // The Profile is not yet fully initialized when this object is created, 60 // TokenService should not yet have loaded its tokens since this happens in
53 // so wait until the initialization has finished to initialize the 61 // the background after PKS initialization - so this service should always be
54 // UserCloudPolicyManager as otherwise various crashes ensue from services 62 // created before the oauth token is available.
55 // trying to access the partially-initialized Profile. 63 DCHECK(!TokenServiceFactory::GetForProfile(profile_)->HasOAuthLoginToken());
56 // TODO(atwilson): Remove this once ProfileImpl::DoFinalInit() goes away and 64
Mattias Nissler (ping if slow) 2012/12/07 15:20:45 remove extra blank line.
Andrew T Wilson (Slow) 2012/12/07 17:34:29 Done.
57 // the profile is fully initialized before ProfileKeyedServices are created. 65
66 // Register a listener to be called back once the current profile has finished
67 // initializing, so we can startup the UserCloudPolicyManager.
58 registrar_.Add(this, 68 registrar_.Add(this,
59 chrome::NOTIFICATION_PROFILE_ADDED, 69 chrome::NOTIFICATION_PROFILE_ADDED,
60 content::Source<Profile>(profile)); 70 content::Source<Profile>(profile));
61 } 71 }
62 72
63 UserPolicySigninService::~UserPolicySigninService() {} 73 UserPolicySigninService::~UserPolicySigninService() {}
64 74
75 void UserPolicySigninService::FetchPolicyForSignedInUser(
76 const std::string& oauth2_access_token,
77 const PolicyFetchCallback& callback) {
78 if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin)) {
79 callback.Run(false);
80 return;
81 }
82
83 // The user has just signed in, so the UserCloudPolicyManager should not yet
84 // be initialized, and the client should not be registered because there
85 // should be no cached policy. This routine will proactively ask the client
86 // to register itself without waiting for the CloudPolicyService to finish
87 // initialization.
88 DCHECK(!GetManager()->cloud_policy_service());
89 InitializeUserCloudPolicyManager();
90 DCHECK(!GetManager()->IsClientRegistered());
91
92 DCHECK(!pending_fetch_);
93 pending_fetch_ = true;
94 pending_fetch_callback_ = callback;
95
96 // Register the client using this access token.
97 RegisterCloudPolicyService(oauth2_access_token);
98 }
99
65 void UserPolicySigninService::StopObserving() { 100 void UserPolicySigninService::StopObserving() {
66 UserCloudPolicyManager* manager = GetManager(); 101 UserCloudPolicyManager* manager = GetManager();
67 if (manager && manager->cloud_policy_service()) 102 if (manager) {
68 manager->cloud_policy_service()->RemoveObserver(this); 103 if (manager->cloud_policy_service())
104 manager->cloud_policy_service()->RemoveObserver(this);
105 if (manager->cloud_policy_client())
106 manager->cloud_policy_client()->RemoveObserver(this);
107 }
69 } 108 }
70 109
110 void UserPolicySigninService::StartObserving() {
111 UserCloudPolicyManager* manager = GetManager();
112 // Manager should be fully initialized by now.
113 DCHECK(manager);
114 DCHECK(manager->cloud_policy_service());
115 DCHECK(manager->cloud_policy_client());
116 manager->cloud_policy_service()->AddObserver(this);
117 manager->cloud_policy_client()->AddObserver(this);
118 }
119
Mattias Nissler (ping if slow) 2012/12/07 15:20:45 remove extra blank line.
Andrew T Wilson (Slow) 2012/12/07 17:34:29 Done.
120
71 void UserPolicySigninService::Observe( 121 void UserPolicySigninService::Observe(
72 int type, 122 int type,
73 const content::NotificationSource& source, 123 const content::NotificationSource& source,
74 const content::NotificationDetails& details) { 124 const content::NotificationDetails& details) {
75 switch (type) { 125 switch (type) {
76 case chrome::NOTIFICATION_PROFILE_ADDED: 126 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
Mattias Nissler (ping if slow) 2012/12/07 15:20:45 shouldn't we check that this is actually for the p
Andrew T Wilson (Slow) 2012/12/07 17:34:29 When we register for the notification, we specify
77 // Profile is initialized so it's safe to initialize the 127 ShutdownUserCloudPolicyManager();
78 // UserCloudPolicyManager now.
79 ConfigureUserCloudPolicyManager();
80 break; 128 break;
81 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 129 case chrome::NOTIFICATION_PROFILE_ADDED: {
Mattias Nissler (ping if slow) 2012/12/07 15:20:45 Is this correct? This fires for any profile, not j
Andrew T Wilson (Slow) 2012/12/07 17:34:29 We are specifying a source profile when registerin
82 ConfigureUserCloudPolicyManager(); 130 // A new profile has been loaded - if it's signed in, then initialize the
131 // UCPM, otherwise shut down the UCPM (which deletes any cached policy
132 // data).
133 SigninManager* signin_manager =
134 SigninManagerFactory::GetForProfile(profile_);
135 if (signin_manager->GetAuthenticatedUsername().empty())
136 ShutdownUserCloudPolicyManager();
137 else
138 InitializeUserCloudPolicyManager();
83 break; 139 break;
140 }
84 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 141 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
85 const TokenService::TokenAvailableDetails& token_details = 142 const TokenService::TokenAvailableDetails& token_details =
86 *(content::Details<const TokenService::TokenAvailableDetails>( 143 *(content::Details<const TokenService::TokenAvailableDetails>(
87 details).ptr()); 144 details).ptr());
88 if (token_details.service() == 145 if (token_details.service() ==
89 GaiaConstants::kGaiaOAuth2LoginRefreshToken) { 146 GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
90 // TokenService now has a refresh token, so initialize the 147 // TokenService now has a refresh token (implying that the user is
91 // UserCloudPolicyManager. 148 // signed in) so initialize the UserCloudPolicyManager.
92 ConfigureUserCloudPolicyManager(); 149 InitializeUserCloudPolicyManager();
93 } 150 }
94 break; 151 break;
95 } 152 }
96 default: 153 default:
97 NOTREACHED(); 154 NOTREACHED();
98 } 155 }
99 } 156 }
100 157
158 void UserPolicySigninService::InitializeUserCloudPolicyManager() {
159 UserCloudPolicyManager* manager = GetManager();
160 DCHECK(!SigninManagerFactory::GetForProfile(profile_)->
161 GetAuthenticatedUsername().empty());
162 if (!manager->cloud_policy_service()) {
163 // Make sure we've initialized the DeviceManagementService. It's OK to
164 // call this multiple times so we do it every time we initialize the
165 // UserCloudPolicyManager.
166 g_browser_process->browser_policy_connector()->
167 ScheduleServiceInitialization(
168 kPolicyServiceInitializationDelayMilliseconds);
169 // If there is no cached DMToken then we can detect this below (or when
170 // the OnInitializationCompleted() callback is invoked).
171 policy::DeviceManagementService* service = g_browser_process->
172 browser_policy_connector()->device_management_service();
173 manager->Initialize(g_browser_process->local_state(), service);
174 DCHECK(manager->cloud_policy_service());
175 StartObserving();
176 }
101 177
102 void UserPolicySigninService::ConfigureUserCloudPolicyManager() { 178 // If the CloudPolicyService is initialized, kick off registration. If the
103 // Don't do anything unless cloud policy is enabled. 179 // TokenService doesn't have an OAuth token yet (e.g. this is during initial
104 if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin)) 180 // signin, or when dynamically loading a signed-in policy) this does nothing
105 return; 181 // until the OAuth token is loaded.
182 if (manager->cloud_policy_service()->IsInitializationComplete())
183 OnInitializationCompleted(manager->cloud_policy_service());
184 }
106 185
107 // Either startup or shutdown the UserCloudPolicyManager depending on whether 186 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
108 // the user is signed in or not. 187 StopObserving();
188 NotifyPendingFetchCallback(false);
189
109 UserCloudPolicyManager* manager = GetManager(); 190 UserCloudPolicyManager* manager = GetManager();
110 if (!manager) 191 if (manager) // Can be null in unit tests.
111 return; // Can be null in unit tests.
112
113 SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile_);
114 if (signin_manager->GetAuthenticatedUsername().empty()) {
115 // User has signed out - remove existing policy.
116 StopObserving();
117 manager->ShutdownAndRemovePolicy(); 192 manager->ShutdownAndRemovePolicy();
118 } else {
119 // Initialize the UserCloudPolicyManager if it isn't already initialized.
120 if (!manager->cloud_policy_service()) {
121 // Make sure we've initialized the DeviceManagementService. It's OK to
122 // call this multiple times so we do it every time we initialize the
123 // UserCloudPolicyManager.
124 g_browser_process->browser_policy_connector()->
125 ScheduleServiceInitialization(
126 kPolicyServiceInitializationDelayMilliseconds);
127 // If there is no cached DMToken then we can detect this below (or when
128 // the OnInitializationCompleted() callback is invoked.
129 policy::DeviceManagementService* service = g_browser_process->
130 browser_policy_connector()->device_management_service();
131 manager->Initialize(g_browser_process->local_state(), service);
132 DCHECK(manager->cloud_policy_service());
133 manager->cloud_policy_service()->AddObserver(this);
134 }
135
136 // If the CloudPolicyService is initialized, but the CloudPolicyClient still
137 // needs to be registered, kick off registration.
138 if (manager->cloud_policy_service()->IsInitializationComplete() &&
139 !manager->IsClientRegistered()) {
140 RegisterCloudPolicyService();
141 }
142 }
143 } 193 }
144 194
145 void UserPolicySigninService::OnInitializationCompleted( 195 void UserPolicySigninService::OnInitializationCompleted(
146 CloudPolicyService* service) { 196 CloudPolicyService* service) {
147 UserCloudPolicyManager* manager = GetManager(); 197 UserCloudPolicyManager* manager = GetManager();
148 DCHECK_EQ(service, manager->cloud_policy_service()); 198 DCHECK_EQ(service, manager->cloud_policy_service());
149 DCHECK(service->IsInitializationComplete()); 199 DCHECK(service->IsInitializationComplete());
150 // The service is now initialized - if the client is not yet registered, then 200 // The service is now initialized - if the client is not yet registered, then
151 // it means that there is no cached policy and so we need to initiate a new 201 // it means that there is no cached policy and so we need to initiate a new
152 // client registration. 202 // client registration.
153 DVLOG_IF(1, manager->IsClientRegistered()) 203 DVLOG_IF(1, manager->IsClientRegistered())
154 << "Client already registered - not fetching DMToken"; 204 << "Client already registered - not fetching DMToken";
155 if (!manager->IsClientRegistered()) 205 if (!manager->IsClientRegistered()) {
156 RegisterCloudPolicyService(); 206 std::string token = TokenServiceFactory::GetForProfile(profile_)->
207 GetOAuth2LoginRefreshToken();
208 if (token.empty()) {
209 // No token yet - this class listens for NOTIFICATION_TOKEN_AVAILABLE
210 // and will re-attempt registration once the token is available.
211 DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
212 return;
213 }
214 RegisterCloudPolicyService(token);
215 }
157 } 216 }
158 217
159 void UserPolicySigninService::RegisterCloudPolicyService() { 218 void UserPolicySigninService::RegisterCloudPolicyService(
219 std::string login_token) {
220 DCHECK(!GetManager()->IsClientRegistered());
160 DVLOG(1) << "Fetching new DM Token"; 221 DVLOG(1) << "Fetching new DM Token";
161 // TODO(atwilson): Move the code to mint the devicemanagement token into
162 // TokenService.
163 std::string token = TokenServiceFactory::GetForProfile(profile_)->
164 GetOAuth2LoginRefreshToken();
165 if (token.empty()) {
166 DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
167 return;
168 }
169
170 // Do nothing if already fetching an access token. 222 // Do nothing if already fetching an access token.
171 if (oauth2_access_token_fetcher_.get()) 223 if (oauth2_access_token_fetcher_.get())
172 return; 224 return;
173 225
174 // Start fetching an OAuth2 access token for the device management service and 226 // Start fetching an OAuth2 access token for the device management service and
175 // hand it off to the CloudPolicyClient when done. 227 // hand it off to the CloudPolicyClient when done.
176 oauth2_access_token_fetcher_.reset( 228 oauth2_access_token_fetcher_.reset(
177 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext())); 229 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext()));
178 std::vector<std::string> scopes(1, kServiceScopeChromeOSDeviceManagement); 230 std::vector<std::string> scopes(1, kServiceScopeChromeOSDeviceManagement);
179 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); 231 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
180 oauth2_access_token_fetcher_->Start( 232 oauth2_access_token_fetcher_->Start(
181 gaia_urls->oauth2_chrome_client_id(), 233 gaia_urls->oauth2_chrome_client_id(),
182 gaia_urls->oauth2_chrome_client_secret(), 234 gaia_urls->oauth2_chrome_client_secret(),
183 token, 235 login_token,
184 scopes); 236 scopes);
185 } 237 }
186 238
187 void UserPolicySigninService::OnGetTokenFailure( 239 void UserPolicySigninService::OnGetTokenFailure(
188 const GoogleServiceAuthError& error) { 240 const GoogleServiceAuthError& error) {
189 DLOG(WARNING) << "Could not fetch access token for " 241 DLOG(WARNING) << "Could not fetch access token for "
190 << kServiceScopeChromeOSDeviceManagement; 242 << kServiceScopeChromeOSDeviceManagement;
191 oauth2_access_token_fetcher_.reset(); 243 oauth2_access_token_fetcher_.reset();
244 // If there was a pending fetch request, let them know the fetch failed.
245 NotifyPendingFetchCallback(false);
192 } 246 }
193 247
194 void UserPolicySigninService::OnGetTokenSuccess( 248 void UserPolicySigninService::OnGetTokenSuccess(
195 const std::string& access_token, 249 const std::string& access_token,
196 const base::Time& expiration_time) { 250 const base::Time& expiration_time) {
197 UserCloudPolicyManager* manager = GetManager(); 251 UserCloudPolicyManager* manager = GetManager();
198 // Pass along the new access token to the CloudPolicyClient. 252 // Pass along the new access token to the CloudPolicyClient.
199 DVLOG(1) << "Fetched new scoped OAuth token:" << access_token; 253 DVLOG(1) << "Fetched new scoped OAuth token:" << access_token;
200 manager->RegisterClient(access_token); 254 manager->RegisterClient(access_token);
201 oauth2_access_token_fetcher_.reset(); 255 oauth2_access_token_fetcher_.reset();
202 } 256 }
203 257
258 void UserPolicySigninService::OnRegistrationStateChanged(
259 CloudPolicyClient* client) {
260 DCHECK_EQ(GetManager()->cloud_policy_client(), client);
261 if (pending_fetch_) {
262 UserCloudPolicyManager* manager = GetManager();
263 if (manager->IsClientRegistered()) {
264 // Request a policy fetch.
265 manager->cloud_policy_service()->RefreshPolicy(
266 base::Bind(
267 &UserPolicySigninService::NotifyPendingFetchCallback,
268 weak_factory_.GetWeakPtr()));
269 } else {
270 // Shouldn't be possible for the client to get unregistered.
271 NOTREACHED() << "Client unregistered while waiting for policy fetch";
272 }
273 }
274 }
275
276 void UserPolicySigninService::NotifyPendingFetchCallback(bool success) {
277 if (pending_fetch_) {
278 pending_fetch_ = false;
279 pending_fetch_callback_.Run(success);
280 }
281 }
282
283 void UserPolicySigninService::OnPolicyFetched(CloudPolicyClient* client) {
284 // Do nothing when policy is fetched - if the policy fetch is successful,
285 // NotifyPendingFetchCallback will be invoked.
286 }
287
288 void UserPolicySigninService::OnClientError(CloudPolicyClient* client) {
289 NotifyPendingFetchCallback(false);
290 }
291
204 void UserPolicySigninService::Shutdown() { 292 void UserPolicySigninService::Shutdown() {
205 StopObserving(); 293 StopObserving();
206 } 294 }
207 295
208 UserCloudPolicyManager* UserPolicySigninService::GetManager() { 296 UserCloudPolicyManager* UserPolicySigninService::GetManager() {
209 return UserCloudPolicyManagerFactory::GetForProfile(profile_); 297 return UserCloudPolicyManagerFactory::GetForProfile(profile_);
210 } 298 }
211 299
212 } // namespace policy 300 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698