external_policy_loader.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/external_policy_loader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check an extension ID and an URL to be syntactically correct. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckExtension(const std::string& id, const std::string& update_url) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(update_url); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Policy specifies invalid update URL for external " 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "extension: " << update_url; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Extension::IdIsValid(id)) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Policy specifies invalid ID for external " 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "extension: " << id; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExternalPolicyLoader::ExternalPolicyLoader(Profile* profile) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.Init(profile_->GetPrefs()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.Add(prefs::kExtensionInstallForceList, this); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add(this, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_PROFILE_DESTROYED, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalPolicyLoader::StartLoading() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ListValue* forcelist = 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->GetList(prefs::kExtensionInstallForceList); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* result = new DictionaryValue(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forcelist != NULL) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_desc; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ListValue::const_iterator it = forcelist->begin(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != forcelist->end(); ++it) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(*it)->GetAsString(&extension_desc)) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to read forcelist string."; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each string item of the list has the following form: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension_id_code;extension_update_url 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The update URL might also contain semicolons. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t pos = extension_desc.find(';'); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id = extension_desc.substr(0, pos); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string update_url = extension_desc.substr(pos+1); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CheckExtension(id, update_url)) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(id + ".external_update_url", update_url); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_.reset(result); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadFinished(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalPolicyLoader::Observe( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile_ == NULL) return; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == chrome::NOTIFICATION_PROFILE_DESTROYED) << 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unexpected notification type."; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (content::Source<Profile>(source).ptr() == profile_) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.RemoveAll(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.RemoveAll(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = NULL; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExternalPolicyLoader::OnPreferenceChanged(PrefServiceBase* service, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& pref_name) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service == profile_->GetPrefs()) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(std::string(prefs::kExtensionInstallForceList), pref_name); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartLoading(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 100