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

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: review feedback 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 // (DoFinalInit() has not yet been called, so ProfileIOData and
133 // SSLConfigServiceManager have not been created yet).
134 SigninManager* signin_manager =
135 SigninManagerFactory::GetForProfile(profile_);
136 if (signin_manager->GetAuthenticatedUsername().empty())
137 ShutdownUserCloudPolicyManager();
138 else
139 InitializeUserCloudPolicyManager();
83 break; 140 break;
141 }
84 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 142 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
85 const TokenService::TokenAvailableDetails& token_details = 143 const TokenService::TokenAvailableDetails& token_details =
86 *(content::Details<const TokenService::TokenAvailableDetails>( 144 *(content::Details<const TokenService::TokenAvailableDetails>(
87 details).ptr()); 145 details).ptr());
88 if (token_details.service() == 146 if (token_details.service() ==
89 GaiaConstants::kGaiaOAuth2LoginRefreshToken) { 147 GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
90 // TokenService now has a refresh token, so initialize the 148 // TokenService now has a refresh token (implying that the user is
91 // UserCloudPolicyManager. 149 // signed in) so initialize the UserCloudPolicyManager.
92 ConfigureUserCloudPolicyManager(); 150 InitializeUserCloudPolicyManager();
93 } 151 }
94 break; 152 break;
95 } 153 }
96 default: 154 default:
97 NOTREACHED(); 155 NOTREACHED();
98 } 156 }
99 } 157 }
100 158
159 void UserPolicySigninService::InitializeUserCloudPolicyManager() {
160 UserCloudPolicyManager* manager = GetManager();
161 DCHECK(!SigninManagerFactory::GetForProfile(profile_)->
162 GetAuthenticatedUsername().empty());
163 if (!manager->core()->service()) {
164 // Make sure we've initialized the DeviceManagementService. It's OK to
165 // call this multiple times so we do it every time we initialize the
166 // UserCloudPolicyManager.
167 g_browser_process->browser_policy_connector()->
168 ScheduleServiceInitialization(
169 kPolicyServiceInitializationDelayMilliseconds);
170 // If there is no cached DMToken then we can detect this below (or when
171 // the OnInitializationCompleted() callback is invoked).
172 BrowserPolicyConnector* connector =
173 g_browser_process->browser_policy_connector();
174 manager->Connect(g_browser_process->local_state(),
175 connector->device_management_service());
176 DCHECK(manager->core()->service());
177 StartObserving();
178 }
101 179
102 void UserPolicySigninService::ConfigureUserCloudPolicyManager() { 180 // If the CloudPolicyService is initialized, kick off registration. If the
103 // Don't do anything unless cloud policy is enabled. 181 // TokenService doesn't have an OAuth token yet (e.g. this is during initial
104 if (!profile_->GetPrefs()->GetBoolean(prefs::kLoadCloudPolicyOnSignin)) 182 // signin, or when dynamically loading a signed-in policy) this does nothing
105 return; 183 // until the OAuth token is loaded.
184 if (manager->core()->service()->IsInitializationComplete())
185 OnInitializationCompleted(manager->core()->service());
186 }
106 187
107 // Either startup or shutdown the UserCloudPolicyManager depending on whether 188 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
108 // the user is signed in or not. 189 StopObserving();
190 NotifyPendingFetchCallback(false);
191
109 UserCloudPolicyManager* manager = GetManager(); 192 UserCloudPolicyManager* manager = GetManager();
110 if (!manager) 193 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(); 194 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 } 195 }
144 196
145 void UserPolicySigninService::OnInitializationCompleted( 197 void UserPolicySigninService::OnInitializationCompleted(
146 CloudPolicyService* service) { 198 CloudPolicyService* service) {
147 UserCloudPolicyManager* manager = GetManager(); 199 UserCloudPolicyManager* manager = GetManager();
148 DCHECK_EQ(service, manager->core()->service()); 200 DCHECK_EQ(service, manager->core()->service());
149 DCHECK(service->IsInitializationComplete()); 201 DCHECK(service->IsInitializationComplete());
150 // The service is now initialized - if the client is not yet registered, then 202 // 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 203 // it means that there is no cached policy and so we need to initiate a new
152 // client registration. 204 // client registration.
153 DVLOG_IF(1, manager->IsClientRegistered()) 205 DVLOG_IF(1, manager->IsClientRegistered())
154 << "Client already registered - not fetching DMToken"; 206 << "Client already registered - not fetching DMToken";
155 if (!manager->IsClientRegistered()) 207 if (!manager->IsClientRegistered()) {
156 RegisterCloudPolicyService(); 208 std::string token = TokenServiceFactory::GetForProfile(profile_)->
209 GetOAuth2LoginRefreshToken();
210 if (token.empty()) {
211 // No token yet - this class listens for NOTIFICATION_TOKEN_AVAILABLE
212 // and will re-attempt registration once the token is available.
213 DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
214 return;
215 }
216 RegisterCloudPolicyService(token);
217 }
157 } 218 }
158 219
159 void UserPolicySigninService::RegisterCloudPolicyService() { 220 void UserPolicySigninService::RegisterCloudPolicyService(
221 std::string login_token) {
222 DCHECK(!GetManager()->IsClientRegistered());
160 DVLOG(1) << "Fetching new DM Token"; 223 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. 224 // Do nothing if already fetching an access token.
171 if (oauth2_access_token_fetcher_.get()) 225 if (oauth2_access_token_fetcher_.get())
172 return; 226 return;
173 227
174 // Start fetching an OAuth2 access token for the device management service and 228 // Start fetching an OAuth2 access token for the device management service and
175 // hand it off to the CloudPolicyClient when done. 229 // hand it off to the CloudPolicyClient when done.
176 oauth2_access_token_fetcher_.reset( 230 oauth2_access_token_fetcher_.reset(
177 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext())); 231 new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext()));
178 std::vector<std::string> scopes(1, kServiceScopeChromeOSDeviceManagement); 232 std::vector<std::string> scopes(1, kServiceScopeChromeOSDeviceManagement);
179 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); 233 GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
180 oauth2_access_token_fetcher_->Start( 234 oauth2_access_token_fetcher_->Start(
181 gaia_urls->oauth2_chrome_client_id(), 235 gaia_urls->oauth2_chrome_client_id(),
182 gaia_urls->oauth2_chrome_client_secret(), 236 gaia_urls->oauth2_chrome_client_secret(),
183 token, 237 login_token,
184 scopes); 238 scopes);
185 } 239 }
186 240
187 void UserPolicySigninService::OnGetTokenFailure( 241 void UserPolicySigninService::OnGetTokenFailure(
188 const GoogleServiceAuthError& error) { 242 const GoogleServiceAuthError& error) {
189 DLOG(WARNING) << "Could not fetch access token for " 243 DLOG(WARNING) << "Could not fetch access token for "
190 << kServiceScopeChromeOSDeviceManagement; 244 << kServiceScopeChromeOSDeviceManagement;
191 oauth2_access_token_fetcher_.reset(); 245 oauth2_access_token_fetcher_.reset();
246 // If there was a pending fetch request, let them know the fetch failed.
247 NotifyPendingFetchCallback(false);
192 } 248 }
193 249
194 void UserPolicySigninService::OnGetTokenSuccess( 250 void UserPolicySigninService::OnGetTokenSuccess(
195 const std::string& access_token, 251 const std::string& access_token,
196 const base::Time& expiration_time) { 252 const base::Time& expiration_time) {
197 UserCloudPolicyManager* manager = GetManager(); 253 UserCloudPolicyManager* manager = GetManager();
198 // Pass along the new access token to the CloudPolicyClient. 254 // Pass along the new access token to the CloudPolicyClient.
199 DVLOG(1) << "Fetched new scoped OAuth token:" << access_token; 255 DVLOG(1) << "Fetched new scoped OAuth token:" << access_token;
200 manager->RegisterClient(access_token); 256 manager->RegisterClient(access_token);
201 oauth2_access_token_fetcher_.reset(); 257 oauth2_access_token_fetcher_.reset();
202 } 258 }
203 259
260 void UserPolicySigninService::OnRegistrationStateChanged(
261 CloudPolicyClient* client) {
262 DCHECK_EQ(GetManager()->core()->client(), client);
263 if (pending_fetch_) {
264 UserCloudPolicyManager* manager = GetManager();
265 if (manager->IsClientRegistered()) {
266 // Request a policy fetch.
267 manager->core()->service()->RefreshPolicy(
268 base::Bind(
269 &UserPolicySigninService::NotifyPendingFetchCallback,
270 weak_factory_.GetWeakPtr()));
271 } else {
272 // Shouldn't be possible for the client to get unregistered.
273 NOTREACHED() << "Client unregistered while waiting for policy fetch";
274 }
275 }
276 }
277
278 void UserPolicySigninService::NotifyPendingFetchCallback(bool success) {
279 if (pending_fetch_) {
280 pending_fetch_ = false;
281 pending_fetch_callback_.Run(success);
282 }
283 }
284
285 void UserPolicySigninService::OnPolicyFetched(CloudPolicyClient* client) {
286 // Do nothing when policy is fetched - if the policy fetch is successful,
287 // NotifyPendingFetchCallback will be invoked.
288 }
289
290 void UserPolicySigninService::OnClientError(CloudPolicyClient* client) {
291 NotifyPendingFetchCallback(false);
292 }
293
204 void UserPolicySigninService::Shutdown() { 294 void UserPolicySigninService::Shutdown() {
205 StopObserving(); 295 StopObserving();
206 } 296 }
207 297
208 UserCloudPolicyManager* UserPolicySigninService::GetManager() { 298 UserCloudPolicyManager* UserPolicySigninService::GetManager() {
209 return UserCloudPolicyManagerFactory::GetForProfile(profile_); 299 return UserCloudPolicyManagerFactory::GetForProfile(profile_);
210 } 300 }
211 301
212 } // namespace policy 302 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/user_policy_signin_service.h ('k') | chrome/browser/policy/user_policy_signin_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698