Home | History | Annotate | Download | only in common
      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     NUM_LOCATIONS
     51   };
     52 
     53   // Do not change the order of entries or remove entries in this list
     54   // as this is used in UMA_HISTOGRAM_ENUMERATIONs about extensions.
     55   enum Type {
     56     TYPE_UNKNOWN = 0,
     57     TYPE_EXTENSION,
     58     TYPE_THEME,
     59     TYPE_USER_SCRIPT,
     60     TYPE_HOSTED_APP,
     61     // This is marked legacy because platform apps are preferred. For
     62     // backwards compatibility, we can't remove support for packaged apps
     63     TYPE_LEGACY_PACKAGED_APP,
     64     TYPE_PLATFORM_APP,
     65     TYPE_SHARED_MODULE
     66   };
     67 
     68   // Given two install sources, return the one which should take priority
     69   // over the other. If an extension is installed from two sources A and B,
     70   // its install source should be set to GetHigherPriorityLocation(A, B).
     71   static Location GetHigherPriorityLocation(Location loc1, Location loc2);
     72 
     73   // Whether the |location| is external or not.
     74   static inline bool IsExternalLocation(Location location) {
     75     return location == EXTERNAL_PREF ||
     76            location == EXTERNAL_REGISTRY ||
     77            location == EXTERNAL_PREF_DOWNLOAD ||
     78            location == EXTERNAL_POLICY ||
     79            location == EXTERNAL_POLICY_DOWNLOAD ||
     80            location == EXTERNAL_COMPONENT;
     81   }
     82 
     83   // Whether the |location| is unpacked (no CRX) or not.
     84   static inline bool IsUnpackedLocation(Location location) {
     85     return location == UNPACKED || location == COMMAND_LINE;
     86   }
     87 
     88   // Whether extensions with |location| are auto-updatable or not.
     89   static inline bool IsAutoUpdateableLocation(Location location) {
     90     // Only internal and external extensions can be autoupdated.
     91     return location == INTERNAL ||
     92            IsExternalLocation(location);
     93   }
     94 
     95   // Whether the |location| is a source of extensions force-installed through
     96   // policy.
     97   static inline bool IsPolicyLocation(Location location) {
     98     return location == EXTERNAL_POLICY ||
     99            location == EXTERNAL_POLICY_DOWNLOAD ||
    100            location == EXTERNAL_COMPONENT;
    101   }
    102 
    103   // Unpacked extensions start off with file access since they are a developer
    104   // feature.
    105   static inline bool ShouldAlwaysAllowFileAccess(Location location) {
    106     return IsUnpackedLocation(location);
    107   }
    108 
    109   Manifest(Location location, scoped_ptr<base::DictionaryValue> value);
    110   virtual ~Manifest();
    111 
    112   const std::string& extension_id() const { return extension_id_; }
    113   void set_extension_id(const std::string& id) { extension_id_ = id; }
    114 
    115   Location location() const { return location_; }
    116 
    117   // Returns false and |error| will be non-empty if the manifest is malformed.
    118   // |warnings| will be populated if there are keys in the manifest that cannot
    119   // be specified by the extension type.
    120   bool ValidateManifest(std::string* error,
    121                         std::vector<InstallWarning>* warnings) const;
    122 
    123   // The version of this extension's manifest. We increase the manifest
    124   // version when making breaking changes to the extension system. If the
    125   // manifest contains no explicit manifest version, this returns the current
    126   // system default.
    127   int GetManifestVersion() const;
    128 
    129   // Returns the manifest type.
    130   Type type() const { return type_; }
    131 
    132   bool is_theme() const { return type_ == TYPE_THEME; }
    133   bool is_app() const {
    134     return is_legacy_packaged_app() || is_hosted_app() || is_platform_app();
    135   }
    136   bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP; }
    137   bool is_hosted_app() const { return type_ == TYPE_HOSTED_APP; }
    138   bool is_legacy_packaged_app() const {
    139     return type_ == TYPE_LEGACY_PACKAGED_APP;
    140   }
    141   bool is_extension() const { return type_ == TYPE_EXTENSION; }
    142   bool is_shared_module() const { return type_ == TYPE_SHARED_MODULE; }
    143 
    144   // These access the wrapped manifest value, returning false when the property
    145   // does not exist or if the manifest type can't access it.
    146   bool HasKey(const std::string& key) const;
    147   bool HasPath(const std::string& path) const;
    148   bool Get(const std::string& path, const base::Value** out_value) const;
    149   bool GetBoolean(const std::string& path, bool* out_value) const;
    150   bool GetInteger(const std::string& path, int* out_value) const;
    151   bool GetString(const std::string& path, std::string* out_value) const;
    152   bool GetString(const std::string& path, string16* out_value) const;
    153   bool GetDictionary(const std::string& path,
    154                      const base::DictionaryValue** out_value) const;
    155   bool GetList(const std::string& path,
    156                const base::ListValue** out_value) const;
    157 
    158   // Returns a new Manifest equal to this one, passing ownership to
    159   // the caller.
    160   Manifest* DeepCopy() const;
    161 
    162   // Returns true if this equals the |other| manifest.
    163   bool Equals(const Manifest* other) const;
    164 
    165   // Gets the underlying DictionaryValue representing the manifest.
    166   // Note: only use this when you KNOW you don't need the validation.
    167   const base::DictionaryValue* value() const { return value_.get(); }
    168 
    169  private:
    170   // Returns true if the extension can specify the given |path|.
    171   bool CanAccessPath(const std::string& path) const;
    172   bool CanAccessKey(const std::string& key) const;
    173 
    174   // A persistent, globally unique ID. An extension's ID is used in things
    175   // like directory structures and URLs, and is expected to not change across
    176   // versions. It is generated as a SHA-256 hash of the extension's public
    177   // key, or as a hash of the path in the case of unpacked extensions.
    178   std::string extension_id_;
    179 
    180   // The location the extension was loaded from.
    181   Location location_;
    182 
    183   // The underlying dictionary representation of the manifest.
    184   scoped_ptr<base::DictionaryValue> value_;
    185 
    186   Type type_;
    187 
    188   DISALLOW_COPY_AND_ASSIGN(Manifest);
    189 };
    190 
    191 }  // namespace extensions
    192 
    193 #endif  // EXTENSIONS_COMMON_MANIFEST_H_
    194