static aclList parsePermissions(xmlNode *node, aclList policyList) { xmlNode *cur_node = node; policyPtr accessNode = null; if (cur_node && cur_node->type == XML_ELEMENT_NODE && !strcmp(cur_node->name, permissionsTagName)) { for (cur_node = node->children; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { if (!strcmp(cur_node->name, allowTagName)) { accessNode = parsePermission(cur_node, 1); if (accessNode) { insertAtBack(policyList, accessNode); } else { return null; } } else if (!strcmp(cur_node->name, denyTagName)) { accessNode = parsePermission(cur_node, 0); if (accessNode) { insertAtStart(policyList, accessNode); } else { return null; } } else { fprintf(stderr, "\nInvalid Element:%s\n", cur_node->name); } } } } else { fprintf(stderr, "Expected element : %s, as root node but found:%s", permissionsTagName, cur_node->name); } return policyList; }
ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't revoke permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Permissions", scriptState->context()->Global(), scriptState->isolate()); Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); client->revokePermission(type.get(), KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type.get())); return promise; }
ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Permissions", scriptState->context()->Global(), scriptState->isolate()); Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->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.get(), KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type.get())); return promise; }
ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dictionary>& rawPermissions) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't request permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Permissions", scriptState->context()->Global(), scriptState->isolate()); OwnPtr<Vector<WebPermissionType>> internalPermissions = adoptPtr(new Vector<WebPermissionType>()); OwnPtr<Vector<int>> callerIndexToInternalIndex = adoptPtr(new Vector<int>(rawPermissions.size())); for (size_t i = 0; i < rawPermissions.size(); ++i) { const Dictionary& rawPermission = rawPermissions[i]; Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Only append permissions to the vector that is passed to the client if it is not already // in the vector (i.e. do not duplicate permisison types). int internalIndex; auto it = internalPermissions->find(type.get()); if (it == kNotFound) { internalIndex = internalPermissions->size(); internalPermissions->append(type.get()); } else { internalIndex = it; } callerIndexToInternalIndex->operator[](i) = internalIndex; } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebVector<WebPermissionType> internalWebPermissions = *internalPermissions; client->requestPermissions(internalWebPermissions, KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionsCallback(resolver, internalPermissions.release(), callerIndexToInternalIndex.release())); return promise; }