Home | History | Annotate | Download | only in cloud
      1 // Copyright 2014 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/policy/cloud/user_policy_signin_service_mobile.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/callback.h"
     10 #include "base/command_line.h"
     11 #include "base/logging.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/prefs/pref_service.h"
     14 #include "base/time/time.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     17 #include "chrome/common/pref_names.h"
     18 #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
     19 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
     20 #include "components/policy/core/common/policy_switches.h"
     21 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     22 #include "components/signin/core/browser/signin_manager.h"
     23 #include "net/base/network_change_notifier.h"
     24 #include "net/url_request/url_request_context_getter.h"
     25 #include "policy/proto/device_management_backend.pb.h"
     26 
     27 namespace policy {
     28 
     29 namespace {
     30 
     31 enterprise_management::DeviceRegisterRequest::Type GetRegistrationType() {
     32   CommandLine* command_line = CommandLine::ForCurrentProcess();
     33   if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
     34     return enterprise_management::DeviceRegisterRequest::BROWSER;
     35 #if defined(OS_IOS)
     36   return enterprise_management::DeviceRegisterRequest::IOS_BROWSER;
     37 #elif defined(OS_ANDROID)
     38   return enterprise_management::DeviceRegisterRequest::ANDROID_BROWSER;
     39 #else
     40 #error "This file can be built only on OS_IOS or OS_ANDROID."
     41 #endif
     42 }
     43 
     44 }  // namespace
     45 
     46 UserPolicySigninService::UserPolicySigninService(
     47     Profile* profile,
     48     PrefService* local_state,
     49     DeviceManagementService* device_management_service,
     50     UserCloudPolicyManager* policy_manager,
     51     SigninManager* signin_manager,
     52     scoped_refptr<net::URLRequestContextGetter> system_request_context,
     53     ProfileOAuth2TokenService* token_service)
     54     : UserPolicySigninServiceBase(profile,
     55                                   local_state,
     56                                   device_management_service,
     57                                   policy_manager,
     58                                   signin_manager,
     59                                   system_request_context),
     60       oauth2_token_service_(token_service),
     61       profile_prefs_(profile->GetPrefs()),
     62       weak_factory_(this) {
     63 #if defined(OS_IOS)
     64   // iOS doesn't create this service with the Profile; instead it's created
     65   // a little bit later. See UserPolicySigninServiceFactory.
     66   InitializeOnProfileReady(profile);
     67 #endif
     68 }
     69 
     70 UserPolicySigninService::~UserPolicySigninService() {}
     71 
     72 void UserPolicySigninService::RegisterForPolicy(
     73     const std::string& username,
     74     const PolicyRegistrationCallback& callback) {
     75   RegisterForPolicyInternal(username, "", callback);
     76 }
     77 
     78 #if !defined(OS_ANDROID)
     79 void UserPolicySigninService::RegisterForPolicyWithAccessToken(
     80     const std::string& username,
     81     const std::string& access_token,
     82     const PolicyRegistrationCallback& callback) {
     83   RegisterForPolicyInternal(username, access_token, callback);
     84 }
     85 
     86 // static
     87 std::vector<std::string> UserPolicySigninService::GetScopes() {
     88   return CloudPolicyClientRegistrationHelper::GetScopes();
     89 }
     90 #endif
     91 
     92 void UserPolicySigninService::RegisterForPolicyInternal(
     93     const std::string& username,
     94     const std::string& access_token,
     95     const PolicyRegistrationCallback& callback) {
     96   // Create a new CloudPolicyClient for fetching the DMToken.
     97   scoped_ptr<CloudPolicyClient> policy_client = CreateClientForRegistrationOnly(
     98       username);
     99   if (!policy_client) {
    100     callback.Run(std::string(), std::string());
    101     return;
    102   }
    103 
    104   CancelPendingRegistration();
    105 
    106   // Fire off the registration process. Callback keeps the CloudPolicyClient
    107   // alive for the length of the registration process.
    108   registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
    109       policy_client.get(),
    110       GetRegistrationType()));
    111 
    112   if (access_token.empty()) {
    113     registration_helper_->StartRegistration(
    114         oauth2_token_service_,
    115         username,
    116         base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
    117                    base::Unretained(this),
    118                    base::Passed(&policy_client),
    119                    callback));
    120   } else {
    121 #if defined(OS_ANDROID)
    122     NOTREACHED();
    123 #else
    124     registration_helper_->StartRegistrationWithAccessToken(
    125         access_token,
    126         base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
    127                    base::Unretained(this),
    128                    base::Passed(&policy_client),
    129                    callback));
    130 #endif
    131   }
    132 }
    133 
    134 void UserPolicySigninService::CallPolicyRegistrationCallback(
    135     scoped_ptr<CloudPolicyClient> client,
    136     PolicyRegistrationCallback callback) {
    137   registration_helper_.reset();
    138   callback.Run(client->dm_token(), client->client_id());
    139 }
    140 
    141 void UserPolicySigninService::Shutdown() {
    142   CancelPendingRegistration();
    143   registration_helper_.reset();
    144   UserPolicySigninServiceBase::Shutdown();
    145 }
    146 
    147 void UserPolicySigninService::OnInitializationCompleted(
    148     CloudPolicyService* service) {
    149   UserCloudPolicyManager* manager = policy_manager();
    150   DCHECK_EQ(service, manager->core()->service());
    151   DCHECK(service->IsInitializationComplete());
    152   // The service is now initialized - if the client is not yet registered, then
    153   // it means that there is no cached policy and so we need to initiate a new
    154   // client registration.
    155   if (manager->IsClientRegistered()) {
    156     DVLOG(1) << "Client already registered - not fetching DMToken";
    157     return;
    158   }
    159 
    160   net::NetworkChangeNotifier::ConnectionType connection_type =
    161       net::NetworkChangeNotifier::GetConnectionType();
    162   base::TimeDelta retry_delay = base::TimeDelta::FromDays(3);
    163   if (connection_type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
    164       connection_type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
    165     retry_delay = base::TimeDelta::FromDays(1);
    166   }
    167 
    168   base::Time last_check_time = base::Time::FromInternalValue(
    169       profile_prefs_->GetInt64(prefs::kLastPolicyCheckTime));
    170   base::Time now = base::Time::Now();
    171   base::Time next_check_time = last_check_time + retry_delay;
    172 
    173   // Check immediately if no check was ever done before (last_check_time == 0),
    174   // or if the last check was in the future (?), or if we're already past the
    175   // next check time. Otherwise, delay checking until the next check time.
    176   base::TimeDelta try_registration_delay = base::TimeDelta::FromSeconds(5);
    177   if (now > last_check_time && now < next_check_time)
    178     try_registration_delay = next_check_time - now;
    179 
    180   base::MessageLoop::current()->PostDelayedTask(
    181       FROM_HERE,
    182       base::Bind(&UserPolicySigninService::RegisterCloudPolicyService,
    183                  weak_factory_.GetWeakPtr()),
    184       try_registration_delay);
    185 }
    186 
    187 void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
    188   CancelPendingRegistration();
    189   UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
    190 }
    191 
    192 void UserPolicySigninService::RegisterCloudPolicyService() {
    193   // If the user signed-out while this task was waiting then Shutdown() would
    194   // have been called, which would have invalidated this task. Since we're here
    195   // then the user must still be signed-in.
    196   const std::string& username = signin_manager()->GetAuthenticatedUsername();
    197   DCHECK(!username.empty());
    198   DCHECK(!policy_manager()->IsClientRegistered());
    199   DCHECK(policy_manager()->core()->client());
    200 
    201   // Persist the current time as the last policy registration attempt time.
    202   profile_prefs_->SetInt64(prefs::kLastPolicyCheckTime,
    203                            base::Time::Now().ToInternalValue());
    204 
    205   registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
    206       policy_manager()->core()->client(),
    207       GetRegistrationType()));
    208   registration_helper_->StartRegistration(
    209       oauth2_token_service_,
    210       username,
    211       base::Bind(&UserPolicySigninService::OnRegistrationDone,
    212                  base::Unretained(this)));
    213 }
    214 
    215 void UserPolicySigninService::CancelPendingRegistration() {
    216   weak_factory_.InvalidateWeakPtrs();
    217 }
    218 
    219 void UserPolicySigninService::OnRegistrationDone() {
    220   registration_helper_.reset();
    221 }
    222 
    223 }  // namespace policy
    224