diff --git a/docs/rst/daemon/configuration/access.rst b/docs/rst/daemon/configuration/access.rst index 2696a66c..dd75f3a7 100644 --- a/docs/rst/daemon/configuration/access.rst +++ b/docs/rst/daemon/configuration/access.rst @@ -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). diff --git a/docs/rst/scripting/lua_api/lua_proxies_api.rst b/docs/rst/scripting/lua_api/lua_proxies_api.rst index 6553e1ef..b54461a0 100644 --- a/docs/rst/scripting/lua_api/lua_proxies_api.rst +++ b/docs/rst/scripting/lua_api/lua_proxies_api.rst @@ -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` diff --git a/lib/wp/client.c b/lib/wp/client.c index 59afcff0..e9d3d70f 100644 --- a/lib/wp/client.c +++ b/lib/wp/client.c @@ -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); +} diff --git a/lib/wp/client.h b/lib/wp/client.h index 1a878cb2..8f9e39b9 100644 --- a/lib/wp/client.h +++ b/lib/wp/client.h @@ -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 diff --git a/lib/wp/permission-manager.c b/lib/wp/permission-manager.c index 0e5a384b..dadd7298 100644 --- a/lib/wp/permission-manager.c +++ b/lib/wp/permission-manager.c @@ -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). * diff --git a/lib/wp/permission-manager.h b/lib/wp/permission-manager.h index 073dfb66..886baf5d 100644 --- a/lib/wp/permission-manager.h +++ b/lib/wp/permission-manager.h @@ -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); diff --git a/modules/module-lua-scripting/api/api.c b/modules/module-lua-scripting/api/api.c index 3b9dfdde..5b09be83 100644 --- a/modules/module-lua-scripting/api/api.c +++ b/modules/module-lua-scripting/api/api.c @@ -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 },