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