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 27namespace policy { 28 29namespace { 30 31enterprise_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 46UserPolicySigninService::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 70UserPolicySigninService::~UserPolicySigninService() {} 71 72void UserPolicySigninService::RegisterForPolicy( 73 const std::string& username, 74 const PolicyRegistrationCallback& callback) { 75 RegisterForPolicyInternal(username, "", callback); 76} 77 78#if !defined(OS_ANDROID) 79void 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 87std::vector<std::string> UserPolicySigninService::GetScopes() { 88 return CloudPolicyClientRegistrationHelper::GetScopes(); 89} 90#endif 91 92void 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 134void 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 141void UserPolicySigninService::Shutdown() { 142 CancelPendingRegistration(); 143 registration_helper_.reset(); 144 UserPolicySigninServiceBase::Shutdown(); 145} 146 147void 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 187void UserPolicySigninService::ShutdownUserCloudPolicyManager() { 188 CancelPendingRegistration(); 189 UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager(); 190} 191 192void 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 215void UserPolicySigninService::CancelPendingRegistration() { 216 weak_factory_.InvalidateWeakPtrs(); 217} 218 219void UserPolicySigninService::OnRegistrationDone() { 220 registration_helper_.reset(); 221} 222 223} // namespace policy 224