mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
As file:// URLs are considered opaque origins by default, we need to special case them in the allowlist as any opaque origin will not be matched in the allow list.
99 lines
3.3 KiB
C++
99 lines
3.3 KiB
C++
/*
|
||
* Copyright (c) 2023-2025, Tim Flynn <trflynn89@ladybird.org>
|
||
*
|
||
* SPDX-License-Identifier: BSD-2-Clause
|
||
*/
|
||
|
||
#include <AK/String.h>
|
||
#include <LibURL/Origin.h>
|
||
#include <LibURL/Parser.h>
|
||
#include <LibURL/URL.h>
|
||
#include <LibWeb/DOM/Document.h>
|
||
#include <LibWeb/DOMURL/DOMURL.h>
|
||
#include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
|
||
|
||
// FIXME: This is an ad-hoc implementation of the "autoplay" policy-controlled feature:
|
||
// https://w3c.github.io/webappsec-permissions-policy/#policy-controlled-feature
|
||
|
||
namespace Web::PermissionsPolicy {
|
||
|
||
AutoplayAllowlist& AutoplayAllowlist::the()
|
||
{
|
||
static AutoplayAllowlist filter;
|
||
return filter;
|
||
}
|
||
|
||
AutoplayAllowlist::AutoplayAllowlist() = default;
|
||
AutoplayAllowlist::~AutoplayAllowlist() = default;
|
||
|
||
// https://w3c.github.io/webappsec-permissions-policy/#is-feature-enabled
|
||
Decision AutoplayAllowlist::is_allowed_for_origin(DOM::Document const& document, URL::Origin const& origin) const
|
||
{
|
||
// FIXME: 1. Let policy be document’s Permissions Policy
|
||
// FIXME: 2. If policy’s inherited policy for feature is Disabled, return "Disabled".
|
||
|
||
// 3. If feature is present in policy’s declared policy:
|
||
if (m_allowlist.has_value()) {
|
||
// 1. If the allowlist for feature in policy’s declared policy matches origin, then return "Enabled".
|
||
// 2. Otherwise return "Disabled".
|
||
return m_allowlist->visit(
|
||
[](Global) {
|
||
return Decision::Enabled;
|
||
},
|
||
[&](auto const& patterns) {
|
||
for (auto const& pattern : patterns) {
|
||
if (pattern.is_same_origin_domain(origin))
|
||
return Decision::Enabled;
|
||
|
||
// AD-HOC: Allow autoplay for file:// URLs if the document is also from a file:// URL.
|
||
if (origin.is_opaque_file_origin() && document.origin().is_opaque_file_origin())
|
||
return Decision::Enabled;
|
||
}
|
||
|
||
return Decision::Disabled;
|
||
});
|
||
}
|
||
|
||
// 4. If feature’s default allowlist is *, return "Enabled".
|
||
// 5. If feature’s default allowlist is 'self', and origin is same origin with document’s origin, return "Enabled".
|
||
// NOTE: The "autoplay" feature's default allowlist is 'self'.
|
||
// https://html.spec.whatwg.org/multipage/infrastructure.html#autoplay-feature
|
||
if (origin.is_same_origin(document.origin()))
|
||
return Decision::Enabled;
|
||
|
||
// AD-HOC: Allow autoplay for file:// URLs if the document is also from a file:// URL.
|
||
if (origin.is_opaque_file_origin() && document.origin().is_opaque_file_origin())
|
||
return Decision::Enabled;
|
||
|
||
// 6. Return "Disabled".
|
||
return Decision::Disabled;
|
||
}
|
||
|
||
void AutoplayAllowlist::enable_globally()
|
||
{
|
||
m_allowlist = Global {};
|
||
}
|
||
|
||
void AutoplayAllowlist::enable_for_origins(ReadonlySpan<String> origins)
|
||
{
|
||
m_allowlist = Patterns {};
|
||
|
||
auto& allowlist = m_allowlist->get<Patterns>();
|
||
allowlist.ensure_capacity(origins.size());
|
||
|
||
for (auto const& origin : origins) {
|
||
auto url = URL::Parser::basic_parse(origin);
|
||
|
||
if (!url.has_value())
|
||
url = URL::Parser::basic_parse(MUST(String::formatted("https://{}", origin)));
|
||
if (!url.has_value()) {
|
||
dbgln("Invalid origin for autoplay allowlist: {}", origin);
|
||
continue;
|
||
}
|
||
|
||
allowlist.append(url->origin());
|
||
}
|
||
}
|
||
|
||
}
|