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

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: Merge to ToT 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
57 // the profile is fully initialized before ProfileKeyedServices are created. 65 // Register a listener to be called back once the current profile has finished
66 // initializing, so we can startup the UserCloudPolicyManager.
58 registrar_.Add(this, 67 registrar_.Add(this,
59 chrome::NOTIFICATION_PROFILE_ADDED, 68 chrome::NOTIFICATION_PROFILE_ADDED,
60 content::Source<Profile>(profile)); 69 content::Source<Profile>(profile));
61 } 70 }
62 71
63 UserPolicySigninService::~UserPolicySigninService() {} 72 UserPolicySigninService::~UserPolicySigninService() {}
64 73
74 void UserPolicySigninService::FetchPolicyForSignedInUser(
75 const std::string& oauth2_access_token,
76 const PolicyFetchCallback& callback) {
77 if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin)) {
78 callback.Run(false);
79 return;
80 }
81
82 // The user has just signed in, so the UserCloudPolicyManager should not yet
83 // be initialized, and the client should not be registered because there
84 // should be no cached policy. This routine will proactively ask the client
85 // to register itself without waiting for the CloudPolicyService to finish
86 // initialization.
87 DCHECK(!GetManager()->core()->service());
88 InitializeUserCloudPolicyManager();
89 DCHECK(!GetManager()->IsClientRegistered());
90
91 DCHECK(!pending_fetch_);
92 pending_fetch_ = true;
93 pending_fetch_callback_ = callback;
94
95 // Register the client using this access token.
96 RegisterCloudPolicyService(oauth2_access_token);
97 }
98
65 void UserPolicySigninService::StopObserving() { 99 void UserPolicySigninService::StopObserving() {
66 UserCloudPolicyManager* manager = GetManager(); 100 UserCloudPolicyManager* manager = GetManager();
67 if (manager && manager->core()->service()) 101 if (manager) {
68 manager->core()->service()->RemoveObserver(this); 102 if (manager->core()->service())
103 manager->core()->service()->RemoveObserver(this);
104 if (manager->core()->client())
105 manager->core()->client()->RemoveObserver(this);
106 }
107 }
108
109 void UserPolicySigninService::StartObserving() {
110 UserCloudPolicyManager* manager = GetManager();
111 // Manager should be fully initialized by now.
112 DCHECK(manager);
113 DCHECK(manager->core()->service());
114 DCHECK(manager->core()->client());
115 manager->core()->service()->AddObserver(this);
116 manager->core()->client()->AddObserver(this);
69 } 117 }
70 118
71 void UserPolicySigninService::Observe( 119 void UserPolicySigninService::Observe(
72 int type, 120 int type,
73 const content::NotificationSource& source, 121 const content::NotificationSource& source,
74 const content::NotificationDetails& details) { 122 const content::NotificationDetails& details) {
75 switch (type) { 123 switch (type) {
76 case chrome::NOTIFICATION_PROFILE_ADDED: 124 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
77 // Profile is initialized so it's safe to initialize the 125 ShutdownUserCloudPolicyManager();
78 // UserCloudPolicyManager now.
79 ConfigureUserCloudPolicyManager();
80 break; 126 break;
81 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 127 case chrome::NOTIFICATION_PROFILE_ADDED: {
82 ConfigureUserCloudPolicyManager(); 128 // A new profile has been loaded - if it's signed in, then initialize the
129 // UCPM, otherwise shut down the UCPM (which deletes any cached policy
130 // data). This must be done here instead of at constructor time because
131 // the Profile is not fully initialized when this object is constructed
132 // (accessing things like URLFetchers will crash).
Mattias Nissler (ping if slow) 2012/12/10 09:01:09 nit: Can you elaborate why it crashes and what the
Andrew T Wilson (Slow) 2012/12/10 10:12:40 Done.
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->core()->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();
Mattias Nissler (ping if slow) 2012/12/10 09:01:09 nit: declaring a |connector| local might improve r
Andrew T Wilson (Slow) 2012/12/10 10:12:40 Done.
173 manager->Connect(g_browser_process->local_state(), service);
174 DCHECK(manager->core()->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->core()->service()->IsInitializationComplete())
183 OnInitializationCompleted(manager->core()->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->DisconnectAndRemovePolicy(); 192 manager->DisconnectAndRemovePolicy();
118 } else {
119 // Initialize the UserCloudPolicyManager if it isn't already initialized.
120 if (!manager->core()->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->Connect(g_browser_process->local_state(), service);
132 DCHECK(manager->core()->service());
133 manager->core()->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->core()->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->core()->service()); 198 DCHECK_EQ(service, manager->core()->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()->core()->client(), client);
261 if (pending_fetch_) {
262 UserCloudPolicyManager* manager = GetManager();
263 if (manager->IsClientRegistered()) {
264 // Request a policy fetch.
265 manager->core()->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