ladybird/Libraries/LibWeb/PermissionsAPI/PermissionStore.cpp
Andreas Kling 164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00

85 lines
3.7 KiB
C++

/*
* Copyright (c) 2026, Niccolo Antonelli-Dziri <niccolo.antonelli-dziri@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/PermissionsAPI/PermissionStore.h>
namespace Web::PermissionsAPI {
bool permission_key_is_equal_to(Bindings::PermissionDescriptor const&, URL::Origin const& key1, URL::Origin const& key2)
{
// FIXME: 1. If key1 is not of descriptor's permission key type or key2 is not of descriptor's permission key type, return false.
// 2. Return the result of running the permission key comparison algorithm for the feature named by descriptor's name, passing key1 and key2.
return permission_key_comparison_algorithm(key1, key2);
}
// https://w3c.github.io/permissions/#dfn-permission-key-comparison-algorithm
bool permission_key_comparison_algorithm(URL::Origin const& key1, URL::Origin const& key2)
{
// 1. Return key1 is same origin with key2.
return key1.is_same_origin(key2);
}
// https://w3c.github.io/permissions/#dfn-permission-key-generation-algorithm
URL::Origin permission_key_generation_algorithm(URL::Origin const& origin, URL::Origin const&)
{
// Takes an origin origin and an origin embedded origin, and returns a new permission key.
// If unspecified, this defaults to the default permission key generation algorithm.
// A feature that specifies a custom permission key generation algorithm MUST also specify a permission key comparison algorithm.
// 1. Return origin.
return origin;
// Note: Permission Delegation
// Most powerful features grant permission to the top-level origin and delegate access to the requesting document via Permissions Policy.
// This is known as permission delegation.
}
// FIXME: This should be store at the user-agent level (IPC to the browser process)
PermissionStore& PermissionStore::the()
{
static auto& s_the = *new PermissionStore;
return s_the;
}
Optional<PermissionStoreEntry> PermissionStore::get_permission_store_entry(Bindings::PermissionDescriptor const& descriptor, URL::Origin const& key)
{
// 1. If the user agent's permission store contains an entry whose descriptor is descriptor, and whose key is equal to key given descriptor, return that entry.
for (auto const& entry : m_entries) {
if (entry.descriptor.name == descriptor.name && permission_key_is_equal_to(descriptor, entry.permission_key, key))
return entry;
}
// 2. Return null.
return {};
}
void PermissionStore::set_permission_store_entry(Bindings::PermissionDescriptor const& descriptor, URL::Origin const& key, Bindings::PermissionState state)
{
// 1. Let newEntry be a new permission store entry whose descriptor is descriptor, and whose key is key, and whose state is state.
PermissionStoreEntry new_entry { descriptor, key, state };
// 2. If the user agent's permission store contains an entry whose descriptor is descriptor, and whose key is equal to key given descriptor, replace that entry with newEntry and abort these steps.
for (auto& entry : m_entries) {
if (entry.descriptor.name == descriptor.name && permission_key_is_equal_to(descriptor, entry.permission_key, key)) {
entry = new_entry;
return;
}
}
// 3. Append newEntry to the user agent's permission store.
m_entries.append(move(new_entry));
}
void PermissionStore::remove_permission_store_entry(Bindings::PermissionDescriptor const& descriptor, URL::Origin const& key)
{
// 1. Remove the entry whose descriptor is descriptor, and whose key is equal to key given descriptor, from the user agent's permission store.
m_entries.remove_all_matching([&](auto const& entry) {
return entry.descriptor.name == descriptor.name && permission_key_is_equal_to(descriptor, entry.permission_key, key);
});
}
}