| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/permissions/Permissions.h" | 5 #include "modules/permissions/Permissions.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/Dictionary.h" | 7 #include "bindings/core/v8/Dictionary.h" |
| 8 #include "bindings/core/v8/Nullable.h" | 8 #include "bindings/core/v8/Nullable.h" |
| 9 #include "bindings/core/v8/ScriptPromise.h" | 9 #include "bindings/core/v8/ScriptPromise.h" |
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "public/platform/modules/permissions/WebPermissionClient.h" | 24 #include "public/platform/modules/permissions/WebPermissionClient.h" |
| 25 #include "wtf/NotFound.h" | 25 #include "wtf/NotFound.h" |
| 26 #include "wtf/PtrUtil.h" | 26 #include "wtf/PtrUtil.h" |
| 27 #include "wtf/Vector.h" | 27 #include "wtf/Vector.h" |
| 28 #include <memory> | 28 #include <memory> |
| 29 | 29 |
| 30 namespace blink { | 30 namespace blink { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // Websites will be able to run code when `name()` is called, changing the |
| 35 // current context. The caller should make sure that no assumption is made |
| 36 // after this has been called. |
| 34 WebPermissionType getPermissionType(ScriptState* scriptState, const Dictionary&
rawPermission, const PermissionDescriptor& permission, ExceptionState& exception
State) | 37 WebPermissionType getPermissionType(ScriptState* scriptState, const Dictionary&
rawPermission, const PermissionDescriptor& permission, ExceptionState& exception
State) |
| 35 { | 38 { |
| 36 const String& name = permission.name(); | 39 const String& name = permission.name(); |
| 37 if (name == "geolocation") | 40 if (name == "geolocation") |
| 38 return WebPermissionTypeGeolocation; | 41 return WebPermissionTypeGeolocation; |
| 39 if (name == "notifications") | 42 if (name == "notifications") |
| 40 return WebPermissionTypeNotifications; | 43 return WebPermissionTypeNotifications; |
| 41 if (name == "push") | 44 if (name == "push") |
| 42 return WebPermissionTypePushNotifications; | 45 return WebPermissionTypePushNotifications; |
| 43 if (name == "midi") { | 46 if (name == "midi") { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 if (!document->frame()) | 102 if (!document->frame()) |
| 100 return nullptr; | 103 return nullptr; |
| 101 PermissionController* controller = PermissionController::from(*document-
>frame()); | 104 PermissionController* controller = PermissionController::from(*document-
>frame()); |
| 102 return controller ? controller->client() : nullptr; | 105 return controller ? controller->client() : nullptr; |
| 103 } | 106 } |
| 104 return Platform::current()->permissionClient(); | 107 return Platform::current()->permissionClient(); |
| 105 } | 108 } |
| 106 | 109 |
| 107 ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& raw
Permission) | 110 ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& raw
Permission) |
| 108 { | 111 { |
| 109 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); | |
| 110 if (!client) | |
| 111 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't query pe
rmissions.")); | |
| 112 | |
| 113 ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Perm
issions", scriptState->context()->Global(), scriptState->isolate()); | 112 ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Perm
issions", scriptState->context()->Global(), scriptState->isolate()); |
| 114 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); | 113 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); |
| 115 if (exceptionState.hadException()) | 114 if (exceptionState.hadException()) |
| 116 return exceptionState.reject(scriptState); | 115 return exceptionState.reject(scriptState); |
| 117 | 116 |
| 117 // This must be called after `parsePermission` because the website might |
| 118 // be able to run code. |
| 119 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); |
| 120 if (!client) |
| 121 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't query pe
rmissions.")); |
| 122 |
| 118 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 123 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 119 ScriptPromise promise = resolver->promise(); | 124 ScriptPromise promise = resolver->promise(); |
| 120 | 125 |
| 121 // If the current origin is a file scheme, it will unlikely return a | 126 // If the current origin is a file scheme, it will unlikely return a |
| 122 // meaningful value because most APIs are broken on file scheme and no | 127 // meaningful value because most APIs are broken on file scheme and no |
| 123 // permission prompt will be shown even if the returned permission will most | 128 // permission prompt will be shown even if the returned permission will most |
| 124 // likely be "prompt". | 129 // likely be "prompt". |
| 125 client->queryPermission(type.get(), KURL(KURL(), scriptState->getExecutionCo
ntext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type
.get())); | 130 client->queryPermission(type.get(), KURL(KURL(), scriptState->getExecutionCo
ntext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type
.get())); |
| 126 return promise; | 131 return promise; |
| 127 } | 132 } |
| 128 | 133 |
| 129 ScriptPromise Permissions::request(ScriptState* scriptState, const Dictionary& r
awPermission) | 134 ScriptPromise Permissions::request(ScriptState* scriptState, const Dictionary& r
awPermission) |
| 130 { | 135 { |
| 131 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); | |
| 132 if (!client) | |
| 133 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); | |
| 134 | |
| 135 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); | 136 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); |
| 136 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); | 137 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); |
| 137 if (exceptionState.hadException()) | 138 if (exceptionState.hadException()) |
| 138 return exceptionState.reject(scriptState); | 139 return exceptionState.reject(scriptState); |
| 139 | 140 |
| 141 // This must be called after `parsePermission` because the website might |
| 142 // be able to run code. |
| 143 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); |
| 144 if (!client) |
| 145 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); |
| 146 |
| 140 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 147 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 141 ScriptPromise promise = resolver->promise(); | 148 ScriptPromise promise = resolver->promise(); |
| 142 | 149 |
| 143 client->requestPermission(type.get(), KURL(KURL(), scriptState->getExecution
Context()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, ty
pe.get())); | 150 client->requestPermission(type.get(), KURL(KURL(), scriptState->getExecution
Context()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, ty
pe.get())); |
| 144 return promise; | 151 return promise; |
| 145 } | 152 } |
| 146 | 153 |
| 147 ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& ra
wPermission) | 154 ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& ra
wPermission) |
| 148 { | 155 { |
| 149 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); | |
| 150 if (!client) | |
| 151 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't revoke p
ermissions.")); | |
| 152 | |
| 153 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Per
missions", scriptState->context()->Global(), scriptState->isolate()); | 156 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Per
missions", scriptState->context()->Global(), scriptState->isolate()); |
| 154 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); | 157 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermissio
n, exceptionState); |
| 155 if (exceptionState.hadException()) | 158 if (exceptionState.hadException()) |
| 156 return exceptionState.reject(scriptState); | 159 return exceptionState.reject(scriptState); |
| 157 | 160 |
| 161 // This must be called after `parsePermission` because the website might |
| 162 // be able to run code. |
| 163 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); |
| 164 if (!client) |
| 165 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't revoke p
ermissions.")); |
| 166 |
| 158 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 167 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 159 ScriptPromise promise = resolver->promise(); | 168 ScriptPromise promise = resolver->promise(); |
| 160 | 169 |
| 161 client->revokePermission(type.get(), KURL(KURL(), scriptState->getExecutionC
ontext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, typ
e.get())); | 170 client->revokePermission(type.get(), KURL(KURL(), scriptState->getExecutionC
ontext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, typ
e.get())); |
| 162 return promise; | 171 return promise; |
| 163 } | 172 } |
| 164 | 173 |
| 165 ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dic
tionary>& rawPermissions) | 174 ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dic
tionary>& rawPermissions) |
| 166 { | 175 { |
| 167 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); | |
| 168 if (!client) | |
| 169 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); | |
| 170 | |
| 171 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); | 176 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); |
| 172 std::unique_ptr<Vector<WebPermissionType>> internalPermissions = wrapUnique(
new Vector<WebPermissionType>()); | 177 std::unique_ptr<Vector<WebPermissionType>> internalPermissions = wrapUnique(
new Vector<WebPermissionType>()); |
| 173 std::unique_ptr<Vector<int>> callerIndexToInternalIndex = wrapUnique(new Vec
tor<int>(rawPermissions.size())); | 178 std::unique_ptr<Vector<int>> callerIndexToInternalIndex = wrapUnique(new Vec
tor<int>(rawPermissions.size())); |
| 174 for (size_t i = 0; i < rawPermissions.size(); ++i) { | 179 for (size_t i = 0; i < rawPermissions.size(); ++i) { |
| 175 const Dictionary& rawPermission = rawPermissions[i]; | 180 const Dictionary& rawPermission = rawPermissions[i]; |
| 176 | 181 |
| 177 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermi
ssion, exceptionState); | 182 Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermi
ssion, exceptionState); |
| 178 if (exceptionState.hadException()) | 183 if (exceptionState.hadException()) |
| 179 return exceptionState.reject(scriptState); | 184 return exceptionState.reject(scriptState); |
| 180 | 185 |
| 181 // Only append permissions to the vector that is passed to the client if
it is not already | 186 // Only append permissions to the vector that is passed to the client if
it is not already |
| 182 // in the vector (i.e. do not duplicate permisison types). | 187 // in the vector (i.e. do not duplicate permisison types). |
| 183 int internalIndex; | 188 int internalIndex; |
| 184 auto it = internalPermissions->find(type.get()); | 189 auto it = internalPermissions->find(type.get()); |
| 185 if (it == kNotFound) { | 190 if (it == kNotFound) { |
| 186 internalIndex = internalPermissions->size(); | 191 internalIndex = internalPermissions->size(); |
| 187 internalPermissions->append(type.get()); | 192 internalPermissions->append(type.get()); |
| 188 } else { | 193 } else { |
| 189 internalIndex = it; | 194 internalIndex = it; |
| 190 } | 195 } |
| 191 callerIndexToInternalIndex->operator[](i) = internalIndex; | 196 callerIndexToInternalIndex->operator[](i) = internalIndex; |
| 192 } | 197 } |
| 193 | 198 |
| 199 // This must be called after `parsePermission` because the website might |
| 200 // be able to run code. |
| 201 WebPermissionClient* client = getClient(scriptState->getExecutionContext()); |
| 202 if (!client) |
| 203 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); |
| 204 |
| 194 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 205 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 195 ScriptPromise promise = resolver->promise(); | 206 ScriptPromise promise = resolver->promise(); |
| 196 | 207 |
| 197 WebVector<WebPermissionType> internalWebPermissions = *internalPermissions; | 208 WebVector<WebPermissionType> internalWebPermissions = *internalPermissions; |
| 198 client->requestPermissions(internalWebPermissions, KURL(KURL(), scriptState-
>getExecutionContext()->getSecurityOrigin()->toString()), | 209 client->requestPermissions(internalWebPermissions, KURL(KURL(), scriptState-
>getExecutionContext()->getSecurityOrigin()->toString()), |
| 199 new PermissionsCallback(resolver, std::move(internalPermissions), std::m
ove(callerIndexToInternalIndex))); | 210 new PermissionsCallback(resolver, std::move(internalPermissions), std::m
ove(callerIndexToInternalIndex))); |
| 200 return promise; | 211 return promise; |
| 201 } | 212 } |
| 202 | 213 |
| 203 } // namespace blink | 214 } // namespace blink |
| OLD | NEW |