OLD | NEW |
| (Empty) |
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_EXTENSION_PERMISSION_SET_H_ | |
6 #define CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ | |
7 #pragma once | |
8 | |
9 #include <map> | |
10 #include <set> | |
11 #include <string> | |
12 #include <vector> | |
13 | |
14 #include "base/gtest_prod_util.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/memory/singleton.h" | |
17 #include "base/string16.h" | |
18 #include "chrome/common/extensions/url_pattern_set.h" | |
19 | |
20 // TODO(jstritar): Move each class to its own file in extensions/permissions. | |
21 | |
22 class ExtensionPermissionsInfo; | |
23 | |
24 namespace extensions { | |
25 class Extension; | |
26 } | |
27 | |
28 // When prompting the user to install or approve permissions, we display | |
29 // messages describing the effects of the permissions rather than listing the | |
30 // permissions themselves. Each ExtensionPermissionMessage represents one of the | |
31 // messages shown to the user. | |
32 class ExtensionPermissionMessage { | |
33 public: | |
34 // Do not reorder this enumeration. If you need to add a new enum, add it just | |
35 // prior to kEnumBoundary. | |
36 enum ID { | |
37 kUnknown, | |
38 kNone, | |
39 kBookmarks, | |
40 kGeolocation, | |
41 kBrowsingHistory, | |
42 kTabs, | |
43 kManagement, | |
44 kDebugger, | |
45 kHosts1, | |
46 kHosts2, | |
47 kHosts3, | |
48 kHosts4OrMore, | |
49 kHostsAll, | |
50 kFullAccess, | |
51 kClipboard, | |
52 kTtsEngine, | |
53 kContentSettings, | |
54 kAllPageContent, | |
55 kPrivacy, | |
56 kManagedMode, | |
57 kInput, | |
58 kAudioCapture, | |
59 kVideoCapture, | |
60 kDownloads, | |
61 kEnumBoundary | |
62 }; | |
63 | |
64 // Creates the corresponding permission message for a list of hosts. This is | |
65 // simply a convenience method around the constructor, since the messages | |
66 // change depending on what hosts are present. | |
67 static ExtensionPermissionMessage CreateFromHostList( | |
68 const std::set<std::string>& hosts); | |
69 | |
70 // Creates the corresponding permission message. | |
71 ExtensionPermissionMessage(ID id, const string16& message); | |
72 ~ExtensionPermissionMessage(); | |
73 | |
74 // Gets the id of the permission message, which can be used in UMA | |
75 // histograms. | |
76 ID id() const { return id_; } | |
77 | |
78 // Gets a localized message describing this permission. Please note that | |
79 // the message will be empty for message types TYPE_NONE and TYPE_UNKNOWN. | |
80 const string16& message() const { return message_; } | |
81 | |
82 // Comparator to work with std::set. | |
83 bool operator<(const ExtensionPermissionMessage& that) const { | |
84 return id_ < that.id_; | |
85 } | |
86 | |
87 private: | |
88 ID id_; | |
89 string16 message_; | |
90 }; | |
91 | |
92 typedef std::vector<ExtensionPermissionMessage> ExtensionPermissionMessages; | |
93 | |
94 // The ExtensionAPIPermission is an immutable class that describes a single | |
95 // named permission (API permission). | |
96 class ExtensionAPIPermission { | |
97 public: | |
98 enum ID { | |
99 // Error codes. | |
100 kInvalid = -2, | |
101 kUnknown = -1, | |
102 | |
103 // Real permissions. | |
104 kActiveTab, | |
105 kAlarms, | |
106 kAppNotifications, | |
107 kAudioCapture, | |
108 kBackground, | |
109 kBookmark, | |
110 kBrowsingData, | |
111 kChromeAuthPrivate, | |
112 kChromeosInfoPrivate, | |
113 kClipboardRead, | |
114 kClipboardWrite, | |
115 kContentSettings, | |
116 kContextMenus, | |
117 kCookie, | |
118 kDebugger, | |
119 kDeclarative, | |
120 kDeclarativeWebRequest, | |
121 kDevtools, | |
122 kEchoPrivate, | |
123 kDownloads, | |
124 kExperimental, | |
125 kFileBrowserHandler, | |
126 kFileBrowserHandlerInternal, | |
127 kFileBrowserPrivate, | |
128 kFileSystem, | |
129 kGeolocation, | |
130 kHistory, | |
131 kIdle, | |
132 kInput, | |
133 kInputMethodPrivate, | |
134 kKeybinding, | |
135 kManagedModePrivate, | |
136 kManagement, | |
137 kMediaPlayerPrivate, | |
138 kMetricsPrivate, | |
139 kNotification, | |
140 kPageCapture, | |
141 kPlugin, | |
142 kPrivacy, | |
143 kProxy, | |
144 kSocket, | |
145 kStorage, | |
146 kSystemPrivate, | |
147 kTab, | |
148 kTerminalPrivate, | |
149 kTopSites, | |
150 kTts, | |
151 kTtsEngine, | |
152 kUnlimitedStorage, | |
153 kUsb, | |
154 kVideoCapture, | |
155 kWebNavigation, | |
156 kWebRequest, | |
157 kWebRequestBlocking, | |
158 kWebRequestInternal, | |
159 kWebSocketProxyPrivate, | |
160 kWebstorePrivate, | |
161 kEnumBoundary | |
162 }; | |
163 | |
164 enum Flag { | |
165 kFlagNone = 0, | |
166 | |
167 // Indicates if the permission implies full access (native code). | |
168 kFlagImpliesFullAccess = 1 << 0, | |
169 | |
170 // Indicates if the permission implies full URL access. | |
171 kFlagImpliesFullURLAccess = 1 << 1, | |
172 | |
173 // Indicates that extensions cannot specify the permission as optional. | |
174 kFlagCannotBeOptional = 1 << 3 | |
175 }; | |
176 | |
177 typedef std::set<ID> IDSet; | |
178 | |
179 ~ExtensionAPIPermission(); | |
180 | |
181 // Returns the localized permission message associated with this api. | |
182 ExtensionPermissionMessage GetMessage() const; | |
183 | |
184 int flags() const { return flags_; } | |
185 | |
186 ID id() const { return id_; } | |
187 | |
188 // Returns the message id associated with this permission. | |
189 ExtensionPermissionMessage::ID message_id() const { | |
190 return message_id_; | |
191 } | |
192 | |
193 // Returns the name of this permission. | |
194 const char* name() const { return name_; } | |
195 | |
196 // Returns true if this permission implies full access (e.g., native code). | |
197 bool implies_full_access() const { | |
198 return (flags_ & kFlagImpliesFullAccess) != 0; | |
199 } | |
200 | |
201 // Returns true if this permission implies full URL access. | |
202 bool implies_full_url_access() const { | |
203 return (flags_ & kFlagImpliesFullURLAccess) != 0; | |
204 } | |
205 | |
206 // Returns true if this permission can be added and removed via the | |
207 // optional permissions extension API. | |
208 bool supports_optional() const { | |
209 return (flags_ & kFlagCannotBeOptional) == 0; | |
210 } | |
211 | |
212 private: | |
213 // Instances should only be constructed from within ExtensionPermissionsInfo. | |
214 friend class ExtensionPermissionsInfo; | |
215 | |
216 explicit ExtensionAPIPermission( | |
217 ID id, | |
218 const char* name, | |
219 int l10n_message_id, | |
220 ExtensionPermissionMessage::ID message_id, | |
221 int flags); | |
222 | |
223 // Register ALL the permissions! | |
224 static void RegisterAllPermissions(ExtensionPermissionsInfo* info); | |
225 | |
226 ID id_; | |
227 const char* name_; | |
228 int flags_; | |
229 int l10n_message_id_; | |
230 ExtensionPermissionMessage::ID message_id_; | |
231 }; | |
232 | |
233 typedef std::set<ExtensionAPIPermission::ID> ExtensionAPIPermissionSet; | |
234 | |
235 // Singleton that holds the extension permission instances and provides static | |
236 // methods for accessing them. | |
237 class ExtensionPermissionsInfo { | |
238 public: | |
239 // Returns a pointer to the singleton instance. | |
240 static ExtensionPermissionsInfo* GetInstance(); | |
241 | |
242 // Returns the permission with the given |id|, and NULL if it doesn't exist. | |
243 ExtensionAPIPermission* GetByID(ExtensionAPIPermission::ID id); | |
244 | |
245 // Returns the permission with the given |name|, and NULL if none | |
246 // exists. | |
247 ExtensionAPIPermission* GetByName(const std::string& name); | |
248 | |
249 // Returns a set containing all valid api permission ids. | |
250 ExtensionAPIPermissionSet GetAll(); | |
251 | |
252 // Converts all the permission names in |permission_names| to permission ids. | |
253 ExtensionAPIPermissionSet GetAllByName( | |
254 const std::set<std::string>& permission_names); | |
255 | |
256 // Gets the total number of API permissions. | |
257 size_t get_permission_count() { return permission_count_; } | |
258 | |
259 private: | |
260 friend class ExtensionAPIPermission; | |
261 | |
262 ~ExtensionPermissionsInfo(); | |
263 ExtensionPermissionsInfo(); | |
264 | |
265 // Registers an |alias| for a given permission |name|. | |
266 void RegisterAlias(const char* name, const char* alias); | |
267 | |
268 // Registers a permission with the specified attributes and flags. | |
269 ExtensionAPIPermission* RegisterPermission( | |
270 ExtensionAPIPermission::ID id, | |
271 const char* name, | |
272 int l10n_message_id, | |
273 ExtensionPermissionMessage::ID message_id, | |
274 int flags); | |
275 | |
276 // Maps permission ids to permissions. | |
277 typedef std::map<ExtensionAPIPermission::ID, ExtensionAPIPermission*> IDMap; | |
278 | |
279 // Maps names and aliases to permissions. | |
280 typedef std::map<std::string, ExtensionAPIPermission*> NameMap; | |
281 | |
282 IDMap id_map_; | |
283 NameMap name_map_; | |
284 | |
285 size_t hosted_app_permission_count_; | |
286 size_t permission_count_; | |
287 | |
288 friend struct DefaultSingletonTraits<ExtensionPermissionsInfo>; | |
289 DISALLOW_COPY_AND_ASSIGN(ExtensionPermissionsInfo); | |
290 }; | |
291 | |
292 typedef std::set<std::string> ExtensionOAuth2Scopes; | |
293 | |
294 // The ExtensionPermissionSet is an immutable class that encapsulates an | |
295 // extension's permissions. The class exposes set operations for combining and | |
296 // manipulating the permissions. | |
297 class ExtensionPermissionSet | |
298 : public base::RefCountedThreadSafe<ExtensionPermissionSet> { | |
299 public: | |
300 // Creates an empty permission set (e.g. default permissions). | |
301 ExtensionPermissionSet(); | |
302 | |
303 // Creates a new permission set based on the |extension| manifest data, and | |
304 // the api and host permissions (|apis| and |hosts|). The effective hosts | |
305 // of the newly created permission set will be inferred from the |extension| | |
306 // manifest, |apis| and |hosts|. | |
307 ExtensionPermissionSet(const extensions::Extension* extension, | |
308 const ExtensionAPIPermissionSet& apis, | |
309 const URLPatternSet& explicit_hosts, | |
310 const ExtensionOAuth2Scopes& scopes); | |
311 | |
312 | |
313 // Creates a new permission set based on the specified data. | |
314 ExtensionPermissionSet(const ExtensionAPIPermissionSet& apis, | |
315 const URLPatternSet& explicit_hosts, | |
316 const URLPatternSet& scriptable_hosts); | |
317 | |
318 // Creates a new permission set that has oauth scopes in it. | |
319 ExtensionPermissionSet(const ExtensionAPIPermissionSet& apis, | |
320 const URLPatternSet& explicit_hosts, | |
321 const URLPatternSet& scriptable_hosts, | |
322 const ExtensionOAuth2Scopes& scopes); | |
323 | |
324 // Creates a new permission set containing only oauth scopes. | |
325 explicit ExtensionPermissionSet(const ExtensionOAuth2Scopes& scopes); | |
326 | |
327 // Creates a new permission set equal to |set1| - |set2|, passing ownership of | |
328 // the new set to the caller. | |
329 static ExtensionPermissionSet* CreateDifference( | |
330 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
331 | |
332 // Creates a new permission set equal to the intersection of |set1| and | |
333 // |set2|, passing ownership of the new set to the caller. | |
334 static ExtensionPermissionSet* CreateIntersection( | |
335 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
336 | |
337 // Creates a new permission set equal to the union of |set1| and |set2|. | |
338 // Passes ownership of the new set to the caller. | |
339 static ExtensionPermissionSet* CreateUnion( | |
340 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
341 | |
342 bool operator==(const ExtensionPermissionSet& rhs) const; | |
343 | |
344 // Returns true if |set| is a subset of this. | |
345 bool Contains(const ExtensionPermissionSet& set) const; | |
346 | |
347 // Gets the API permissions in this set as a set of strings. | |
348 std::set<std::string> GetAPIsAsStrings() const; | |
349 | |
350 // Gets the API permissions in this set, plus any that have implicit access | |
351 // (such as APIs that require no permissions, or APIs with functions that | |
352 // require no permissions). | |
353 // TODO(kalman): return scoped_ptr to avoid copying. | |
354 std::set<std::string> GetAPIsWithAnyAccessAsStrings() const; | |
355 | |
356 // Returns whether this namespace has any functions which the extension has | |
357 // permission to use. For example, even though the extension may not have | |
358 // the "tabs" permission, "tabs.create" requires no permissions so | |
359 // HasAnyAPIPermission("tabs") will return true. | |
360 bool HasAnyAccessToAPI(const std::string& api_name) const; | |
361 | |
362 // Gets a list of the distinct hosts for displaying to the user. | |
363 // NOTE: do not use this for comparing permissions, since this disgards some | |
364 // information. | |
365 std::set<std::string> GetDistinctHostsForDisplay() const; | |
366 | |
367 // Gets the localized permission messages that represent this set. | |
368 ExtensionPermissionMessages GetPermissionMessages() const; | |
369 | |
370 // Gets the localized permission messages that represent this set (represented | |
371 // as strings). | |
372 std::vector<string16> GetWarningMessages() const; | |
373 | |
374 // Returns true if this is an empty set (e.g., the default permission set). | |
375 bool IsEmpty() const; | |
376 | |
377 // Returns true if the set has the specified API permission. | |
378 bool HasAPIPermission(ExtensionAPIPermission::ID permission) const; | |
379 | |
380 // Returns true if the permissions in this set grant access to the specified | |
381 // |function_name|. | |
382 bool HasAccessToFunction(const std::string& function_name) const; | |
383 | |
384 // Returns true if this includes permission to access |origin|. | |
385 bool HasExplicitAccessToOrigin(const GURL& origin) const; | |
386 | |
387 // Returns true if this permission set includes access to script |url|. | |
388 bool HasScriptableAccessToURL(const GURL& url) const; | |
389 | |
390 // Returns true if this permission set includes effective access to all | |
391 // origins. | |
392 bool HasEffectiveAccessToAllHosts() const; | |
393 | |
394 // Returns true if this permission set includes effective access to |url|. | |
395 bool HasEffectiveAccessToURL(const GURL& url) const; | |
396 | |
397 // Returns ture if this permission set effectively represents full access | |
398 // (e.g. native code). | |
399 bool HasEffectiveFullAccess() const; | |
400 | |
401 // Returns true if |permissions| has a greater privilege level than this | |
402 // permission set (e.g., this permission set has less permissions). | |
403 bool HasLessPrivilegesThan(const ExtensionPermissionSet* permissions) const; | |
404 | |
405 const ExtensionAPIPermissionSet& apis() const { return apis_; } | |
406 | |
407 const URLPatternSet& effective_hosts() const { return effective_hosts_; } | |
408 | |
409 const URLPatternSet& explicit_hosts() const { return explicit_hosts_; } | |
410 | |
411 const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; } | |
412 | |
413 const ExtensionOAuth2Scopes& scopes() const { return scopes_; } | |
414 | |
415 private: | |
416 FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionsTest, | |
417 HasLessHostPrivilegesThan); | |
418 FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionsTest, | |
419 GetWarningMessages_AudioVideo); | |
420 friend class base::RefCountedThreadSafe<ExtensionPermissionSet>; | |
421 | |
422 ~ExtensionPermissionSet(); | |
423 | |
424 static std::set<std::string> GetDistinctHosts( | |
425 const URLPatternSet& host_patterns, | |
426 bool include_rcd, | |
427 bool exclude_file_scheme); | |
428 | |
429 // Initializes the set based on |extension|'s manifest data. | |
430 void InitImplicitExtensionPermissions(const extensions::Extension* extension); | |
431 | |
432 // Initializes the effective host permission based on the data in this set. | |
433 void InitEffectiveHosts(); | |
434 | |
435 // Gets the permission messages for the API permissions. | |
436 std::set<ExtensionPermissionMessage> GetSimplePermissionMessages() const; | |
437 | |
438 // Returns true if |permissions| has an elevated API privilege level than | |
439 // this set. | |
440 bool HasLessAPIPrivilegesThan( | |
441 const ExtensionPermissionSet* permissions) const; | |
442 | |
443 // Returns true if |permissions| has more host permissions compared to this | |
444 // set. | |
445 bool HasLessHostPrivilegesThan( | |
446 const ExtensionPermissionSet* permissions) const; | |
447 | |
448 // Returns true if |permissions| has more oauth2 scopes compared to this set. | |
449 bool HasLessScopesThan(const ExtensionPermissionSet* permissions) const; | |
450 | |
451 // The api list is used when deciding if an extension can access certain | |
452 // extension APIs and features. | |
453 ExtensionAPIPermissionSet apis_; | |
454 | |
455 // The list of hosts that can be accessed directly from the extension. | |
456 // TODO(jstritar): Rename to "hosts_"? | |
457 URLPatternSet explicit_hosts_; | |
458 | |
459 // The list of hosts that can be scripted by content scripts. | |
460 // TODO(jstritar): Rename to "user_script_hosts_"? | |
461 URLPatternSet scriptable_hosts_; | |
462 | |
463 // The list of hosts this effectively grants access to. | |
464 URLPatternSet effective_hosts_; | |
465 | |
466 // A set of oauth2 scopes that are used by the identity API to create OAuth2 | |
467 // tokens for accessing the Google Account of the signed-in sync account. | |
468 ExtensionOAuth2Scopes scopes_; | |
469 }; | |
470 | |
471 #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ | |
OLD | NEW |