device_local_account_policy_service.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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/device_local_account_policy_service.h" 6 7#include "base/logging.h" 8#include "base/message_loop.h" 9#include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" 10#include "chrome/browser/policy/cloud/cloud_policy_client.h" 11#include "chrome/browser/policy/cloud/cloud_policy_constants.h" 12#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 13#include "chrome/browser/policy/cloud/device_management_service.h" 14#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 15#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 16#include "chromeos/dbus/session_manager_client.h" 17#include "policy/policy_constants.h" 18 19namespace em = enterprise_management; 20 21namespace policy { 22 23DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker( 24 scoped_ptr<DeviceLocalAccountPolicyStore> store) 25 : store_(store.Pass()), 26 core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType, 27 store_->account_id()), 28 store_.get()) {} 29 30DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {} 31 32const std::string& DeviceLocalAccountPolicyBroker::account_id() const { 33 return store_->account_id(); 34} 35 36void DeviceLocalAccountPolicyBroker::Connect( 37 scoped_ptr<CloudPolicyClient> client) { 38 core_.Connect(client.Pass()); 39 core_.StartRefreshScheduler(); 40 UpdateRefreshDelay(); 41} 42 43void DeviceLocalAccountPolicyBroker::Disconnect() { 44 core_.Disconnect(); 45} 46 47void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() { 48 if (core_.refresh_scheduler()) { 49 const Value* policy_value = 50 store_->policy_map().GetValue(key::kPolicyRefreshRate); 51 int delay = 0; 52 if (policy_value && policy_value->GetAsInteger(&delay)) 53 core_.refresh_scheduler()->SetRefreshDelay(delay); 54 } 55} 56 57std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const { 58 std::string display_name; 59 const base::Value* display_name_value = 60 store_->policy_map().GetValue(policy::key::kUserDisplayName); 61 if (display_name_value) 62 display_name_value->GetAsString(&display_name); 63 return display_name; 64} 65 66DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService( 67 chromeos::SessionManagerClient* session_manager_client, 68 chromeos::DeviceSettingsService* device_settings_service) 69 : session_manager_client_(session_manager_client), 70 device_settings_service_(device_settings_service), 71 device_management_service_(NULL) { 72 device_settings_service_->AddObserver(this); 73 DeviceSettingsUpdated(); 74} 75 76DeviceLocalAccountPolicyService::~DeviceLocalAccountPolicyService() { 77 device_settings_service_->RemoveObserver(this); 78 DeleteBrokers(&policy_brokers_); 79} 80 81void DeviceLocalAccountPolicyService::Connect( 82 DeviceManagementService* device_management_service) { 83 DCHECK(!device_management_service_); 84 device_management_service_ = device_management_service; 85 86 // Connect the brokers. 87 for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); 88 broker != policy_brokers_.end(); ++broker) { 89 DCHECK(!broker->second->core()->client()); 90 broker->second->Connect( 91 CreateClientForAccount(broker->second->account_id()).Pass()); 92 } 93} 94 95void DeviceLocalAccountPolicyService::Disconnect() { 96 DCHECK(device_management_service_); 97 device_management_service_ = NULL; 98 99 // Disconnect the brokers. 100 for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); 101 broker != policy_brokers_.end(); ++broker) { 102 broker->second->Disconnect(); 103 } 104} 105 106DeviceLocalAccountPolicyBroker* 107 DeviceLocalAccountPolicyService::GetBrokerForAccount( 108 const std::string& account_id) { 109 PolicyBrokerMap::iterator entry = policy_brokers_.find(account_id); 110 if (entry == policy_brokers_.end()) 111 return NULL; 112 113 if (!entry->second) 114 entry->second = CreateBroker(account_id).release(); 115 116 return entry->second; 117} 118 119bool DeviceLocalAccountPolicyService::IsPolicyAvailableForAccount( 120 const std::string& account_id) { 121 DeviceLocalAccountPolicyBroker* broker = GetBrokerForAccount(account_id); 122 return broker && broker->core()->store()->is_managed(); 123} 124 125void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) { 126 observers_.AddObserver(observer); 127} 128 129void DeviceLocalAccountPolicyService::RemoveObserver(Observer* observer) { 130 observers_.RemoveObserver(observer); 131} 132 133void DeviceLocalAccountPolicyService::OwnershipStatusChanged() { 134 // TODO(mnissler): The policy key has changed, re-fetch policy. For 135 // consumer devices, re-sign the current settings and send updates to 136 // session_manager. 137} 138 139void DeviceLocalAccountPolicyService::DeviceSettingsUpdated() { 140 const em::ChromeDeviceSettingsProto* device_settings = 141 device_settings_service_->device_settings(); 142 if (device_settings) 143 UpdateAccountList(*device_settings); 144} 145 146void DeviceLocalAccountPolicyService::OnStoreLoaded(CloudPolicyStore* store) { 147 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); 148 broker->UpdateRefreshDelay(); 149 FOR_EACH_OBSERVER(Observer, observers_, 150 OnPolicyUpdated(broker->account_id())); 151} 152 153void DeviceLocalAccountPolicyService::OnStoreError(CloudPolicyStore* store) { 154 DeviceLocalAccountPolicyBroker* broker = GetBrokerForStore(store); 155 FOR_EACH_OBSERVER(Observer, observers_, 156 OnPolicyUpdated(broker->account_id())); 157} 158 159void DeviceLocalAccountPolicyService::UpdateAccountList( 160 const em::ChromeDeviceSettingsProto& device_settings) { 161 using google::protobuf::RepeatedPtrField; 162 163 // Update |policy_brokers_|, keeping existing entries. 164 PolicyBrokerMap new_policy_brokers; 165 const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts = 166 device_settings.device_local_accounts().account(); 167 RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry; 168 for (entry = accounts.begin(); entry != accounts.end(); ++entry) { 169 std::string account_id; 170 if (entry->has_type() && 171 entry->type() == 172 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION) { 173 account_id = entry->account_id(); 174 } else if (entry->has_deprecated_public_session_id()) { 175 account_id = entry->deprecated_public_session_id(); 176 } 177 178 if (account_id.empty()) 179 continue; 180 181 // Sanity check for whether this account ID has already been processed. 182 DeviceLocalAccountPolicyBroker*& new_broker = 183 new_policy_brokers[account_id]; 184 if (new_broker) { 185 LOG(WARNING) << "Duplicate public account " << account_id; 186 continue; 187 } 188 189 // Reuse the existing broker if present. 190 DeviceLocalAccountPolicyBroker*& existing_broker = 191 policy_brokers_[account_id]; 192 new_broker = existing_broker; 193 existing_broker = NULL; 194 195 // Fire up the cloud connection for fetching policy for the account from 196 // the cloud if this is an enterprise-managed device. 197 if (!new_broker || !new_broker->core()->client()) { 198 scoped_ptr<CloudPolicyClient> client( 199 CreateClientForAccount(account_id)); 200 if (client.get()) { 201 if (!new_broker) 202 new_broker = CreateBroker(account_id).release(); 203 new_broker->Connect(client.Pass()); 204 } 205 } 206 } 207 policy_brokers_.swap(new_policy_brokers); 208 DeleteBrokers(&new_policy_brokers); 209 210 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged()); 211} 212 213scoped_ptr<DeviceLocalAccountPolicyBroker> 214 DeviceLocalAccountPolicyService::CreateBroker( 215 const std::string& account_id) { 216 scoped_ptr<DeviceLocalAccountPolicyStore> store( 217 new DeviceLocalAccountPolicyStore(account_id, session_manager_client_, 218 device_settings_service_)); 219 scoped_ptr<DeviceLocalAccountPolicyBroker> broker( 220 new DeviceLocalAccountPolicyBroker(store.Pass())); 221 broker->core()->store()->AddObserver(this); 222 broker->core()->store()->Load(); 223 return broker.Pass(); 224} 225 226void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) { 227 for (PolicyBrokerMap::iterator broker = map->begin(); broker != map->end(); 228 ++broker) { 229 if (broker->second) { 230 broker->second->core()->store()->RemoveObserver(this); 231 delete broker->second; 232 } 233 } 234 map->clear(); 235} 236 237DeviceLocalAccountPolicyBroker* 238 DeviceLocalAccountPolicyService::GetBrokerForStore( 239 CloudPolicyStore* store) { 240 for (PolicyBrokerMap::iterator broker(policy_brokers_.begin()); 241 broker != policy_brokers_.end(); ++broker) { 242 if (broker->second->core()->store() == store) 243 return broker->second; 244 } 245 return NULL; 246} 247 248scoped_ptr<CloudPolicyClient> 249 DeviceLocalAccountPolicyService::CreateClientForAccount( 250 const std::string& account_id) { 251 const em::PolicyData* policy_data = device_settings_service_->policy_data(); 252 if (!policy_data || 253 !policy_data->has_request_token() || 254 !policy_data->has_device_id() || 255 !device_management_service_) { 256 return scoped_ptr<CloudPolicyClient>(); 257 } 258 259 scoped_ptr<CloudPolicyClient> client( 260 new CloudPolicyClient(std::string(), std::string(), 261 USER_AFFILIATION_MANAGED, 262 NULL, device_management_service_)); 263 client->SetupRegistration(policy_data->request_token(), 264 policy_data->device_id()); 265 return client.Pass(); 266} 267 268} // namespace policy 269