AutoplayAllowlist.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/String.h>
  7. #include <AK/URL.h>
  8. #include <LibWeb/DOM/Document.h>
  9. #include <LibWeb/DOMURL/DOMURL.h>
  10. #include <LibWeb/HTML/Origin.h>
  11. #include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
  12. // FIXME: This is an ad-hoc implementation of the "autoplay" policy-controlled feature:
  13. // https://w3c.github.io/webappsec-permissions-policy/#policy-controlled-feature
  14. namespace Web::PermissionsPolicy {
  15. AutoplayAllowlist& AutoplayAllowlist::the()
  16. {
  17. static AutoplayAllowlist filter;
  18. return filter;
  19. }
  20. AutoplayAllowlist::AutoplayAllowlist() = default;
  21. AutoplayAllowlist::~AutoplayAllowlist() = default;
  22. // https://w3c.github.io/webappsec-permissions-policy/#is-feature-enabled
  23. Decision AutoplayAllowlist::is_allowed_for_origin(DOM::Document const& document, HTML::Origin const& origin) const
  24. {
  25. // FIXME: 1. Let policy be document’s Permissions Policy
  26. // FIXME: 2. If policy’s inherited policy for feature is Disabled, return "Disabled".
  27. // 3. If feature is present in policy’s declared policy:
  28. if (m_allowlist.has_value()) {
  29. // 1. If the allowlist for feature in policy’s declared policy matches origin, then return "Enabled".
  30. // 2. Otherwise return "Disabled".
  31. return m_allowlist->visit(
  32. [](Global) {
  33. return Decision::Enabled;
  34. },
  35. [&](auto const& patterns) {
  36. for (auto const& pattern : patterns) {
  37. if (pattern.is_same_origin_domain(origin))
  38. return Decision::Enabled;
  39. }
  40. return Decision::Disabled;
  41. });
  42. }
  43. // 4. If feature’s default allowlist is *, return "Enabled".
  44. // 5. If feature’s default allowlist is 'self', and origin is same origin with document’s origin, return "Enabled".
  45. // NOTE: The "autoplay" feature's default allowlist is 'self'.
  46. // https://html.spec.whatwg.org/multipage/infrastructure.html#autoplay-feature
  47. if (origin.is_same_origin(document.origin()))
  48. return Decision::Enabled;
  49. // 6. Return "Disabled".
  50. return Decision::Disabled;
  51. }
  52. void AutoplayAllowlist::enable_globally()
  53. {
  54. m_allowlist = Global {};
  55. }
  56. ErrorOr<void> AutoplayAllowlist::enable_for_origins(ReadonlySpan<String> origins)
  57. {
  58. m_allowlist = Patterns {};
  59. auto& allowlist = m_allowlist->get<Patterns>();
  60. TRY(allowlist.try_ensure_capacity(origins.size()));
  61. for (auto const& origin : origins) {
  62. URL url { origin };
  63. if (!url.is_valid())
  64. url = TRY(String::formatted("https://{}", origin));
  65. if (!url.is_valid()) {
  66. dbgln("Invalid origin for autoplay allowlist: {}", origin);
  67. continue;
  68. }
  69. TRY(allowlist.try_append(DOMURL::url_origin(url)));
  70. }
  71. return {};
  72. }
  73. }