client, permission-manager: add getters for runtime introspection

Add wp_client_get_permission_manager() and
wp_permission_manager_get_default_permissions() and expose both as Lua
methods. This allows Lua scripts to verify a client's trust level at
runtime by inspecting the actual permission bits of its attached PM.
This commit is contained in:
Torkel Niklasson 2026-04-29 21:34:22 +02:00
parent 0e5ececfcc
commit 19b6cb0658
7 changed files with 133 additions and 0 deletions

View file

@ -123,3 +123,31 @@ Each permission manager supports the following properties:
When both ``default_permissions`` and ``permission_manager_name`` are set in
a rule's ``update-props`` action, ``default_permissions`` takes precedence and
the permission manager is ignored.
Introspecting Permissions from Scripts
--------------------------------------
Lua scripts can query the permission manager attached to a client at runtime
using ``client:get_permission_manager()``. This returns the
``WpPermissionManager`` object (or ``nil`` if none is attached), which can then
be used to inspect the configured permissions.
Example:
.. code-block:: lua
local client_om = ObjectManager { Interest { type = "client" } }
client_om:activate()
-- Check if a client has at least read + execute permissions
local pm = client:get_permission_manager()
if pm then
local perms = pm:get_default_permissions()
if (perms & Perm.RX) == Perm.RX then
-- Client has sufficient permissions
end
end
This is useful for scripts that need to verify a client's trust level before
performing privileged operations on its behalf (e.g. linking nodes into an
audio chain).

View file

@ -186,6 +186,27 @@ contain the following methods:
:param self: the client
:param WpPermissionManager pm: the permission manager to attach
.. function:: Client.get_permission_manager(self)
Binds :c:func:`wp_client_get_permission_manager`
Returns the permission manager currently attached to this client, or ``nil``
if no permission manager is attached.
**Example:**
.. code-block:: lua
local pm = client:get_permission_manager()
if pm then
local perms = pm:get_default_permissions()
-- check permission bits
end
:param self: the client
:returns: the attached permission manager, or nil
:rtype: WpPermissionManager or nil
PipeWire Metadata
.................
@ -233,6 +254,27 @@ with default permissions, core permissions, and match rules.
:param self: the permission manager
:param perms: a permission string (e.g. "rx") or an integer bitmask (e.g. ``Perm.RX``)
.. function:: PermissionManager.get_default_permissions(self)
Binds :c:func:`wp_permission_manager_get_default_permissions`
Returns the default permissions as an integer bitmask. This can be compared
against the ``Perm`` constants using bitwise operators.
**Example:**
.. code-block:: lua
local pm = client:get_permission_manager()
local perms = pm:get_default_permissions()
if (perms & Perm.RX) == Perm.RX then
-- client has at least read + execute
end
:param self: the permission manager
:returns: the default permissions bitmask
:rtype: integer
.. function:: PermissionManager.set_core_permissions(self, perms)
Binds :c:func:`wp_permission_manager_set_core_permissions`

View file

@ -268,3 +268,19 @@ wp_client_attach_permission_manager (WpClient *self, WpPermissionManager *pm)
wp_permission_manager_add_client (pm, self);
g_weak_ref_set (&self->permission_manager, pm);
}
/*!
* \brief Gets the permission manager attached to this client, if any.
*
* \ingroup wpclient
* \param self the client
* \returns (transfer full) (nullable): the attached permission manager,
* or NULL if no permission manager is attached
*/
WpPermissionManager *
wp_client_get_permission_manager (WpClient *self)
{
g_return_val_if_fail (WP_IS_CLIENT (self), NULL);
return g_weak_ref_get (&self->permission_manager);
}

View file

@ -42,6 +42,9 @@ WP_API
void wp_client_attach_permission_manager (WpClient *self,
WpPermissionManager *pm);
WP_API
WpPermissionManager * wp_client_get_permission_manager (WpClient *self);
G_END_DECLS
#endif

View file

@ -523,6 +523,22 @@ wp_permission_manager_set_default_permissions (WpPermissionManager *self,
}
}
/*!
* \brief Gets the default permissions that are applied to all objects that
* don't match any interest
*
* \ingroup wppermissionmanager
* \param self the permission manager
* \returns the default permissions
*/
guint32
wp_permission_manager_get_default_permissions (WpPermissionManager *self)
{
g_return_val_if_fail (WP_IS_PERMISSION_MANAGER (self), 0);
return self->default_perms;
}
/*!
* \brief Sets the permissions that will be applied to the core object (ID 0).
*

View file

@ -54,6 +54,10 @@ WP_API
void wp_permission_manager_set_default_permissions (
WpPermissionManager *self, guint32 permissions);
WP_API
guint32 wp_permission_manager_get_default_permissions (
WpPermissionManager *self);
WP_API
void wp_permission_manager_set_core_permissions (
WpPermissionManager *self, guint32 permissions);

View file

@ -1399,11 +1399,24 @@ client_attach_permission_manager (lua_State *L)
return 0;
}
static int
client_get_permission_manager (lua_State *L)
{
WpClient *client = wplua_checkobject (L, 1, WP_TYPE_CLIENT);
WpPermissionManager *pm = wp_client_get_permission_manager (client);
if (pm)
wplua_pushobject (L, pm);
else
lua_pushnil (L);
return 1;
}
static const luaL_Reg client_methods[] = {
{ "update_permissions", client_update_permissions },
{ "update_properties", client_update_properties },
{ "send_error", client_send_error },
{ "attach_permission_manager", client_attach_permission_manager },
{ "get_permission_manager", client_get_permission_manager },
{ NULL, NULL }
};
@ -2660,6 +2673,16 @@ permission_manager_set_default_permissions (lua_State *L)
return 0;
}
static int
permission_manager_get_default_permissions (lua_State *L)
{
WpPermissionManager *pm = wplua_checkobject (L, 1,
WP_TYPE_PERMISSION_MANAGER);
guint32 perms = wp_permission_manager_get_default_permissions (pm);
lua_pushinteger (L, perms);
return 1;
}
static int
permission_manager_set_core_permissions (lua_State *L)
{
@ -2746,6 +2769,7 @@ permission_manager_update_permissions (lua_State *L)
static const luaL_Reg permission_manager_funcs[] = {
{ "set_default_permissions", permission_manager_set_default_permissions },
{ "get_default_permissions", permission_manager_get_default_permissions },
{ "set_core_permissions", permission_manager_set_core_permissions },
{ "add_interest_match", permission_manager_add_interest_match },
{ "add_interest_match_simple", permission_manager_add_interest_match_simple },