1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/cloud_external_data_policy_observer.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <set> 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector> 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind_helpers.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/stl_util.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/values.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/profiles/profile_helper.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/policy/profile_policy_connector.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/policy/profile_policy_connector_factory.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chromeos/settings/cros_settings_names.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chromeos/settings/cros_settings_provider.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_core.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_store.h" 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h" 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_namespace.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_service.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h" 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/notification_details.h" 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/notification_service.h" 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/notification_source.h" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace policy { 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Helper class that observes a policy for a logged-in user, notifying the 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// |parent_| whenever the external data reference for this user changes. 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class CloudExternalDataPolicyObserver::PolicyServiceObserver 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : public PolicyService::Observer { 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyServiceObserver(CloudExternalDataPolicyObserver* parent, 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id, 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyService* policy_service); 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~PolicyServiceObserver(); 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // PolicyService::Observer: 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void OnPolicyUpdated(const PolicyNamespace& ns, 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap& previous, 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap& current) OVERRIDE; 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloudExternalDataPolicyObserver* parent_; 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string user_id_; 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyService* policy_service_; 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PolicyServiceObserver); 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CloudExternalDataPolicyObserver::PolicyServiceObserver::PolicyServiceObserver( 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloudExternalDataPolicyObserver* parent, 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id, 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyService* policy_service) 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : parent_(parent), 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) user_id_(user_id), 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy_service_(policy_service) { 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this); 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!IsDeviceLocalAccountUser(user_id, NULL)) { 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Notify |parent_| if the external data reference for |user_id_| is set 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // during login. This is omitted for device-local accounts because their 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // policy is available before login and the external data reference will 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // have been seen by the |parent_| already. 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap::Entry* entry = policy_service_->GetPolicies( 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) .Get(parent_->policy_); 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (entry) 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) parent_->HandleExternalDataPolicyUpdate(user_id_, entry); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CloudExternalDataPolicyObserver::PolicyServiceObserver:: 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~PolicyServiceObserver() { 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::PolicyServiceObserver::OnPolicyUpdated( 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyNamespace& ns, 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap& previous, 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap& current) { 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(ns == PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap::Entry* previous_entry = previous.Get(parent_->policy_); 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap::Entry* current_entry = current.Get(parent_->policy_); 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if ((!previous_entry && current_entry) || 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (previous_entry && !current_entry) || 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (previous_entry && current_entry && 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !previous_entry->Equals(*current_entry))) { 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Notify |parent_| if the external data reference for |user_id_| has 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // changed. 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) parent_->HandleExternalDataPolicyUpdate(user_id_, current_entry); 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::Delegate::OnExternalDataSet( 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& policy, 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id) { 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::Delegate::OnExternalDataCleared( 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& policy, 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id) { 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::Delegate::OnExternalDataFetched( 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& policy, 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id, 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<std::string> data) { 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CloudExternalDataPolicyObserver::Delegate::~Delegate() { 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CloudExternalDataPolicyObserver::CloudExternalDataPolicyObserver( 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chromeos::CrosSettings* cros_settings, 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceLocalAccountPolicyService* device_local_account_policy_service, 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& policy, 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Delegate* delegate) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : cros_settings_(cros_settings), 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_policy_service_(device_local_account_policy_service), 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy_(policy), 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_(delegate), 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_factory_(this) { 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notification_registrar_.Add( 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::NotificationService::AllSources()); 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (device_local_account_policy_service_) 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_policy_service_->AddObserver(this); 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_accounts_subscription_ = cros_settings_->AddSettingsObserver( 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chromeos::kAccountsPrefDeviceLocalAccounts, 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts, 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this))); 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CloudExternalDataPolicyObserver::~CloudExternalDataPolicyObserver() { 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (device_local_account_policy_service_) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_policy_service_->RemoveObserver(this); 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (DeviceLocalAccountEntryMap::iterator it = 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.begin(); 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it != device_local_account_entries_.end(); ++it) { 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it->second.DeleteOwnedMembers(); 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.clear(); 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::Init() { 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RetrieveDeviceLocalAccounts(); 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::Observe( 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int type, 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const content::NotificationSource& source, 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const content::NotificationDetails& details) { 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (type != chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED) { 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Profile* profile = content::Details<Profile>(details).ptr(); 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const user_manager::User* user = 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chromeos::ProfileHelper::Get()->GetUserByProfile(profile); 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!user) { 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id = user->email(); 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (ContainsKey(logged_in_user_observers_, user_id)) { 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ProfilePolicyConnector* policy_connector = 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ProfilePolicyConnectorFactory::GetForProfile(profile); 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) logged_in_user_observers_[user_id] = make_linked_ptr( 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new PolicyServiceObserver(this, 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) user_id, 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy_connector->policy_service())); 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::OnPolicyUpdated( 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id) { 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (ContainsKey(logged_in_user_observers_, user_id)) { 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // When a device-local account is logged in, a policy change triggers both 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // OnPolicyUpdated() and PolicyServiceObserver::OnPolicyUpdated(). Ignore 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the former so that the policy change is handled only once. 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!device_local_account_policy_service_) { 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceLocalAccountPolicyBroker* broker = 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_policy_service_->GetBrokerForUser(user_id); 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!broker) { 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The order in which |this| and the |device_local_account_policy_service_| 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // find out that a new device-local account has been added is undefined. If 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // no |broker| exists yet, the |device_local_account_policy_service_| must 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // not have seen the new |user_id| yet. OnPolicyUpdated() will be invoked 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // again by the |device_local_account_policy_service_| in this case when it 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // finds out about |user_id| and creates a |broker| for it. 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap::Entry* entry = 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) broker->core()->store()->policy_map().Get(policy_); 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!entry) { 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceLocalAccountEntryMap::iterator it = 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.find(user_id); 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (it != device_local_account_entries_.end()) { 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it->second.DeleteOwnedMembers(); 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.erase(it); 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) HandleExternalDataPolicyUpdate(user_id, NULL); 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PolicyMap::Entry& map_entry = device_local_account_entries_[user_id]; 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (map_entry.Equals(*entry)) 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) map_entry.DeleteOwnedMembers(); 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) map_entry = *entry->DeepCopy(); 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) HandleExternalDataPolicyUpdate(user_id, entry); 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::OnDeviceLocalAccountsChanged() { 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // No action needed here, changes to the list of device-local accounts get 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // handled via the kAccountsPrefDeviceLocalAccounts device setting observer. 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts() { 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Schedule a callback if device policy has not yet been verified. 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (chromeos::CrosSettingsProvider::TRUSTED != 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cros_settings_->PrepareTrustedValues(base::Bind( 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &CloudExternalDataPolicyObserver::RetrieveDeviceLocalAccounts, 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_factory_.GetWeakPtr()))) { 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<DeviceLocalAccount> device_local_account_list = 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) policy::GetDeviceLocalAccounts(cros_settings_); 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::set<std::string> device_local_accounts; 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (std::vector<DeviceLocalAccount>::const_iterator it = 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_list.begin(); 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it != device_local_account_list.end(); ++it) { 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_accounts.insert(it->user_id); 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (DeviceLocalAccountEntryMap::iterator it = 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.begin(); 264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it != device_local_account_entries_.end(); ) { 265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ContainsKey(device_local_accounts, it->first)) { 266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string user_id = it->first; 267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it->second.DeleteOwnedMembers(); 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_local_account_entries_.erase(it++); 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // When a device-local account whose external data reference was set is 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // removed, emit a notification that the external data reference has been 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // cleared. 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) HandleExternalDataPolicyUpdate(user_id, NULL); 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ++it; 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (std::set<std::string>::const_iterator it = device_local_accounts.begin(); 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) it != device_local_accounts.end(); ++it) { 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnPolicyUpdated(*it); 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::HandleExternalDataPolicyUpdate( 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id, 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const PolicyMap::Entry* entry) { 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!entry) { 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnExternalDataCleared(policy_, user_id); 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fetch_weak_ptrs_.erase(user_id); 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnExternalDataSet(policy_, user_id); 294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) linked_ptr<WeakPtrFactory>& weak_ptr_factory = fetch_weak_ptrs_[user_id]; 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_ptr_factory.reset(new WeakPtrFactory(this)); 297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (entry->external_data_fetcher) { 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry->external_data_fetcher->Fetch(base::Bind( 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &CloudExternalDataPolicyObserver::OnExternalDataFetched, 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_ptr_factory->GetWeakPtr(), 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) user_id)); 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CloudExternalDataPolicyObserver::OnExternalDataFetched( 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& user_id, 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<std::string> data) { 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FetchWeakPtrMap::iterator it = fetch_weak_ptrs_.find(user_id); 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(it != fetch_weak_ptrs_.end()); 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fetch_weak_ptrs_.erase(it); 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->OnExternalDataFetched(policy_, user_id, data.Pass()); 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace policy 317