Chromium Code Reviews| Index: chrome/common/extensions/extension_permission_set.h |
| diff --git a/chrome/common/extensions/extension_permission_set.h b/chrome/common/extensions/extension_permission_set.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f78c1f210ab07298bc1d5679cd6899b4fbd41e09 |
| --- /dev/null |
| +++ b/chrome/common/extensions/extension_permission_set.h |
| @@ -0,0 +1,412 @@ |
| +// Copyright (c) 2011 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 CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ |
| +#define CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ |
| +#pragma once |
| + |
| +#include <map> |
| +#include <set> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/gtest_prod_util.h" |
| +#include "base/memory/singleton.h" |
| +#include "base/scoped_ptr.h" |
| +#include "base/string16.h" |
| +#include "chrome/common/extensions/url_pattern_set.h" |
| + |
| +class DictionaryValue; |
| +class Extension; |
| +class ExtensionPrefs; |
| +class ListValue; |
| + |
| +// When prompting the user to install or approve permissions, we display |
| +// messages describing the effects of the permissions rather than listing the |
| +// permissions themselves. Each ExtensionPermissionMessage represents one of the |
| +// messages shown to the user. |
| +class ExtensionPermissionMessage { |
| + public: |
| + // Do not reorder this enumeration. If you need to add a new enum, add it just |
| + // prior to kEnumBoundary. |
| + enum Id { |
|
Matt Perry
2011/06/21 00:43:10
nit: rename to ID
jstritar
2011/06/21 23:12:16
Done.
|
| + kUnknown, |
| + kNone, |
| + kBookmarks, |
| + kGeolocation, |
| + kBrowsingHistory, |
| + kTabs, |
| + kManagement, |
| + kDebugger, |
| + kHosts1, |
| + kHosts2, |
| + kHosts3, |
| + kHosts4OrMore, |
| + kHostsAll, |
| + kFullAccess, |
| + kClipboard, |
| + kEnumBoundary |
| + }; |
| + |
| + // Creates the corresponding permission message for a list of hosts. This is |
| + // simply a convenience method around the constructor, since the messages |
| + // change depending on what hosts are present. |
| + static ExtensionPermissionMessage CreateFromHostList( |
| + const std::vector<std::string> hosts); |
|
Matt Perry
2011/06/21 00:43:10
pass by ref: const std::vector<std::string>&
jstritar
2011/06/21 23:12:16
Done.
|
| + |
| + // Creates the corresponding permission message. |
| + ExtensionPermissionMessage(Id id, string16 message); |
|
Matt Perry
2011/06/21 00:43:10
pass string16 by const ref
jstritar
2011/06/21 23:12:16
Done.
|
| + |
|
Matt Perry
2011/06/21 00:43:10
nit: add a destructor, and define it in the .cc. (
jstritar
2011/06/21 23:12:16
Done.
|
| + // Gets the id of the permission message, which can be used in UMA |
| + // histograms. |
| + Id id() const { return id_; } |
| + |
| + // Gets a localized message describing this permission. Please note that |
| + // the message will be empty for message types TYPE_NONE and TYPE_UNKNOWN. |
| + const string16& message() const { return message_; } |
| + |
| + // Comparator to work with std::set. |
| + bool operator<(const ExtensionPermissionMessage& that) const { |
| + return id_ < that.id_; |
| + } |
| + |
| + private: |
| + Id id_; |
| + string16 message_; |
| +}; |
| + |
| +typedef std::vector<ExtensionPermissionMessage> ExtensionPermissionMessages; |
| + |
| +// The ExtensionAPIPermission is an immutable class that describes a single |
| +// named permission (API permission). |
| +class ExtensionAPIPermission { |
| + public: |
| + // Do not reorder this list. If you need to add a new enum, add it just prior |
| + // to kEnumBoundary. |
| + enum Id { |
| + // Error codes. |
| + kInvalid, |
|
Matt Perry
2011/06/21 00:43:10
nit: can you make these 2 negative?
jstritar
2011/06/21 23:12:16
Done.
|
| + kUnknown, |
| + |
| + // Default permission that every extension has implicity. |
| + kDefault, |
| + |
| + // Real permissions. |
| + kBackground, |
| + kBookmark, |
| + kClipboardRead, |
| + kClipboardWrite, |
| + kContentSettings, |
| + kContextMenus, |
| + kCookie, |
| + kChromePrivate, |
| + kChromeosInfoPrivate, |
| + kDebugger, |
| + kExperimental, |
| + kFileBrowserHandler, |
| + kFileBrowserPrivate, |
| + kGeolocation, |
| + kHistory, |
| + kIdle, |
| + kManagement, |
| + kMediaPlayerPrivate, |
| + kNotification, |
| + kProxy, |
| + kTab, |
| + kUnlimitedStorage, |
| + kWebSocketProxyPrivate, |
| + kWebstorePrivate, |
| + kDevtools, |
| + kPlugin, |
| + kEnumBoundary |
| + }; |
| + |
| + typedef std::set<Id> IdSet; |
|
Matt Perry
2011/06/21 00:43:10
IDSet
jstritar
2011/06/21 23:12:16
Done.
|
| + |
| + ~ExtensionAPIPermission(); |
| + |
| + // Returns the localized permission message associated with this api. |
| + ExtensionPermissionMessage GetMessage() const; |
| + |
| + // TODO(jstritar): Extend ExtensionAPIPermission so each knows what functions |
| + // it grants access to. (e.g., kDefault will grant access to functions that |
| + // don't require explicit permissions). |
| + // bool GrantsAccessToFunction(const std::string& function_name) const; |
| + |
| + Id id() const { return id_; } |
| + |
| + // Returns the message id associated with this permission. |
| + ExtensionPermissionMessage::Id message_id() const { |
| + return message_id_; |
| + } |
| + |
| + // Returns the name of this permission. |
| + const char* name() const { return name_; } |
| + |
| + // Returns true if this permission implies full access (e.g., native code). |
| + bool implies_full_access() const { return implies_full_access_; } |
| + |
| + // Returns true if this permission implies full URL access. |
| + bool implies_full_url_access() const { return implies_full_url_access_; } |
| + |
| + // Returns true if this permission can be accessed by hosted apps. |
| + bool is_hosted_app() const { return is_hosted_app_; } |
| + |
| + // Returns true if this permission can only be acquired by COMPONENT |
| + // extensions. |
| + bool is_component_only() const { return is_component_only_; } |
| + |
| + private: |
| + // Instances should only be constructed from within ExtensionPermissionsInfo. |
| + friend class ExtensionPermissionsInfo; |
| + |
| + explicit ExtensionAPIPermission( |
| + Id id, |
| + const char* name, |
| + bool is_hosted_app, |
| + bool is_component_only, |
| + int l10n_message_id, |
| + ExtensionPermissionMessage::Id message_id, |
| + bool implies_full_access, |
| + bool implies_full_url_access); |
| + |
| + Id id_; |
| + const char* name_; |
| + bool implies_full_access_; |
| + bool implies_full_url_access_; |
| + bool is_hosted_app_; |
| + bool is_component_only_; |
| + int l10n_message_id_; |
| + ExtensionPermissionMessage::Id message_id_; |
| + |
| +}; |
| + |
| +typedef std::set<ExtensionAPIPermission::Id> ExtensionAPIPermissionSet; |
| + |
| +// Singleton that holds the extension permission instances and provides static |
| +// methods for accessing them. |
| +class ExtensionPermissionsInfo { |
| + public: |
| + // Returns a pointer to the singleton instance. |
| + static ExtensionPermissionsInfo* GetInstance(); |
| + |
| + // Returns the permission with the given |id|, and NULL if it doesn't exist. |
| + static ExtensionAPIPermission* GetById(ExtensionAPIPermission::Id id); |
|
Matt Perry
2011/06/21 00:43:10
GetByID
Matt Perry
2011/06/21 00:43:10
Why are all the public methods static? Consumers c
jstritar
2011/06/21 23:12:16
Done.
jstritar
2011/06/21 23:12:16
I originally thought they'd be easier to access li
|
| + |
| + // Returns the permission with the given |name|, and NULL if none |
| + // exists. |
| + static ExtensionAPIPermission* GetByName(std::string name); |
| + |
| + // Returns a set containing all valid api permission ids. |
| + static ExtensionAPIPermissionSet GetAll(); |
| + |
| + // Converts all the permission names in |permission_names| to permission ids. |
| + static ExtensionAPIPermissionSet GetAllByName( |
| + const std::set<std::string>& permission_names); |
| + |
| + // Gets the total number of API permissions available to hosted apps. |
| + static size_t GetHostedAppPermissionCount(); |
| + |
| + // Gets the total number of API permissions. |
| + static size_t GetPermissionCount(); |
| + |
| + private: |
| + ~ExtensionPermissionsInfo(); |
| + ExtensionPermissionsInfo(); |
| + |
| + // Registers an |alias| for a given permission |name|. |
| + void RegisterAlias(const char* name, const char* alias); |
| + |
| + // Registers a standard extension permission. |
| + void RegisterExtensionPermission( |
| + ExtensionAPIPermission::Id id, |
| + const char* name, |
| + int l10n_message_id, |
| + ExtensionPermissionMessage::Id message_id); |
| + |
| + // Registers a permission that can be accessed by hosted apps. |
| + void RegisterHostedAppPermission( |
| + ExtensionAPIPermission::Id id, |
| + const char* name, |
| + int l10n_message_id, |
| + ExtensionPermissionMessage::Id message_id); |
| + |
| + // Registers a permission accessible only by COMPONENT extensions. |
| + void RegisterPrivatePermission( |
| + ExtensionAPIPermission::Id id, |
| + const char* name); |
| + |
| + // Registers a permission with a custom set of attributes not satisfied |
| + // by the other registration functions. |
| + void RegisterPermission( |
| + ExtensionAPIPermission::Id id, |
| + const char* name, |
| + int l10n_message_id, |
| + ExtensionPermissionMessage::Id message_id, |
| + bool is_hosted_app, |
| + bool is_component_only, |
| + bool implies_full_access, |
| + bool implies_full_url_access); |
| + |
| + // Maps permission ids to permissions. |
| + typedef std::map<ExtensionAPIPermission::Id, ExtensionAPIPermission*> IdMap; |
|
Matt Perry
2011/06/21 00:43:10
IDMap
jstritar
2011/06/21 23:12:16
Done.
|
| + |
| + // Maps names and aliases to permissions. |
| + typedef std::map<std::string, ExtensionAPIPermission*> NameMap; |
| + |
| + IdMap id_map_; |
| + NameMap name_map_; |
| + |
| + size_t hosted_app_permission_count_; |
| + size_t permission_count_; |
| + |
| + friend struct DefaultSingletonTraits<ExtensionPermissionsInfo>; |
| + DISALLOW_COPY_AND_ASSIGN(ExtensionPermissionsInfo); |
| +}; |
| + |
| +// The ExtensionPermissionSet is an immutable class that encapsulates an |
| +// extension's permissions. The class exposes set operations for combining and |
| +// manipulating the permissions. |
| +class ExtensionPermissionSet { |
| + public: |
| + // Creates an empty permission set (e.g. default permissions). |
| + ExtensionPermissionSet(); |
| + |
| + // Creates a new permission set based on the |extension| manifest data, and |
| + // the api and host permissions (|apis| and |hosts|). The effective hosts |
| + // of the newly created permission set will be infered from the |extension| |
|
Matt Perry
2011/06/21 00:43:10
inferred
jstritar
2011/06/21 23:12:16
Done.
|
| + // manifest, |apis| and |hosts|. |
| + ExtensionPermissionSet(const Extension* extension, |
| + ExtensionAPIPermissionSet apis, |
|
Matt Perry
2011/06/21 00:43:10
pass these args by const ref
jstritar
2011/06/21 23:12:16
Done.
|
| + URLPatternSet explicit_hosts); |
| + |
| + // Creates a new permission set based on the specified data. |
| + ExtensionPermissionSet(ExtensionAPIPermissionSet apis, |
| + URLPatternSet explicit_hosts, |
| + URLPatternSet scriptable_hosts); |
| + |
| + ~ExtensionPermissionSet(); |
| + |
| + // TODO(jstritar): Implement this... |
|
Matt Perry
2011/06/21 00:43:10
do you have a use case planned for these methods?
jstritar
2011/06/21 23:12:16
Yes, they'll be used by the optional permissions A
|
| + // Creates a new permission set equal to |set1| - |set2|. |
| + // Passes ownership of the new set to the caller. |
| + // static ExtensionPermissionSet* CreateDifference( |
| + // const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); |
| + |
| + // TODO(jstritar): Implement this... |
| + // Creates a new permission set equal to the intersection of |set1| and |
| + // |set2|. |
| + // Passes ownership of the new set to the caller. |
| + // static ExtensionPermissionSet* CreateIntersection( |
| + // const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); |
| + |
| + // Creates a new permission set equal to the union of |set1| and |set2|. |
| + // Passes ownership of the new set to the caller. |
| + static ExtensionPermissionSet* CreateUnion( |
| + const ExtensionPermissionSet* set1, const ExtensionPermissionSet* set2); |
| + |
| + // TODO(jstritar): Implement this... |
| + // Returns true if |set| is a subset of this. |
| + // bool Contains(const ExtensionPermissionSet* set) const; |
| + |
| + // Gets the API permissions in this set as a set of strings. |
| + std::set<std::string> GetAPIsAsStrings() const; |
| + |
| + // Gets a list of the distinct hosts for displaying to the user. |
| + // NOTE: do not use this for comparing permissions, since this disgards some |
| + // information. |
| + std::vector<std::string> GetDistinctHostsForDisplay() const; |
| + |
| + // Gets the localized permission messages that represent this set. |
| + ExtensionPermissionMessages GetPermissionMessages() const; |
| + |
| + // Gets the localized permission messages that represent this set (represented |
| + // as strings). |
| + std::vector<string16> GetWarningMessages() const; |
| + |
| + // Returns true if this is an empty set (e.g., the default permission set). |
| + bool IsDefault() const; |
|
Matt Perry
2011/06/21 00:43:10
I think IsEmpty would convey this more clearly.
jstritar
2011/06/21 23:12:16
Done.
|
| + |
| + // Returns true if the set has the specified API permission. |
| + bool HasAPIPermission(ExtensionAPIPermission::Id permission) const; |
| + |
| + // Returns true if the permissions in this set grant access to the specified |
| + // |function_name|. |
| + bool HasAccessToFunction(const std::string& function_name) const; |
| + |
| + // Returns true if this includes permission to access |origin|. |
| + bool HasExplicitAccessToOrigin(const GURL& origin) const; |
|
Matt Perry
2011/06/21 00:43:10
Looks like this actually matches an URL, not an Or
jstritar
2011/06/21 23:12:16
The host permission paths are set to "/*" within E
Matt Perry
2011/06/22 00:01:22
But this class does nothing to enforce that the ar
jstritar
2011/06/22 15:44:47
Yeah, good point. I now remove all the explicit ho
|
| + |
| + // Returns true if this permission set includes access to script |url|. |
| + bool HasScriptableAccessToURL(const GURL& url) const; |
| + |
| + // Returns true if this permission set includes effective access to all |
| + // origins. |
| + bool HasEffectiveAccessToAllHosts() const; |
| + |
| + // Returns true if this permission set includes effective access to |origin|. |
| + bool HasEffectiveAccessToHost(const GURL& origin) const; |
|
Matt Perry
2011/06/21 00:43:10
should be HasEffectAccessToURL - doesn't just matc
jstritar
2011/06/21 23:12:16
Yeah, good point, since the user script URLPattern
|
| + |
| + // Returns ture if this permission set effectively represents full access |
| + // (e.g. native code). |
| + bool HasEffectiveFullAccess() const; |
| + |
| + // Returns true if this permission set includes permissions that are |
| + // restricted to internal extensions. |
| + bool HasPrivatePermissions() const; |
| + |
| + // Returns true if |permissions| has a greater privilege level than this |
| + // permission set (e.g., this permission set has less permissions). |
| + bool HasLessPrivilegesThan(const ExtensionPermissionSet* permissions) const; |
| + |
| + const ExtensionAPIPermissionSet& apis() const { return apis_; } |
| + |
| + const URLPatternSet& effective_hosts() const { return effective_hosts_; } |
| + |
| + const URLPatternSet& explicit_hosts() const { return explicit_hosts_; } |
| + |
| + const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; } |
| + |
| + |
| + private: |
| + FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionSetTest, |
| + HasLessHostPrivilegesThan); |
| + |
| + static std::vector<std::string> GetDistinctHosts( |
| + const URLPatternList& host_patterns, bool include_rcd); |
| + |
| + // Initializes the set based on |extension|'s manifest data. |
| + void InitFromExtension(const Extension* extension); |
| + |
| + // Initializes the effective host permission based on the data in this set. |
| + void InitEffectiveHosts(); |
| + |
| + // Gets the permission messages for the API permissions. |
| + std::set<ExtensionPermissionMessage> GetSimplePermissionMessages() const; |
| + |
| + // Returns true if |permissions| has an elevated API privilege level than |
| + // this set. |
| + bool HasLessAPIPrivilegesThan( |
| + const ExtensionPermissionSet* permissions) const; |
| + |
| + // Returns true if |permissions| has more host permissions compared to this |
| + // set. |
| + bool HasLessHostPrivilegesThan( |
| + const ExtensionPermissionSet* permissions) const; |
| + |
| + // The api list is used when deciding if an extension can access certain |
| + // extension APIs and features. |
| + ExtensionAPIPermissionSet apis_; |
| + |
| + // The list of hosts that can be accessed directly from the extension. |
| + URLPatternSet explicit_hosts_; |
| + |
| + // The list of hosts that can be scripted by content scripts. |
| + URLPatternSet scriptable_hosts_; |
| + |
| + // The list of hosts this effectively grants access to. |
| + URLPatternSet effective_hosts_; |
| +}; |
| + |
| +#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_PERMISSION_SET_H_ |