| 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 // Creates a new permission set based on the specified data. | |
| 313 ExtensionPermissionSet(const ExtensionAPIPermissionSet& apis, | |
| 314 const URLPatternSet& explicit_hosts, | |
| 315 const URLPatternSet& scriptable_hosts); | |
| 316 | |
| 317 // Creates a new permission set that has oauth scopes in it. | |
| 318 ExtensionPermissionSet(const ExtensionAPIPermissionSet& apis, | |
| 319 const URLPatternSet& explicit_hosts, | |
| 320 const URLPatternSet& scriptable_hosts, | |
| 321 const ExtensionOAuth2Scopes& scopes); | |
| 322 | |
| 323 // Creates a new permission set containing only oauth scopes. | |
| 324 explicit ExtensionPermissionSet(const ExtensionOAuth2Scopes& scopes); | |
| 325 | |
| 326 // Creates a new permission set equal to |set1| - |set2|, passing ownership of | |
| 327 // the new set to the caller. | |
| 328 static ExtensionPermissionSet* CreateDifference( | |
| 329 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
| 330 | |
| 331 // Creates a new permission set equal to the intersection of |set1| and | |
| 332 // |set2|, passing ownership of the new set to the caller. | |
| 333 static ExtensionPermissionSet* CreateIntersection( | |
| 334 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
| 335 | |
| 336 // Creates a new permission set equal to the union of |set1| and |set2|. | |
| 337 // Passes ownership of the new set to the caller. | |
| 338 static ExtensionPermissionSet* CreateUnion( | |
| 339 const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); | |
| 340 | |
| 341 bool operator==(const ExtensionPermissionSet& rhs) const; | |
| 342 | |
| 343 // Returns true if |set| is a subset of this. | |
| 344 bool Contains(const ExtensionPermissionSet& set) const; | |
| 345 | |
| 346 // Gets the API permissions in this set as a set of strings. | |
| 347 std::set<std::string> GetAPIsAsStrings() const; | |
| 348 | |
| 349 // Gets the API permissions in this set, plus any that have implicit access | |
| 350 // (such as APIs that require no permissions, or APIs with functions that | |
| 351 // require no permissions). | |
| 352 // TODO(kalman): return scoped_ptr to avoid copying. | |
| 353 std::set<std::string> GetAPIsWithAnyAccessAsStrings() const; | |
| 354 | |
| 355 // Returns whether this namespace has any functions which the extension has | |
| 356 // permission to use. For example, even though the extension may not have | |
| 357 // the "tabs" permission, "tabs.create" requires no permissions so | |
| 358 // HasAnyAPIPermission("tabs") will return true. | |
| 359 bool HasAnyAccessToAPI(const std::string& api_name) const; | |
| 360 | |
| 361 // Gets a list of the distinct hosts for displaying to the user. | |
| 362 // NOTE: do not use this for comparing permissions, since this disgards some | |
| 363 // information. | |
| 364 std::set<std::string> GetDistinctHostsForDisplay() const; | |
| 365 | |
| 366 // Gets the localized permission messages that represent this set. | |
| 367 ExtensionPermissionMessages GetPermissionMessages() const; | |
| 368 | |
| 369 // Gets the localized permission messages that represent this set (represented | |
| 370 // as strings). | |
| 371 std::vector<string16> GetWarningMessages() const; | |
| 372 | |
| 373 // Returns true if this is an empty set (e.g., the default permission set). | |
| 374 bool IsEmpty() const; | |
| 375 | |
| 376 // Returns true if the set has the specified API permission. | |
| 377 bool HasAPIPermission(ExtensionAPIPermission::ID permission) const; | |
| 378 | |
| 379 // Returns true if the permissions in this set grant access to the specified | |
| 380 // |function_name|. | |
| 381 bool HasAccessToFunction(const std::string& function_name) const; | |
| 382 | |
| 383 // Returns true if this includes permission to access |origin|. | |
| 384 bool HasExplicitAccessToOrigin(const GURL& origin) const; | |
| 385 | |
| 386 // Returns true if this permission set includes access to script |url|. | |
| 387 bool HasScriptableAccessToURL(const GURL& url) const; | |
| 388 | |
| 389 // Returns true if this permission set includes effective access to all | |
| 390 // origins. | |
| 391 bool HasEffectiveAccessToAllHosts() const; | |
| 392 | |
| 393 // Returns true if this permission set includes effective access to |url|. | |
| 394 bool HasEffectiveAccessToURL(const GURL& url) const; | |
| 395 | |
| 396 // Returns ture if this permission set effectively represents full access | |
| 397 // (e.g. native code). | |
| 398 bool HasEffectiveFullAccess() const; | |
| 399 | |
| 400 // Returns true if |permissions| has a greater privilege level than this | |
| 401 // permission set (e.g., this permission set has less permissions). | |
| 402 bool HasLessPrivilegesThan(const ExtensionPermissionSet* permissions) const; | |
| 403 | |
| 404 const ExtensionAPIPermissionSet& apis() const { return apis_; } | |
| 405 | |
| 406 const URLPatternSet& effective_hosts() const { return effective_hosts_; } | |
| 407 | |
| 408 const URLPatternSet& explicit_hosts() const { return explicit_hosts_; } | |
| 409 | |
| 410 const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; } | |
| 411 | |
| 412 const ExtensionOAuth2Scopes& scopes() const { return scopes_; } | |
| 413 | |
| 414 private: | |
| 415 FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionsTest, | |
| 416 HasLessHostPrivilegesThan); | |
| 417 FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionsTest, | |
| 418 GetWarningMessages_AudioVideo); | |
| 419 friend class base::RefCountedThreadSafe<ExtensionPermissionSet>; | |
| 420 | |
| 421 ~ExtensionPermissionSet(); | |
| 422 | |
| 423 static std::set<std::string> GetDistinctHosts( | |
| 424 const URLPatternSet& host_patterns, | |
| 425 bool include_rcd, | |
| 426 bool exclude_file_scheme); | |
| 427 | |
| 428 // Initializes the set based on |extension|'s manifest data. | |
| 429 void InitImplicitExtensionPermissions(const extensions::Extension* extension); | |
| 430 | |
| 431 // Initializes the effective host permission based on the data in this set. | |
| 432 void InitEffectiveHosts(); | |
| 433 | |
| 434 // Gets the permission messages for the API permissions. | |
| 435 std::set<ExtensionPermissionMessage> GetSimplePermissionMessages() const; | |
| 436 | |
| 437 // Returns true if |permissions| has an elevated API privilege level than | |
| 438 // this set. | |
| 439 bool HasLessAPIPrivilegesThan( | |
| 440 const ExtensionPermissionSet* permissions) const; | |
| 441 | |
| 442 // Returns true if |permissions| has more host permissions compared to this | |
| 443 // set. | |
| 444 bool HasLessHostPrivilegesThan( | |
| 445 const ExtensionPermissionSet* permissions) const; | |
| 446 | |
| 447 // Returns true if |permissions| has more oauth2 scopes compared to this set. | |
| 448 bool HasLessScopesThan(const ExtensionPermissionSet* permissions) const; | |
| 449 | |
| 450 // The api list is used when deciding if an extension can access certain | |
| 451 // extension APIs and features. | |
| 452 ExtensionAPIPermissionSet apis_; | |
| 453 | |
| 454 // The list of hosts that can be accessed directly from the extension. | |
| 455 // TODO(jstritar): Rename to "hosts_"? | |
| 456 URLPatternSet explicit_hosts_; | |
| 457 | |
| 458 // The list of hosts that can be scripted by content scripts. | |
| 459 // TODO(jstritar): Rename to "user_script_hosts_"? | |
| 460 URLPatternSet scriptable_hosts_; | |
| 461 | |
| 462 // The list of hosts this effectively grants access to. | |
| 463 URLPatternSet effective_hosts_; | |
| 464 | |
| 465 // A set of oauth2 scopes that are used by the identity API to create OAuth2 | |
| 466 // tokens for accessing the Google Account of the signed-in sync account. | |
| 467 ExtensionOAuth2Scopes scopes_; | |
| 468 }; | |
| 469 | |
| 470 #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ | |
| OLD | NEW |