blob: b075c0e5338d1c816cadea4ab6a5ea9cce3f7705 [file] [log] [blame]
// 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_PERMISSIONS_API_PERMISSION_H_
#define EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_H_
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/pickle.h"
#include "base/values.h"
namespace extensions {
class PermissionIDSet;
class APIPermissionInfo;
class PermissionsInfo;
// APIPermission is for handling some complex permissions. Please refer to
// extensions::SocketPermission as an example.
// There is one instance per permission per loaded extension.
class APIPermission {
public:
// The IDs of all permissions available to apps. Add as many permissions here
// as needed to generate meaningful permission messages. Add the rules for the
// messages to ChromePermissionMessageProvider.
// Do not reorder this enumeration or remove any entries. To deprecate an
// entry, prefix it with the "kDeleted_" specifier and to add a new entry, add
// it just prior to kEnumBoundary, and ensure to update the
// "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml (by
// running update_extension_permission.py).
// TODO(sashab): Move this to a more central location, and rename it to
// PermissionID.
enum ID {
// Error codes.
kInvalid = 0,
kUnknown = 1,
// Actual permission IDs. Not all of these are valid permissions on their
// own; some are just needed by various manifest permissions to represent
// their permission message rule combinations.
kAccessibilityFeaturesModify = 2,
kAccessibilityFeaturesRead = 3,
kAccessibilityPrivate = 4,
kActiveTab = 5,
kActivityLogPrivate = 6,
kAlarms = 7,
kAlphaEnabled = 8,
kAlwaysOnTopWindows = 9,
kAppView = 10,
kAudio = 11,
kAudioCapture = 12,
kDeleted_AudioModem = 13,
kAutofillPrivate = 14,
kAutomation = 15,
kAutoTestPrivate = 16,
kBackground = 17,
kBluetoothPrivate = 18,
kBookmark = 19,
kBookmarkManagerPrivate = 20,
kBrailleDisplayPrivate = 21,
kBrowser = 22,
kBrowsingData = 23,
kCast = 24,
kCastStreaming = 25,
kChromeosInfoPrivate = 26,
kClipboardRead = 27,
kClipboardWrite = 28,
kCloudPrintPrivate = 29,
kCommandLinePrivate = 30,
kCommandsAccessibility = 31,
kContentSettings = 32,
kContextMenus = 33,
kCookie = 34,
kDeleted_Copresence = 35,
kDeleted_CopresencePrivate = 36,
kCryptotokenPrivate = 37,
kDataReductionProxy = 38,
kDiagnostics = 39,
kDeleted_Dial = 40, // API removed.
kDebugger = 41,
kDeclarative = 42,
kDeclarativeContent = 43,
kDeclarativeWebRequest = 44,
kDesktopCapture = 45,
kDesktopCapturePrivate = 46,
kDeveloperPrivate = 47,
kDevtools = 48,
kDns = 49,
kDocumentScan = 50,
kDownloads = 51,
kDownloadsInternal = 52,
kDownloadsOpen = 53,
kDownloadsShelf = 54,
kDeleted_EasyUnlockPrivate = 55,
kEchoPrivate = 56,
kEmbeddedExtensionOptions = 57,
kEnterprisePlatformKeys = 58,
kEnterprisePlatformKeysPrivate = 59,
kDeleted_ExperienceSamplingPrivate = 60,
kExperimental = 61,
kExtensionView = 62,
kExternallyConnectableAllUrls = 63,
kFeedbackPrivate = 64,
kFileBrowserHandler = 65,
kFileBrowserHandlerInternal = 66,
kFileManagerPrivate = 67,
kFileSystem = 68,
kFileSystemDirectory = 69,
kFileSystemProvider = 70,
kFileSystemRequestFileSystem = 71,
kFileSystemRetainEntries = 72,
kFileSystemWrite = 73,
kDeleted_FileSystemWriteDirectory = 74,
kFirstRunPrivate = 75,
kFontSettings = 76,
kFullscreen = 77,
kDeleted_GcdPrivate = 78,
kGcm = 79,
kGeolocation = 80,
kHid = 81,
kHistory = 82,
kHomepage = 83,
kHotwordPrivate = 84,
kIdentity = 85,
kIdentityEmail = 86,
kIdentityPrivate = 87,
kIdltest = 88,
kIdle = 89,
kImeWindowEnabled = 90,
kDeleted_InlineInstallPrivate = 91,
kInput = 92,
kInputMethodPrivate = 93,
kDeleted_InterceptAllKeys = 94,
kLauncherSearchProvider = 95,
kLocation = 96,
kDeleted_LogPrivate = 97,
kManagement = 98,
kMediaGalleries = 99,
kMediaPlayerPrivate = 100,
kMediaRouterPrivate = 101,
kMetricsPrivate = 102,
kMDns = 103,
kMusicManagerPrivate = 104,
kNativeMessaging = 105,
kNetworkingConfig = 106,
kNetworkingPrivate = 107,
kDeleted_NotificationProvider = 108,
kNotifications = 109,
kOverrideEscFullscreen = 110,
kPageCapture = 111,
kPointerLock = 112,
kPlatformKeys = 113,
kDeleted_Plugin = 114,
kPower = 115,
kPreferencesPrivate = 116,
kDeleted_PrincipalsPrivate = 117,
kPrinterProvider = 118,
kPrivacy = 119,
kProcesses = 120,
kProxy = 121,
kImageWriterPrivate = 122,
kDeleted_ReadingListPrivate = 123,
kRtcPrivate = 124,
kSearchProvider = 125,
kSearchEnginesPrivate = 126,
kSerial = 127,
kSessions = 128,
kSettingsPrivate = 129,
kSignedInDevices = 130,
kSocket = 131,
kStartupPages = 132,
kStorage = 133,
kDeleted_StreamsPrivate = 134,
kSyncFileSystem = 135,
kSystemPrivate = 136,
kSystemDisplay = 137,
kSystemStorage = 138,
kTab = 139,
kTabCapture = 140,
kTabCaptureForTab = 141,
kTerminalPrivate = 142,
kTopSites = 143,
kTts = 144,
kTtsEngine = 145,
kUnlimitedStorage = 146,
kU2fDevices = 147,
kUsb = 148,
kUsbDevice = 149,
kVideoCapture = 150,
kVirtualKeyboardPrivate = 151,
kVpnProvider = 152,
kWallpaper = 153,
kWallpaperPrivate = 154,
kWebcamPrivate = 155,
kWebConnectable = 156, // for externally_connectable manifest key
kWebNavigation = 157,
kWebRequest = 158,
kWebRequestBlocking = 159,
kWebrtcAudioPrivate = 160,
kWebrtcDesktopCapturePrivate = 161,
kWebrtcLoggingPrivate = 162,
kWebstorePrivate = 163,
kWebstoreWidgetPrivate = 164,
kWebView = 165,
kWindowShape = 166,
kScreenlockPrivate = 167,
kSystemCpu = 168,
kSystemMemory = 169,
kSystemNetwork = 170,
kSystemInfoCpu = 171,
kSystemInfoMemory = 172,
kBluetooth = 173,
kBluetoothDevices = 174,
kFavicon = 175,
kFullAccess = 176,
kHostReadOnly = 177,
kHostReadWrite = 178,
kHostsAll = 179,
kHostsAllReadOnly = 180,
kMediaGalleriesAllGalleriesCopyTo = 181,
kMediaGalleriesAllGalleriesDelete = 182,
kMediaGalleriesAllGalleriesRead = 183,
kNetworkState = 184,
kOverrideBookmarksUI = 185,
kShouldWarnAllHosts = 186,
kSocketAnyHost = 187,
kSocketDomainHosts = 188,
kSocketSpecificHosts = 189,
kDeleted_UsbDeviceList = 190,
kUsbDeviceUnknownProduct = 191,
kUsbDeviceUnknownVendor = 192,
kUsersPrivate = 193,
kPasswordsPrivate = 194,
kLanguageSettingsPrivate = 195,
kEnterpriseDeviceAttributes = 196,
kCertificateProvider = 197,
kResourcesPrivate = 198,
kDisplaySource = 199,
kClipboard = 200,
kNetworkingOnc = 201,
kVirtualKeyboard = 202,
kNetworkingCastPrivate = 203,
kMediaPerceptionPrivate = 204,
kLockScreen = 205,
kNewTabPageOverride = 206,
kDeclarativeNetRequest = 207,
kLockWindowFullscreenPrivate = 208,
kWebrtcLoggingPrivateAudioDebug = 209,
kEnterpriseReportingPrivate = 210,
kCecPrivate = 211,
kSafeBrowsingPrivate = 212,
kFileSystemRequestDownloads = 213,
kSystemPowerSource = 214,
kArcAppsPrivate = 215,
kEnterpriseHardwarePlatform = 216,
// Last entry: Add new entries above and ensure to update the
// "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
// (by running update_extension_permission.py).
kEnumBoundary,
};
struct CheckParam {
};
explicit APIPermission(const APIPermissionInfo* info);
virtual ~APIPermission();
// Returns the id of this permission.
ID id() const;
// Returns the name of this permission.
const char* name() const;
// Returns the APIPermission of this permission.
const APIPermissionInfo* info() const {
return info_;
}
// The set of permissions an app/extension with this API permission has. These
// permissions are used by PermissionMessageProvider to generate meaningful
// permission messages for the app/extension.
//
// For simple API permissions, this will return a set containing only the ID
// of the permission. More complex permissions might have multiple IDs, one
// for each of the capabilities the API permission has (e.g. read, write and
// copy, in the case of the media gallery permission). Permissions that
// require parameters may also contain a parameter string (along with the
// permission's ID) which can be substituted into the permission message if a
// rule is defined to do so.
//
// Permissions with multiple values, such as host permissions, are represented
// by multiple entries in this set. Each permission in the subset has the same
// ID (e.g. kHostReadOnly) but a different parameter (e.g. google.com). These
// are grouped to form different kinds of permission messages (e.g. 'Access to
// 2 hosts') depending on the number that are in the set. The rules that
// define the grouping of related permissions with the same ID is defined in
// ChromePermissionMessageProvider.
virtual PermissionIDSet GetPermissions() const = 0;
// Returns true if the given permission is allowed.
virtual bool Check(const CheckParam* param) const = 0;
// Returns true if |rhs| is a subset of this.
virtual bool Contains(const APIPermission* rhs) const = 0;
// Returns true if |rhs| is equal to this.
virtual bool Equal(const APIPermission* rhs) const = 0;
// Parses the APIPermission from |value|. Returns false if an error happens
// and optionally set |error| if |error| is not NULL. If |value| represents
// multiple permissions, some are invalid, and |unhandled_permissions| is
// not NULL, the invalid ones are put into |unhandled_permissions| and the
// function returns true.
virtual bool FromValue(const base::Value* value,
std::string* error,
std::vector<std::string>* unhandled_permissions) = 0;
// Stores this into a new created |value|.
virtual std::unique_ptr<base::Value> ToValue() const = 0;
// Clones this.
virtual APIPermission* Clone() const = 0;
// Returns a new API permission which equals this - |rhs|.
virtual APIPermission* Diff(const APIPermission* rhs) const = 0;
// Returns a new API permission which equals the union of this and |rhs|.
virtual APIPermission* Union(const APIPermission* rhs) const = 0;
// Returns a new API permission which equals the intersect of this and |rhs|.
virtual APIPermission* Intersect(const APIPermission* rhs) const = 0;
// IPC functions
// Writes this into the given IPC message |m|.
virtual void Write(base::Pickle* m) const = 0;
// Reads from the given IPC message |m|.
virtual bool Read(const base::Pickle* m, base::PickleIterator* iter) = 0;
// Logs this permission.
virtual void Log(std::string* log) const = 0;
private:
const APIPermissionInfo* const info_;
};
// The APIPermissionInfo is an immutable class that describes a single
// named permission (API permission).
// There is one instance per permission.
class APIPermissionInfo {
public:
enum Flag {
kFlagNone = 0,
// Plugins (NPAPI) are deprecated.
// kFlagImpliesFullAccess = 1 << 0,
// Indicates if the permission implies full URL access.
kFlagImpliesFullURLAccess = 1 << 1,
// Indicates that extensions cannot specify the permission as optional.
kFlagCannotBeOptional = 1 << 3,
// Indicates that the permission is internal to the extensions
// system and cannot be specified in the "permissions" list.
kFlagInternal = 1 << 4,
// Indicates that the permission may be granted to web contents by
// extensions using the content_capabilities manifest feature.
kFlagSupportsContentCapabilities = 1 << 5,
};
typedef APIPermission* (*APIPermissionConstructor)(const APIPermissionInfo*);
typedef std::set<APIPermission::ID> IDSet;
// This exists to allow aggregate initialization, so that default values
// for flags, etc. can be omitted.
// TODO(yoz): Simplify the way initialization is done. APIPermissionInfo
// should be the simple data struct.
struct InitInfo {
APIPermission::ID id;
const char* name;
int flags;
APIPermissionInfo::APIPermissionConstructor constructor;
};
~APIPermissionInfo();
// Creates a APIPermission instance.
APIPermission* CreateAPIPermission() const;
int flags() const { return flags_; }
APIPermission::ID id() const { return id_; }
// Returns the name of this permission.
const char* name() const { return name_; }
// Returns true if this permission implies full URL access.
bool implies_full_url_access() const {
return (flags_ & kFlagImpliesFullURLAccess) != 0;
}
// Returns true if this permission can be added and removed via the
// optional permissions extension API.
bool supports_optional() const {
return (flags_ & kFlagCannotBeOptional) == 0;
}
// Returns true if this permission is internal rather than a
// "permissions" list entry.
bool is_internal() const {
return (flags_ & kFlagInternal) != 0;
}
// Returns true if this permission can be granted to web contents by an
// extension through the content_capabilities manifest feature.
bool supports_content_capabilities() const {
return (flags_ & kFlagSupportsContentCapabilities) != 0;
}
private:
// Instances should only be constructed from within a PermissionsInfo.
friend class PermissionsInfo;
// Implementations of APIPermission will want to get the permission message,
// but this class's implementation should be hidden from everyone else.
friend class APIPermission;
explicit APIPermissionInfo(const InitInfo& info);
const APIPermission::ID id_;
const char* const name_;
const int flags_;
const APIPermissionConstructor api_permission_constructor_;
};
} // namespace extensions
#endif // EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_H_