1 // Copyright (c) 2013 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/chromeos/policy/user_cloud_policy_token_forwarder.h" 6 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" 9 #include "chrome/browser/policy/cloud/cloud_policy_core.h" 10 #include "chrome/browser/signin/profile_oauth2_token_service.h" 11 #include "content/public/browser/notification_source.h" 12 #include "google_apis/gaia/gaia_constants.h" 13 14 namespace policy { 15 16 UserCloudPolicyTokenForwarder::UserCloudPolicyTokenForwarder( 17 UserCloudPolicyManagerChromeOS* manager, 18 ProfileOAuth2TokenService* token_service) 19 : manager_(manager), 20 token_service_(token_service) { 21 // Start by waiting for the CloudPolicyService to be initialized, so that 22 // we can check if it already has a DMToken or not. 23 if (manager_->core()->service()->IsInitializationComplete()) { 24 Initialize(); 25 } else { 26 manager_->core()->service()->AddObserver(this); 27 } 28 } 29 30 UserCloudPolicyTokenForwarder::~UserCloudPolicyTokenForwarder() {} 31 32 void UserCloudPolicyTokenForwarder::Shutdown() { 33 request_.reset(); 34 token_service_->RemoveObserver(this); 35 manager_->core()->service()->RemoveObserver(this); 36 } 37 38 void UserCloudPolicyTokenForwarder::OnRefreshTokenAvailable( 39 const std::string& account_id) { 40 RequestAccessToken(); 41 } 42 43 void UserCloudPolicyTokenForwarder::OnGetTokenSuccess( 44 const OAuth2TokenService::Request* request, 45 const std::string& access_token, 46 const base::Time& expiration_time) { 47 manager_->OnAccessTokenAvailable(access_token); 48 // All done here. 49 Shutdown(); 50 } 51 52 void UserCloudPolicyTokenForwarder::OnGetTokenFailure( 53 const OAuth2TokenService::Request* request, 54 const GoogleServiceAuthError& error) { 55 // This should seldom happen: if the user is signing in for the first time 56 // then this was an online signin and network errors are unlikely; if the 57 // user had already signed in before then he should have policy cached, and 58 // RequestAccessToken() wouldn't have been invoked. 59 // Still, something just went wrong (server 500, or something). Currently 60 // we don't recover in this case, and we'll just try to register for policy 61 // again on the next signin. 62 // TODO(joaodasilva, atwilson): consider blocking signin when this happens, 63 // so that the user has to try again before getting into the session. That 64 // would guarantee that a session always has fresh policy, or at least 65 // enforces a cached policy. 66 Shutdown(); 67 } 68 69 void UserCloudPolicyTokenForwarder::OnInitializationCompleted( 70 CloudPolicyService* service) { 71 Initialize(); 72 } 73 74 void UserCloudPolicyTokenForwarder::Initialize() { 75 if (manager_->IsClientRegistered()) { 76 // We already have a DMToken, so no need to ask for an access token. 77 // All done here. 78 Shutdown(); 79 return; 80 } 81 82 if (token_service_->RefreshTokenIsAvailable()) 83 RequestAccessToken(); 84 else 85 token_service_->AddObserver(this); 86 } 87 88 void UserCloudPolicyTokenForwarder::RequestAccessToken() { 89 OAuth2TokenService::ScopeSet scopes; 90 scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth); 91 request_ = token_service_->StartRequest(scopes, this); 92 } 93 94 } // namespace policy 95