1// Copyright 2013 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 EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_H_
6#define EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_H_
7
8#include <memory>
9#include <set>
10#include <string>
11#include <vector>
12
13#include "base/callback.h"
14#include "base/pickle.h"
15#include "base/values.h"
16
17namespace extensions {
18
19class PermissionIDSet;
20class APIPermissionInfo;
21class PermissionsInfo;
22
23// APIPermission is for handling some complex permissions. Please refer to
24// extensions::SocketPermission as an example.
25// There is one instance per permission per loaded extension.
26class APIPermission {
27 public:
28 // The IDs of all permissions available to apps. Add as many permissions here
29 // as needed to generate meaningful permission messages. Add the rules for the
30 // messages to ChromePermissionMessageProvider.
31 // Do not reorder this enumeration or remove any entries. To deprecate an
32 // entry, prefix it with the "kDeleted_" specifier and to add a new entry, add
33 // it just prior to kEnumBoundary, and ensure to update the
34 // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml (by
35 // running update_extension_permission.py).
36 // TODO(sashab): Move this to a more central location, and rename it to
37 // PermissionID.
38 enum ID {
39 // Error codes.
40 kInvalid = 0,
41 kUnknown = 1,
42
43 // Actual permission IDs. Not all of these are valid permissions on their
44 // own; some are just needed by various manifest permissions to represent
45 // their permission message rule combinations.
46 kAccessibilityFeaturesModify = 2,
47 kAccessibilityFeaturesRead = 3,
48 kAccessibilityPrivate = 4,
49 kActiveTab = 5,
50 kActivityLogPrivate = 6,
51 kAlarms = 7,
52 kAlphaEnabled = 8,
53 kAlwaysOnTopWindows = 9,
54 kAppView = 10,
55 kAudio = 11,
56 kAudioCapture = 12,
57 kDeleted_AudioModem = 13,
58 kAutofillPrivate = 14,
59 kAutomation = 15,
60 kAutoTestPrivate = 16,
61 kBackground = 17,
62 kBluetoothPrivate = 18,
63 kBookmark = 19,
64 kBookmarkManagerPrivate = 20,
65 kBrailleDisplayPrivate = 21,
66 kBrowser = 22,
67 kBrowsingData = 23,
68 kCast = 24,
69 kCastStreaming = 25,
70 kChromeosInfoPrivate = 26,
71 kClipboardRead = 27,
72 kClipboardWrite = 28,
73 kCloudPrintPrivate = 29,
74 kCommandLinePrivate = 30,
75 kCommandsAccessibility = 31,
76 kContentSettings = 32,
77 kContextMenus = 33,
78 kCookie = 34,
79 kDeleted_Copresence = 35,
80 kDeleted_CopresencePrivate = 36,
81 kCryptotokenPrivate = 37,
82 kDataReductionProxy = 38,
83 kDiagnostics = 39,
84 kDeleted_Dial = 40, // API removed.
85 kDebugger = 41,
86 kDeclarative = 42,
87 kDeclarativeContent = 43,
88 kDeclarativeWebRequest = 44,
89 kDesktopCapture = 45,
90 kDesktopCapturePrivate = 46,
91 kDeveloperPrivate = 47,
92 kDevtools = 48,
93 kDns = 49,
94 kDocumentScan = 50,
95 kDownloads = 51,
96 kDownloadsInternal = 52,
97 kDownloadsOpen = 53,
98 kDownloadsShelf = 54,
99 kDeleted_EasyUnlockPrivate = 55,
100 kEchoPrivate = 56,
101 kEmbeddedExtensionOptions = 57,
102 kEnterprisePlatformKeys = 58,
103 kEnterprisePlatformKeysPrivate = 59,
104 kDeleted_ExperienceSamplingPrivate = 60,
105 kExperimental = 61,
106 kExtensionView = 62,
107 kExternallyConnectableAllUrls = 63,
108 kFeedbackPrivate = 64,
109 kFileBrowserHandler = 65,
110 kFileBrowserHandlerInternal = 66,
111 kFileManagerPrivate = 67,
112 kFileSystem = 68,
113 kFileSystemDirectory = 69,
114 kFileSystemProvider = 70,
115 kFileSystemRequestFileSystem = 71,
116 kFileSystemRetainEntries = 72,
117 kFileSystemWrite = 73,
118 kDeleted_FileSystemWriteDirectory = 74,
119 kFirstRunPrivate = 75,
120 kFontSettings = 76,
121 kFullscreen = 77,
122 kDeleted_GcdPrivate = 78,
123 kGcm = 79,
124 kGeolocation = 80,
125 kHid = 81,
126 kHistory = 82,
127 kHomepage = 83,
128 kHotwordPrivate = 84,
129 kIdentity = 85,
130 kIdentityEmail = 86,
131 kIdentityPrivate = 87,
132 kIdltest = 88,
133 kIdle = 89,
134 kImeWindowEnabled = 90,
135 kDeleted_InlineInstallPrivate = 91,
136 kInput = 92,
137 kInputMethodPrivate = 93,
138 kDeleted_InterceptAllKeys = 94,
139 kLauncherSearchProvider = 95,
140 kLocation = 96,
141 kDeleted_LogPrivate = 97,
142 kManagement = 98,
143 kMediaGalleries = 99,
144 kMediaPlayerPrivate = 100,
145 kMediaRouterPrivate = 101,
146 kMetricsPrivate = 102,
147 kMDns = 103,
148 kMusicManagerPrivate = 104,
149 kNativeMessaging = 105,
150 kNetworkingConfig = 106,
151 kNetworkingPrivate = 107,
152 kDeleted_NotificationProvider = 108,
153 kNotifications = 109,
154 kOverrideEscFullscreen = 110,
155 kPageCapture = 111,
156 kPointerLock = 112,
157 kPlatformKeys = 113,
158 kDeleted_Plugin = 114,
159 kPower = 115,
160 kDeleted_PreferencesPrivate = 116,
161 kDeleted_PrincipalsPrivate = 117,
162 kPrinterProvider = 118,
163 kPrivacy = 119,
164 kProcesses = 120,
165 kProxy = 121,
166 kImageWriterPrivate = 122,
167 kDeleted_ReadingListPrivate = 123,
168 kRtcPrivate = 124,
169 kSearchProvider = 125,
170 kSearchEnginesPrivate = 126,
171 kSerial = 127,
172 kSessions = 128,
173 kSettingsPrivate = 129,
174 kSignedInDevices = 130,
175 kSocket = 131,
176 kStartupPages = 132,
177 kStorage = 133,
178 kDeleted_StreamsPrivate = 134,
179 kSyncFileSystem = 135,
180 kSystemPrivate = 136,
181 kSystemDisplay = 137,
182 kSystemStorage = 138,
183 kTab = 139,
184 kTabCapture = 140,
185 kTabCaptureForTab = 141,
186 kTerminalPrivate = 142,
187 kTopSites = 143,
188 kTts = 144,
189 kTtsEngine = 145,
190 kUnlimitedStorage = 146,
191 kU2fDevices = 147,
192 kUsb = 148,
193 kUsbDevice = 149,
194 kVideoCapture = 150,
195 kVirtualKeyboardPrivate = 151,
196 kVpnProvider = 152,
197 kWallpaper = 153,
198 kWallpaperPrivate = 154,
199 kWebcamPrivate = 155,
200 kWebConnectable = 156, // for externally_connectable manifest key
201 kWebNavigation = 157,
202 kWebRequest = 158,
203 kWebRequestBlocking = 159,
204 kWebrtcAudioPrivate = 160,
205 kWebrtcDesktopCapturePrivate = 161,
206 kWebrtcLoggingPrivate = 162,
207 kWebstorePrivate = 163,
208 kWebstoreWidgetPrivate = 164,
209 kWebView = 165,
210 kWindowShape = 166,
211 kDeleted_ScreenlockPrivate = 167,
212 kSystemCpu = 168,
213 kSystemMemory = 169,
214 kSystemNetwork = 170,
215 kSystemInfoCpu = 171,
216 kSystemInfoMemory = 172,
217 kBluetooth = 173,
218 kBluetoothDevices = 174,
219 kFavicon = 175,
220 kFullAccess = 176,
221 kHostReadOnly = 177,
222 kHostReadWrite = 178,
223 kHostsAll = 179,
224 kHostsAllReadOnly = 180,
225 kMediaGalleriesAllGalleriesCopyTo = 181,
226 kMediaGalleriesAllGalleriesDelete = 182,
227 kMediaGalleriesAllGalleriesRead = 183,
228 kNetworkState = 184,
229 kOverrideBookmarksUI = 185,
230 kShouldWarnAllHosts = 186,
231 kSocketAnyHost = 187,
232 kSocketDomainHosts = 188,
233 kSocketSpecificHosts = 189,
234 kDeleted_UsbDeviceList = 190,
235 kUsbDeviceUnknownProduct = 191,
236 kUsbDeviceUnknownVendor = 192,
237 kUsersPrivate = 193,
238 kPasswordsPrivate = 194,
239 kLanguageSettingsPrivate = 195,
240 kEnterpriseDeviceAttributes = 196,
241 kCertificateProvider = 197,
242 kResourcesPrivate = 198,
243 kDisplaySource = 199,
244 kClipboard = 200,
245 kNetworkingOnc = 201,
246 kVirtualKeyboard = 202,
247 kNetworkingCastPrivate = 203,
248 kMediaPerceptionPrivate = 204,
249 kLockScreen = 205,
250 kNewTabPageOverride = 206,
251 kDeclarativeNetRequest = 207,
252 kLockWindowFullscreenPrivate = 208,
253 kWebrtcLoggingPrivateAudioDebug = 209,
254 kEnterpriseReportingPrivate = 210,
255 kCecPrivate = 211,
256 kSafeBrowsingPrivate = 212,
257 kFileSystemRequestDownloads = 213,
258 kSystemPowerSource = 214,
259 kArcAppsPrivate = 215,
260 kEnterpriseHardwarePlatform = 216,
261 // Last entry: Add new entries above and ensure to update the
262 // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
263 // (by running update_extension_permission.py).
264 kEnumBoundary,
265 };
266
267 struct CheckParam {
268 };
269
270 explicit APIPermission(const APIPermissionInfo* info);
271
272 virtual ~APIPermission();
273
274 // Returns the id of this permission.
275 ID id() const;
276
277 // Returns the name of this permission.
278 const char* name() const;
279
280 // Returns the APIPermission of this permission.
281 const APIPermissionInfo* info() const {
282 return info_;
283 }
284
285 // The set of permissions an app/extension with this API permission has. These
286 // permissions are used by PermissionMessageProvider to generate meaningful
287 // permission messages for the app/extension.
288 //
289 // For simple API permissions, this will return a set containing only the ID
290 // of the permission. More complex permissions might have multiple IDs, one
291 // for each of the capabilities the API permission has (e.g. read, write and
292 // copy, in the case of the media gallery permission). Permissions that
293 // require parameters may also contain a parameter string (along with the
294 // permission's ID) which can be substituted into the permission message if a
295 // rule is defined to do so.
296 //
297 // Permissions with multiple values, such as host permissions, are represented
298 // by multiple entries in this set. Each permission in the subset has the same
299 // ID (e.g. kHostReadOnly) but a different parameter (e.g. google.com). These
300 // are grouped to form different kinds of permission messages (e.g. 'Access to
301 // 2 hosts') depending on the number that are in the set. The rules that
302 // define the grouping of related permissions with the same ID is defined in
303 // ChromePermissionMessageProvider.
304 virtual PermissionIDSet GetPermissions() const = 0;
305
306 // Returns true if the given permission is allowed.
307 virtual bool Check(const CheckParam* param) const = 0;
308
309 // Returns true if |rhs| is a subset of this.
310 virtual bool Contains(const APIPermission* rhs) const = 0;
311
312 // Returns true if |rhs| is equal to this.
313 virtual bool Equal(const APIPermission* rhs) const = 0;
314
315 // Parses the APIPermission from |value|. Returns false if an error happens
316 // and optionally set |error| if |error| is not NULL. If |value| represents
317 // multiple permissions, some are invalid, and |unhandled_permissions| is
318 // not NULL, the invalid ones are put into |unhandled_permissions| and the
319 // function returns true.
320 virtual bool FromValue(const base::Value* value,
321 std::string* error,
322 std::vector<std::string>* unhandled_permissions) = 0;
323
324 // Stores this into a new created |value|.
325 virtual std::unique_ptr<base::Value> ToValue() const = 0;
326
327 // Clones this.
328 virtual std::unique_ptr<APIPermission> Clone() const = 0;
329
330 // Returns a new API permission which equals this - |rhs|.
331 virtual std::unique_ptr<APIPermission> Diff(
332 const APIPermission* rhs) const = 0;
333
334 // Returns a new API permission which equals the union of this and |rhs|.
335 virtual std::unique_ptr<APIPermission> Union(
336 const APIPermission* rhs) const = 0;
337
338 // Returns a new API permission which equals the intersect of this and |rhs|.
339 virtual std::unique_ptr<APIPermission> Intersect(
340 const APIPermission* rhs) const = 0;
341
342 // IPC functions
343 // Writes this into the given IPC message |m|.
344 virtual void Write(base::Pickle* m) const = 0;
345
346 // Reads from the given IPC message |m|.
347 virtual bool Read(const base::Pickle* m, base::PickleIterator* iter) = 0;
348
349 // Logs this permission.
350 virtual void Log(std::string* log) const = 0;
351
352 private:
353 const APIPermissionInfo* const info_;
354};
355
356
357// The APIPermissionInfo is an immutable class that describes a single
358// named permission (API permission).
359// There is one instance per permission.
360class APIPermissionInfo {
361 public:
362 enum Flag {
363 kFlagNone = 0,
364
365 // Plugins (NPAPI) are deprecated.
366 // kFlagImpliesFullAccess = 1 << 0,
367
368 // Indicates if the permission implies full URL access.
369 kFlagImpliesFullURLAccess = 1 << 1,
370
371 // Indicates that extensions cannot specify the permission as optional.
372 kFlagCannotBeOptional = 1 << 3,
373
374 // Indicates that the permission is internal to the extensions
375 // system and cannot be specified in the "permissions" list.
376 kFlagInternal = 1 << 4,
377
378 // Indicates that the permission may be granted to web contents by
379 // extensions using the content_capabilities manifest feature.
380 kFlagSupportsContentCapabilities = 1 << 5,
381 };
382
383 using APIPermissionConstructor =
384 std::unique_ptr<APIPermission> (*)(const APIPermissionInfo*);
385
386 typedef std::set<APIPermission::ID> IDSet;
387
388 // This exists to allow aggregate initialization, so that default values
389 // for flags, etc. can be omitted.
390 // TODO(yoz): Simplify the way initialization is done. APIPermissionInfo
391 // should be the simple data struct.
392 struct InitInfo {
393 APIPermission::ID id;
394 const char* name;
395 int flags;
396 APIPermissionInfo::APIPermissionConstructor constructor;
397 };
398
399 ~APIPermissionInfo();
400
401 // Creates a APIPermission instance.
402 std::unique_ptr<APIPermission> CreateAPIPermission() const;
403
404 int flags() const { return flags_; }
405
406 APIPermission::ID id() const { return id_; }
407
408 // Returns the name of this permission.
409 const char* name() const { return name_; }
410
411 // Returns true if this permission implies full URL access.
412 bool implies_full_url_access() const {
413 return (flags_ & kFlagImpliesFullURLAccess) != 0;
414 }
415
416 // Returns true if this permission can be added and removed via the
417 // optional permissions extension API.
418 bool supports_optional() const {
419 return (flags_ & kFlagCannotBeOptional) == 0;
420 }
421
422 // Returns true if this permission is internal rather than a
423 // "permissions" list entry.
424 bool is_internal() const {
425 return (flags_ & kFlagInternal) != 0;
426 }
427
428 // Returns true if this permission can be granted to web contents by an
429 // extension through the content_capabilities manifest feature.
430 bool supports_content_capabilities() const {
431 return (flags_ & kFlagSupportsContentCapabilities) != 0;
432 }
433
434 private:
435 // Instances should only be constructed from within a PermissionsInfo.
436 friend class PermissionsInfo;
437 // Implementations of APIPermission will want to get the permission message,
438 // but this class's implementation should be hidden from everyone else.
439 friend class APIPermission;
440
441 explicit APIPermissionInfo(const InitInfo& info);
442
443 const APIPermission::ID id_;
444 const char* const name_;
445 const int flags_;
446 const APIPermissionConstructor api_permission_constructor_;
447};
448
449} // namespace extensions
450
451#endif // EXTENSIONS_COMMON_PERMISSIONS_API_PERMISSION_H_
452