• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/extensions/external_policy_extension_loader.h"
6 
7 #include "base/logging.h"
8 #include "base/values.h"
9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/extensions/extension.h"
12 #include "chrome/common/pref_names.h"
13 #include "content/browser/browser_thread.h"
14 #include "content/common/notification_service.h"
15 #include "content/common/notification_type.h"
16 #include "googleurl/src/gurl.h"
17 
18 namespace {
19 
20 // Check an extension ID and an URL to be syntactically correct.
CheckExtension(const std::string & id,const std::string & update_url)21 bool CheckExtension(const std::string& id, const std::string& update_url) {
22   GURL url(update_url);
23   if (!url.is_valid()) {
24     LOG(WARNING) << "Policy specifies invalid update URL for external "
25                  << "extension: " << update_url;
26     return false;
27   }
28   if (!Extension::IdIsValid(id)) {
29     LOG(WARNING) << "Policy specifies invalid ID for external "
30                  << "extension: " << id;
31     return false;
32   }
33   return true;
34 }
35 
36 }  // namespace
37 
ExternalPolicyExtensionLoader(Profile * profile)38 ExternalPolicyExtensionLoader::ExternalPolicyExtensionLoader(
39     Profile* profile)
40     : profile_(profile) {
41   pref_change_registrar_.Init(profile_->GetPrefs());
42   pref_change_registrar_.Add(prefs::kExtensionInstallForceList, this);
43   notification_registrar_.Add(this,
44                               NotificationType::PROFILE_DESTROYED,
45                               Source<Profile>(profile_));
46 }
47 
StartLoading()48 void ExternalPolicyExtensionLoader::StartLoading() {
49   const ListValue* forcelist =
50       profile_->GetPrefs()->GetList(prefs::kExtensionInstallForceList);
51   DictionaryValue* result = new DictionaryValue();
52   if (forcelist != NULL) {
53     std::string extension_desc;
54     for (ListValue::const_iterator it = forcelist->begin();
55          it != forcelist->end(); ++it) {
56       if (!(*it)->GetAsString(&extension_desc)) {
57         LOG(WARNING) << "Failed to read forcelist string.";
58       } else {
59         // Each string item of the list has the following form:
60         // extension_id_code;extension_update_url
61         // The update URL might also contain semicolons.
62         size_t pos = extension_desc.find(';');
63         std::string id = extension_desc.substr(0, pos);
64         std::string update_url = extension_desc.substr(pos+1);
65         if (CheckExtension(id, update_url)) {
66           result->SetString(id + ".external_update_url", update_url);
67         }
68       }
69     }
70   }
71   prefs_.reset(result);
72   LoadFinished();
73 }
74 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)75 void ExternalPolicyExtensionLoader::Observe(
76     NotificationType type,
77     const NotificationSource& source,
78     const NotificationDetails& details) {
79   if (profile_ == NULL) return;
80   switch (type.value) {
81     case NotificationType::PREF_CHANGED: {
82       if (Source<PrefService>(source).ptr() == profile_->GetPrefs()) {
83         std::string* pref_name = Details<std::string>(details).ptr();
84         if (*pref_name == prefs::kExtensionInstallForceList) {
85           StartLoading();
86         } else {
87           NOTREACHED() << "Unexpected preference name.";
88         }
89       }
90       break;
91     }
92     case NotificationType::PROFILE_DESTROYED: {
93       if (Source<Profile>(source).ptr() == profile_) {
94         notification_registrar_.RemoveAll();
95         pref_change_registrar_.RemoveAll();
96         profile_ = NULL;
97       }
98       break;
99     }
100     default:
101       NOTREACHED() << "Unexpected notification type.";
102   }
103 }
104