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