manifest.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. #ifndef EXTENSIONS_COMMON_MANIFEST_H_
  5. #define EXTENSIONS_COMMON_MANIFEST_H_
  6. #include <map>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "extensions/common/extension_id.h"
  12. #include "extensions/common/hashed_extension_id.h"
  13. #include "extensions/common/mojom/manifest.mojom-shared.h"
  14. namespace base {
  15. class DictionaryValue;
  16. class Value;
  17. } // namespace base
  18. namespace extensions {
  19. struct InstallWarning;
  20. // Wraps the DictionaryValue form of extension's manifest. Enforces access to
  21. // properties of the manifest using ManifestFeatureProvider.
  22. class Manifest final {
  23. public:
  24. // Do not change the order of entries or remove entries in this list as this
  25. // is used in ExtensionType enum in tools/metrics/histograms/enums.xml.
  26. enum Type {
  27. TYPE_UNKNOWN = 0,
  28. TYPE_EXTENSION = 1,
  29. TYPE_THEME = 2,
  30. TYPE_USER_SCRIPT = 3,
  31. TYPE_HOSTED_APP = 4,
  32. // This is marked legacy because platform apps are preferred. For
  33. // backwards compatibility, we can't remove support for packaged apps
  34. TYPE_LEGACY_PACKAGED_APP = 5,
  35. TYPE_PLATFORM_APP = 6,
  36. TYPE_SHARED_MODULE = 7,
  37. TYPE_LOGIN_SCREEN_EXTENSION = 8,
  38. TYPE_CHROMEOS_SYSTEM_EXTENSION = 9,
  39. // New enum values must go above here.
  40. NUM_LOAD_TYPES
  41. };
  42. // Given two install sources, return the one which should take priority
  43. // over the other. If an extension is installed from two sources A and B,
  44. // its install source should be set to GetHigherPriorityLocation(A, B).
  45. static mojom::ManifestLocation GetHigherPriorityLocation(
  46. mojom::ManifestLocation loc1,
  47. mojom::ManifestLocation loc2);
  48. // Whether the |location| is external or not.
  49. static inline bool IsExternalLocation(mojom::ManifestLocation location) {
  50. return location == mojom::ManifestLocation::kExternalPref ||
  51. location == mojom::ManifestLocation::kExternalRegistry ||
  52. location == mojom::ManifestLocation::kExternalPrefDownload ||
  53. location == mojom::ManifestLocation::kExternalPolicy ||
  54. location == mojom::ManifestLocation::kExternalPolicyDownload ||
  55. location == mojom::ManifestLocation::kExternalComponent;
  56. }
  57. // Whether the |location| is unpacked (no CRX) or not.
  58. static inline bool IsUnpackedLocation(mojom::ManifestLocation location) {
  59. return location == mojom::ManifestLocation::kUnpacked ||
  60. location == mojom::ManifestLocation::kCommandLine;
  61. }
  62. // Whether extensions with |location| are auto-updatable or not.
  63. static inline bool IsAutoUpdateableLocation(
  64. mojom::ManifestLocation location) {
  65. // Only internal and external extensions can be autoupdated.
  66. return location == mojom::ManifestLocation::kInternal ||
  67. IsExternalLocation(location);
  68. }
  69. // Whether the |location| is a source of extensions force-installed through
  70. // policy.
  71. static inline bool IsPolicyLocation(mojom::ManifestLocation location) {
  72. return location == mojom::ManifestLocation::kExternalPolicy ||
  73. location == mojom::ManifestLocation::kExternalPolicyDownload;
  74. }
  75. // Whether the |location| is an extension intended to be an internal part of
  76. // Chrome.
  77. static inline bool IsComponentLocation(mojom::ManifestLocation location) {
  78. return location == mojom::ManifestLocation::kComponent ||
  79. location == mojom::ManifestLocation::kExternalComponent;
  80. }
  81. static inline bool IsValidLocation(mojom::ManifestLocation location) {
  82. return location > mojom::ManifestLocation::kInvalidLocation &&
  83. location <= mojom::ManifestLocation::kMaxValue;
  84. }
  85. // Unpacked extensions start off with file access since they are a developer
  86. // feature.
  87. static inline bool ShouldAlwaysAllowFileAccess(
  88. mojom::ManifestLocation location) {
  89. return IsUnpackedLocation(location);
  90. }
  91. // Returns the Manifest::Type for the given |value|.
  92. static Type GetTypeFromManifestValue(const base::DictionaryValue& value,
  93. bool for_login_screen = false);
  94. // Returns true if an item with the given |location| should always be loaded,
  95. // even if extensions are otherwise disabled.
  96. static bool ShouldAlwaysLoadExtension(mojom::ManifestLocation location,
  97. bool is_theme);
  98. // Creates a Manifest for a login screen context. Note that this won't always
  99. // result in a Manifest of TYPE_LOGIN_SCREEN_EXTENSION, since other items
  100. // (like platform apps) may be installed in the same login screen profile.
  101. static std::unique_ptr<Manifest> CreateManifestForLoginScreen(
  102. mojom::ManifestLocation location,
  103. std::unique_ptr<base::DictionaryValue> value,
  104. ExtensionId extension_id);
  105. Manifest(mojom::ManifestLocation location,
  106. std::unique_ptr<base::DictionaryValue> value,
  107. ExtensionId extension_id);
  108. Manifest(const Manifest&) = delete;
  109. Manifest& operator=(const Manifest&) = delete;
  110. ~Manifest();
  111. const ExtensionId& extension_id() const { return extension_id_; }
  112. const HashedExtensionId& hashed_id() const { return hashed_id_; }
  113. mojom::ManifestLocation location() const { return location_; }
  114. // Returns false and |error| will be non-empty if the manifest is malformed.
  115. // |warnings| will be populated if there are keys in the manifest that cannot
  116. // be specified by the extension type.
  117. bool ValidateManifest(std::string* error,
  118. std::vector<InstallWarning>* warnings) const;
  119. // The version of this extension's manifest. We increase the manifest
  120. // version when making breaking changes to the extension system. If the
  121. // manifest contains no explicit manifest version, this returns the current
  122. // system default.
  123. int manifest_version() const { return manifest_version_; }
  124. // Returns the manifest type.
  125. Type type() const { return type_; }
  126. bool is_theme() const { return type_ == TYPE_THEME; }
  127. bool is_app() const {
  128. return is_legacy_packaged_app() || is_hosted_app() || is_platform_app();
  129. }
  130. bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP; }
  131. bool is_hosted_app() const { return type_ == TYPE_HOSTED_APP; }
  132. bool is_legacy_packaged_app() const {
  133. return type_ == TYPE_LEGACY_PACKAGED_APP;
  134. }
  135. bool is_extension() const { return type_ == TYPE_EXTENSION; }
  136. bool is_login_screen_extension() const {
  137. return type_ == TYPE_LOGIN_SCREEN_EXTENSION;
  138. }
  139. bool is_shared_module() const { return type_ == TYPE_SHARED_MODULE; }
  140. bool is_chromeos_system_extension() const {
  141. return type_ == TYPE_CHROMEOS_SYSTEM_EXTENSION;
  142. }
  143. // These access the wrapped manifest value, returning nullptr/nullopt when the
  144. // property does not exist or if the manifest type can't access it.
  145. const base::Value* FindKey(base::StringPiece path) const;
  146. const base::Value* FindPath(base::StringPiece path) const;
  147. absl::optional<bool> FindBoolPath(base::StringPiece path) const;
  148. absl::optional<int> FindIntPath(base::StringPiece path) const;
  149. const std::string* FindStringPath(base::StringPiece path) const;
  150. // Deprecated: Use the GetDictionary() overload that accepts a base::Value
  151. // output parameter instead.
  152. bool GetDictionary(const std::string& path,
  153. const base::DictionaryValue** out_value) const;
  154. bool GetDictionary(const std::string& path,
  155. const base::Value** out_value) const;
  156. bool GetList(const std::string& path, const base::Value** out_value) const;
  157. // Returns true if this equals the |other| manifest.
  158. bool EqualsForTesting(const Manifest& other) const;
  159. // Gets the underlying DictionaryValue representing the manifest.
  160. // Note: only use this when you KNOW you don't need the validation.
  161. const base::DictionaryValue* value() const { return value_.get(); }
  162. // Gets the underlying DictionaryValue representing the manifest with all
  163. // unavailable manifest keys removed.
  164. const base::DictionaryValue& available_values() const {
  165. return *available_values_;
  166. }
  167. private:
  168. Manifest(mojom::ManifestLocation location,
  169. std::unique_ptr<base::DictionaryValue> value,
  170. ExtensionId extension_id,
  171. bool for_login_screen);
  172. // A persistent, globally unique ID. An extension's ID is used in things
  173. // like directory structures and URLs, and is expected to not change across
  174. // versions. It is generated as a SHA-256 hash of the extension's public
  175. // key, or as a hash of the path in the case of unpacked extensions.
  176. const std::string extension_id_;
  177. // The hex-encoding of the SHA1 of the extension id; used to determine feature
  178. // availability.
  179. const HashedExtensionId hashed_id_;
  180. // The location the extension was loaded from.
  181. const mojom::ManifestLocation location_;
  182. // The underlying dictionary representation of the manifest.
  183. const std::unique_ptr<const base::DictionaryValue> value_;
  184. // Same as |value_| but comprises only of keys available to this manifest.
  185. std::unique_ptr<const base::DictionaryValue> available_values_;
  186. const Type type_;
  187. const int manifest_version_;
  188. };
  189. } // namespace extensions
  190. #endif // EXTENSIONS_COMMON_MANIFEST_H_