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