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 weak_factory_(this), 61 oauth2_token_service_(token_service), 62 profile_prefs_(profile->GetPrefs()) { 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