Home | History | Annotate | Download | only in policy
      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/chromeos/policy/user_cloud_policy_manager_chromeos.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/logging.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
     12 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
     13 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     14 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h"
     15 #include "chrome/browser/policy/cloud/resource_cache.h"
     16 #include "chrome/browser/policy/policy_bundle.h"
     17 #include "chrome/browser/policy/policy_domain_descriptor.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "net/url_request/url_request_context_getter.h"
     20 
     21 namespace em = enterprise_management;
     22 
     23 namespace policy {
     24 
     25 UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
     26     scoped_ptr<CloudPolicyStore> store,
     27     scoped_ptr<ResourceCache> resource_cache,
     28     bool wait_for_policy_fetch,
     29     base::TimeDelta initial_policy_fetch_timeout)
     30     : CloudPolicyManager(
     31           PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
     32           store.get()),
     33       store_(store.Pass()),
     34       wait_for_policy_fetch_(wait_for_policy_fetch),
     35       policy_fetch_timeout_(false, false) {
     36   if (wait_for_policy_fetch_) {
     37     policy_fetch_timeout_.Start(
     38         FROM_HERE,
     39         initial_policy_fetch_timeout,
     40         base::Bind(&UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch,
     41                    base::Unretained(this)));
     42   }
     43   if (resource_cache) {
     44     component_policy_service_.reset(new ComponentCloudPolicyService(
     45         this, store_.get(), resource_cache.Pass()));
     46   }
     47 }
     48 
     49 UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
     50 
     51 void UserCloudPolicyManagerChromeOS::Connect(
     52     PrefService* local_state,
     53     DeviceManagementService* device_management_service,
     54     scoped_refptr<net::URLRequestContextGetter> request_context,
     55     UserAffiliation user_affiliation) {
     56   DCHECK(device_management_service);
     57   DCHECK(local_state);
     58   local_state_ = local_state;
     59   scoped_ptr<CloudPolicyClient> cloud_policy_client(
     60       new CloudPolicyClient(std::string(), std::string(), user_affiliation,
     61                             NULL, device_management_service));
     62   core()->Connect(cloud_policy_client.Pass());
     63   client()->AddObserver(this);
     64 
     65   if (component_policy_service_)
     66     component_policy_service_->Connect(client(), request_context);
     67 
     68   // Determine the next step after the CloudPolicyService initializes.
     69   if (service()->IsInitializationComplete()) {
     70     OnInitializationCompleted(service());
     71   } else {
     72     service()->AddObserver(this);
     73   }
     74 }
     75 
     76 void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
     77     const std::string& access_token) {
     78   access_token_ = access_token;
     79   if (service() && service()->IsInitializationComplete() &&
     80       client() && !client()->is_registered()) {
     81     OnOAuth2PolicyTokenFetched(
     82         access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
     83   }
     84 }
     85 
     86 bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const {
     87   return client() && client()->is_registered();
     88 }
     89 
     90 void UserCloudPolicyManagerChromeOS::Shutdown() {
     91   if (client())
     92     client()->RemoveObserver(this);
     93   if (service())
     94     service()->RemoveObserver(this);
     95   token_fetcher_.reset();
     96   component_policy_service_.reset();
     97   CloudPolicyManager::Shutdown();
     98 }
     99 
    100 bool UserCloudPolicyManagerChromeOS::IsInitializationComplete(
    101     PolicyDomain domain) const {
    102   if (!CloudPolicyManager::IsInitializationComplete(domain))
    103     return false;
    104   if (domain == POLICY_DOMAIN_CHROME)
    105     return !wait_for_policy_fetch_;
    106   if (ComponentCloudPolicyService::SupportsDomain(domain) &&
    107       component_policy_service_) {
    108     return component_policy_service_->is_initialized();
    109   }
    110   return true;
    111 }
    112 
    113 void UserCloudPolicyManagerChromeOS::RegisterPolicyDomain(
    114     scoped_refptr<const PolicyDomainDescriptor> descriptor) {
    115   if (ComponentCloudPolicyService::SupportsDomain(descriptor->domain()) &&
    116       component_policy_service_) {
    117     component_policy_service_->RegisterPolicyDomain(descriptor);
    118   }
    119 }
    120 
    121 scoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() {
    122   scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle();
    123   if (component_policy_service_)
    124     bundle->MergeFrom(component_policy_service_->policy());
    125   return bundle.Pass();
    126 }
    127 
    128 void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
    129     CloudPolicyService* cloud_policy_service) {
    130   DCHECK_EQ(service(), cloud_policy_service);
    131   cloud_policy_service->RemoveObserver(this);
    132   // If the CloudPolicyClient isn't registered at this stage then it needs an
    133   // OAuth token for the initial registration.
    134   //
    135   // If |wait_for_policy_fetch_| is true then Profile initialization is blocking
    136   // on the initial policy fetch, so the token must be fetched immediately.
    137   // In that case, the signin Profile is used to authenticate a Gaia request to
    138   // fetch a refresh token, and then the policy token is fetched.
    139   //
    140   // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder
    141   // service will eventually call OnAccessTokenAvailable() once an access token
    142   // is available. That call may have already happened while waiting for
    143   // initialization of the CloudPolicyService, so in that case check if an
    144   // access token is already available.
    145   if (!client()->is_registered()) {
    146     if (wait_for_policy_fetch_) {
    147       FetchPolicyOAuthTokenUsingSigninProfile();
    148     } else if (!access_token_.empty()) {
    149       OnOAuth2PolicyTokenFetched(
    150           access_token_, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
    151     }
    152   }
    153 
    154   if (!wait_for_policy_fetch_) {
    155     // If this isn't blocking on a policy fetch then
    156     // CloudPolicyManager::OnStoreLoaded() already published the cached policy.
    157     // Start the refresh scheduler now, which will eventually refresh the
    158     // cached policy or make the first fetch once the OAuth2 token is
    159     // available.
    160     StartRefreshSchedulerIfReady();
    161   }
    162 }
    163 
    164 void UserCloudPolicyManagerChromeOS::OnPolicyFetched(
    165     CloudPolicyClient* client) {
    166   // No action required. If we're blocked on a policy fetch, we'll learn about
    167   // completion of it through OnInitialPolicyFetchComplete().
    168 }
    169 
    170 void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged(
    171     CloudPolicyClient* cloud_policy_client) {
    172   DCHECK_EQ(client(), cloud_policy_client);
    173   if (wait_for_policy_fetch_) {
    174     // If we're blocked on the policy fetch, now is a good time to issue it.
    175     if (client()->is_registered()) {
    176       service()->RefreshPolicy(
    177           base::Bind(
    178               &UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete,
    179               base::Unretained(this)));
    180     } else {
    181       // If the client has switched to not registered, we bail out as this
    182       // indicates the cloud policy setup flow has been aborted.
    183       CancelWaitForPolicyFetch();
    184     }
    185   }
    186 }
    187 
    188 void UserCloudPolicyManagerChromeOS::OnClientError(
    189     CloudPolicyClient* cloud_policy_client) {
    190   DCHECK_EQ(client(), cloud_policy_client);
    191   CancelWaitForPolicyFetch();
    192 }
    193 
    194 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyRefreshNeeded() {
    195   core()->RefreshSoon();
    196 }
    197 
    198 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
    199   CheckAndPublishPolicy();
    200   StartRefreshSchedulerIfReady();
    201 }
    202 
    203 void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() {
    204   scoped_refptr<net::URLRequestContextGetter> signin_context;
    205   Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile();
    206   if (signin_profile)
    207     signin_context = signin_profile->GetRequestContext();
    208   if (!signin_context.get()) {
    209     LOG(ERROR) << "No signin Profile for policy oauth token fetch!";
    210     OnOAuth2PolicyTokenFetched(
    211         std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE));
    212     return;
    213   }
    214 
    215   token_fetcher_.reset(new PolicyOAuth2TokenFetcher(
    216       signin_context.get(),
    217       g_browser_process->system_request_context(),
    218       base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
    219                  base::Unretained(this))));
    220   token_fetcher_->Start();
    221 }
    222 
    223 void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
    224     const std::string& policy_token,
    225     const GoogleServiceAuthError& error) {
    226   DCHECK(!client()->is_registered());
    227   if (error.state() == GoogleServiceAuthError::NONE) {
    228     // Start client registration. Either OnRegistrationStateChanged() or
    229     // OnClientError() will be called back.
    230     client()->Register(em::DeviceRegisterRequest::USER,
    231                        policy_token, std::string(), false, std::string());
    232   } else {
    233     // Failed to get a token, stop waiting and use an empty policy.
    234     CancelWaitForPolicyFetch();
    235   }
    236 
    237   token_fetcher_.reset();
    238 }
    239 
    240 void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
    241     bool success) {
    242   CancelWaitForPolicyFetch();
    243 }
    244 
    245 void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
    246   if (!wait_for_policy_fetch_)
    247     return;
    248 
    249   wait_for_policy_fetch_ = false;
    250   CheckAndPublishPolicy();
    251   // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
    252   // can be started.
    253   StartRefreshSchedulerIfReady();
    254 }
    255 
    256 void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() {
    257   if (core()->refresh_scheduler())
    258     return;  // Already started.
    259 
    260   if (wait_for_policy_fetch_)
    261     return;  // Still waiting for the initial, blocking fetch.
    262 
    263   if (!service() || !local_state_)
    264     return;  // Not connected.
    265 
    266   if (component_policy_service_ &&
    267       !component_policy_service_->is_initialized()) {
    268     // If the client doesn't have the list of components to fetch yet then don't
    269     // start the scheduler. The |component_policy_service_| will call back into
    270     // OnComponentCloudPolicyUpdated() once it's ready.
    271     return;
    272   }
    273 
    274   StartRefreshScheduler();
    275   core()->TrackRefreshDelayPref(local_state_, prefs::kUserPolicyRefreshRate);
    276 }
    277 
    278 }  // namespace policy
    279