• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 #ifndef EXTENSIONS_COMMON_MANIFEST_H_
6 #define EXTENSIONS_COMMON_MANIFEST_H_
7 
8 #include <map>
9 #include <set>
10 #include <string>
11 
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string16.h"
14 #include "base/values.h"
15 
16 namespace extensions {
17 struct InstallWarning;
18 
19 // Wraps the DictionaryValue form of extension's manifest. Enforces access to
20 // properties of the manifest using ManifestFeatureProvider.
21 class Manifest {
22  public:
23   // What an extension was loaded from.
24   // NOTE: These values are stored as integers in the preferences and used
25   // in histograms so don't remove or reorder existing items.  Just append
26   // to the end.
27   enum Location {
28     INVALID_LOCATION,
29     INTERNAL,           // A crx file from the internal Extensions directory.
30     EXTERNAL_PREF,      // A crx file from an external directory (via prefs).
31     EXTERNAL_REGISTRY,  // A crx file from an external directory (via eg the
32                         // registry on Windows).
33     UNPACKED,           // From loading an unpacked extension from the
34                         // extensions settings page.
35     COMPONENT,          // An integral component of Chrome itself, which
36                         // happens to be implemented as an extension. We don't
37                         // show these in the management UI.
38     EXTERNAL_PREF_DOWNLOAD,    // A crx file from an external directory (via
39                                // prefs), installed from an update URL.
40     EXTERNAL_POLICY_DOWNLOAD,  // A crx file from an external directory (via
41                                // admin policies), installed from an update URL.
42     COMMAND_LINE,              // --load-extension.
43     EXTERNAL_POLICY,     // A crx file from an external directory (via admin
44                          // policies), cached locally and installed from the
45                          // cache.
46     EXTERNAL_COMPONENT,  // Similar to COMPONENT in that it's considered an
47                          // internal implementation detail of chrome, but
48     // installed from an update URL like the *DOWNLOAD ones.
49 
50     // New enum values must go above here.
51     NUM_LOCATIONS
52   };
53 
54   // Do not change the order of entries or remove entries in this list
55   // as this is used in UMA_HISTOGRAM_ENUMERATIONs about extensions.
56   enum Type {
57     TYPE_UNKNOWN = 0,
58     TYPE_EXTENSION,
59     TYPE_THEME,
60     TYPE_USER_SCRIPT,
61     TYPE_HOSTED_APP,
62     // This is marked legacy because platform apps are preferred. For
63     // backwards compatibility, we can't remove support for packaged apps
64     TYPE_LEGACY_PACKAGED_APP,
65     TYPE_PLATFORM_APP,
66     TYPE_SHARED_MODULE,
67 
68     // New enum values must go above here.
69     NUM_LOAD_TYPES
70   };
71 
72   // Given two install sources, return the one which should take priority
73   // over the other. If an extension is installed from two sources A and B,
74   // its install source should be set to GetHigherPriorityLocation(A, B).
75   static Location GetHigherPriorityLocation(Location loc1, Location loc2);
76 
77   // Whether the |location| is external or not.
IsExternalLocation(Location location)78   static inline bool IsExternalLocation(Location location) {
79     return location == EXTERNAL_PREF ||
80            location == EXTERNAL_REGISTRY ||
81            location == EXTERNAL_PREF_DOWNLOAD ||
82            location == EXTERNAL_POLICY ||
83            location == EXTERNAL_POLICY_DOWNLOAD ||
84            location == EXTERNAL_COMPONENT;
85   }
86 
87   // Whether the |location| is unpacked (no CRX) or not.
IsUnpackedLocation(Location location)88   static inline bool IsUnpackedLocation(Location location) {
89     return location == UNPACKED || location == COMMAND_LINE;
90   }
91 
92   // Whether extensions with |location| are auto-updatable or not.
IsAutoUpdateableLocation(Location location)93   static inline bool IsAutoUpdateableLocation(Location location) {
94     // Only internal and external extensions can be autoupdated.
95     return location == INTERNAL ||
96            IsExternalLocation(location);
97   }
98 
99   // Whether the |location| is a source of extensions force-installed through
100   // policy.
IsPolicyLocation(Location location)101   static inline bool IsPolicyLocation(Location location) {
102     return location == EXTERNAL_POLICY ||
103            location == EXTERNAL_POLICY_DOWNLOAD;
104   }
105 
106   // Whether the |location| is an extension intended to be an internal part of
107   // Chrome.
IsComponentLocation(Location location)108   static inline bool IsComponentLocation(Location location) {
109     return location == COMPONENT || location == EXTERNAL_COMPONENT;
110   }
111 
112   // Unpacked extensions start off with file access since they are a developer
113   // feature.
ShouldAlwaysAllowFileAccess(Location location)114   static inline bool ShouldAlwaysAllowFileAccess(Location location) {
115     return IsUnpackedLocation(location);
116   }
117 
118   Manifest(Location location, scoped_ptr<base::DictionaryValue> value);
119   virtual ~Manifest();
120 
extension_id()121   const std::string& extension_id() const { return extension_id_; }
set_extension_id(const std::string & id)122   void set_extension_id(const std::string& id) { extension_id_ = id; }
123 
location()124   Location location() const { return location_; }
125 
126   // Returns false and |error| will be non-empty if the manifest is malformed.
127   // |warnings| will be populated if there are keys in the manifest that cannot
128   // be specified by the extension type.
129   bool ValidateManifest(std::string* error,
130                         std::vector<InstallWarning>* warnings) const;
131 
132   // The version of this extension's manifest. We increase the manifest
133   // version when making breaking changes to the extension system. If the
134   // manifest contains no explicit manifest version, this returns the current
135   // system default.
136   int GetManifestVersion() const;
137 
138   // Returns the manifest type.
type()139   Type type() const { return type_; }
140 
is_theme()141   bool is_theme() const { return type_ == TYPE_THEME; }
is_app()142   bool is_app() const {
143     return is_legacy_packaged_app() || is_hosted_app() || is_platform_app();
144   }
is_platform_app()145   bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP; }
is_hosted_app()146   bool is_hosted_app() const { return type_ == TYPE_HOSTED_APP; }
is_legacy_packaged_app()147   bool is_legacy_packaged_app() const {
148     return type_ == TYPE_LEGACY_PACKAGED_APP;
149   }
is_extension()150   bool is_extension() const { return type_ == TYPE_EXTENSION; }
is_shared_module()151   bool is_shared_module() const { return type_ == TYPE_SHARED_MODULE; }
152 
153   // These access the wrapped manifest value, returning false when the property
154   // does not exist or if the manifest type can't access it.
155   bool HasKey(const std::string& key) const;
156   bool HasPath(const std::string& path) const;
157   bool Get(const std::string& path, const base::Value** out_value) const;
158   bool GetBoolean(const std::string& path, bool* out_value) const;
159   bool GetInteger(const std::string& path, int* out_value) const;
160   bool GetString(const std::string& path, std::string* out_value) const;
161   bool GetString(const std::string& path, base::string16* out_value) const;
162   bool GetDictionary(const std::string& path,
163                      const base::DictionaryValue** out_value) const;
164   bool GetList(const std::string& path,
165                const base::ListValue** out_value) const;
166 
167   // Returns a new Manifest equal to this one, passing ownership to
168   // the caller.
169   Manifest* DeepCopy() const;
170 
171   // Returns true if this equals the |other| manifest.
172   bool Equals(const Manifest* other) const;
173 
174   // Gets the underlying DictionaryValue representing the manifest.
175   // Note: only use this when you KNOW you don't need the validation.
value()176   const base::DictionaryValue* value() const { return value_.get(); }
177 
178  private:
179   // Returns true if the extension can specify the given |path|.
180   bool CanAccessPath(const std::string& path) const;
181   bool CanAccessKey(const std::string& key) const;
182 
183   // A persistent, globally unique ID. An extension's ID is used in things
184   // like directory structures and URLs, and is expected to not change across
185   // versions. It is generated as a SHA-256 hash of the extension's public
186   // key, or as a hash of the path in the case of unpacked extensions.
187   std::string extension_id_;
188 
189   // The location the extension was loaded from.
190   Location location_;
191 
192   // The underlying dictionary representation of the manifest.
193   scoped_ptr<base::DictionaryValue> value_;
194 
195   Type type_;
196 
197   DISALLOW_COPY_AND_ASSIGN(Manifest);
198 };
199 
200 }  // namespace extensions
201 
202 #endif  // EXTENSIONS_COMMON_MANIFEST_H_
203