Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(604)

Unified Diff: Source/modules/permissions/Permissions.cpp

Issue 1234023002: blink: permissions: add plumbing to revoke permissions (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/permissions/Permissions.h ('k') | Source/modules/permissions/Permissions.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/permissions/Permissions.cpp
diff --git a/Source/modules/permissions/Permissions.cpp b/Source/modules/permissions/Permissions.cpp
index 92e662af2b8ece2bfbb04555d3e97944c211b169..ad99d5919370ac6a17ec30974e13c1c53bb627b7 100644
--- a/Source/modules/permissions/Permissions.cpp
+++ b/Source/modules/permissions/Permissions.cpp
@@ -13,15 +13,58 @@
#include "core/dom/DOMException.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "modules/permissions/PermissionCallback.h"
#include "modules/permissions/PermissionController.h"
#include "modules/permissions/PermissionDescriptor.h"
-#include "modules/permissions/PermissionQueryCallback.h"
#include "modules/permissions/PermissionStatus.h"
#include "public/platform/Platform.h"
#include "public/platform/modules/permissions/WebPermissionClient.h"
namespace blink {
+namespace {
+
+// Here we handle some common permission patterns to prevent propogation up to the content layer
+// Examples of behaviours which would go here are rejecting unsupported permissions, accepting
+// permissions which are always granted or always denied according to the spec etc.
+bool handleDefaultBehaviour(
+ ScriptState* scriptState, const ScriptValue& rawPermission, PassRefPtr<ScriptPromiseResolver> resolver, WebPermissionType type, TrackExceptionState& exceptionState)
+{
+ if (type == WebPermissionTypePushNotifications) {
+ PushPermissionDescriptor pushPermission = NativeValueTraits<PushPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
+ // Only "userVisibleOnly" push is supported for now.
+ if (!pushPermission.userVisibleOnly()) {
+ resolver->reject(DOMException::create(NotSupportedError, "Push Permission without userVisibleOnly:true isn't supported yet."));
+ return true;
+ }
+ } else if (type == WebPermissionTypeMidiSysEx) {
+ MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
+ // Only sysex usage requires a permission, otherwise it is granted.
+ if (!midiPermission.sysex()) {
+ resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusGranted, WebPermissionTypeMidi));
+ return true;
+ }
+ }
+ return false;
+}
+
+WebPermissionType convertPermissionStringToType(const String& name)
+{
+ if (name == "geolocation")
+ return WebPermissionTypeGeolocation;
+ if (name == "notifications")
+ return WebPermissionTypeNotifications;
+ if (name == "push")
+ return WebPermissionTypePushNotifications;
+ if (name == "midi")
+ return WebPermissionTypeMidiSysEx;
+
+ ASSERT_NOT_REACHED();
+ return WebPermissionTypeGeolocation;
+}
+
+} // anonymous namespace
+
// static
WebPermissionClient* Permissions::getClient(ExecutionContext* executionContext)
{
@@ -52,37 +95,41 @@ ScriptPromise Permissions::query(ScriptState* scriptState, const ScriptValue& ra
ScriptPromise promise = resolver->promise();
String name = permission.name();
- WebPermissionType type;
- if (name == "geolocation") {
- type = WebPermissionTypeGeolocation;
- } else if (name == "notifications") {
- type = WebPermissionTypeNotifications;
- } else if (name == "push") {
- PushPermissionDescriptor pushPermission = NativeValueTraits<PushPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
- // Only "userVisibleOnly" push is supported for now.
- if (!pushPermission.userVisibleOnly()) {
- resolver->reject(DOMException::create(NotSupportedError, "Push Permission without userVisibleOnly:true isn't supported yet."));
- return promise;
- }
- type = WebPermissionTypePushNotifications;
- } else if (name == "midi") {
- MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
- // Only sysex usage requires a permission, otherwise it is granted.
- if (!midiPermission.sysex()) {
- resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusGranted, WebPermissionTypeMidi));
- return promise;
- }
- type = WebPermissionTypeMidiSysEx;
- } else {
- ASSERT_NOT_REACHED();
- type = WebPermissionTypeGeolocation;
- }
+ WebPermissionType type = convertPermissionStringToType(name);
+
+ if (handleDefaultBehaviour(scriptState, rawPermission, resolver, type, exceptionState))
+ return promise;
// If the current origin is a file scheme, it will unlikely return a
// meaningful value because most APIs are broken on file scheme and no
// permission prompt will be shown even if the returned permission will most
// likely be "prompt".
- client->queryPermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionQueryCallback(resolver, type));
+ client->queryPermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type));
+ return promise;
+}
+
+ScriptPromise Permissions::revoke(ScriptState* scriptState, const ScriptValue& rawPermission)
+{
+ WebPermissionClient* client = getClient(scriptState->executionContext());
+ if (!client)
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't revoke permissions."));
+
+ TrackExceptionState exceptionState;
+ PermissionDescriptor permission = NativeValueTraits<PermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
+
+ if (exceptionState.hadException())
+ return ScriptPromise::reject(scriptState, v8::Exception::TypeError(v8String(scriptState->isolate(), exceptionState.message())));
+
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+
+ String name = permission.name();
+ WebPermissionType type = convertPermissionStringToType(name);
+
+ if (handleDefaultBehaviour(scriptState, rawPermission, resolver, type, exceptionState))
+ return promise;
+
+ client->revokePermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type));
return promise;
}
« no previous file with comments | « Source/modules/permissions/Permissions.h ('k') | Source/modules/permissions/Permissions.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698