%PDF- %PDF-
Direktori : /usr/share/wireplumber/scripts/access/ |
Current File : //usr/share/wireplumber/scripts/access/access-portal.lua |
MEDIA_ROLE_NONE = 0 MEDIA_ROLE_CAMERA = 1 << 0 function hasPermission (permissions, app_id, lookup) if permissions then for key, values in pairs(permissions) do if key == app_id then for _, v in pairs(values) do if v == lookup then return true end end end end end return false end function parseMediaRoles (media_roles_str) local media_roles = MEDIA_ROLE_NONE for role in media_roles_str:gmatch('[^,%s]+') do if role == "Camera" then media_roles = media_roles | MEDIA_ROLE_CAMERA end end return media_roles end function setPermissions (client, allow_client, allow_nodes) local client_id = client["bound-id"] Log.info(client, "Granting ALL access to client " .. client_id) -- Update permissions on client client:update_permissions { [client_id] = allow_client and "all" or "-" } -- Update permissions on camera source nodes for node in nodes_om:iterate() do local node_id = node["bound-id"] client:update_permissions { [node_id] = allow_nodes and "all" or "-" } end end function updateClientPermissions (client, permissions) local client_id = client["bound-id"] local str_prop = nil local app_id = nil local media_roles = nil local allowed = false -- Make sure the client is not the portal itself str_prop = client.properties["pipewire.access.portal.is_portal"] if str_prop == "yes" then Log.info (client, "client is the portal itself") return end -- Make sure the client has a portal app Id str_prop = client.properties["pipewire.access.portal.app_id"] if str_prop == nil then Log.info (client, "Portal managed client did not set app_id") return end if str_prop == "" then Log.info (client, "Ignoring portal check for non-sandboxed client") setPermissions (client, true, true) return end app_id = str_prop -- Make sure the client has portal media roles str_prop = client.properties["pipewire.access.portal.media_roles"] if str_prop == nil then Log.info (client, "Portal managed client did not set media_roles") return end media_roles = parseMediaRoles (str_prop) if (media_roles & MEDIA_ROLE_CAMERA) == 0 then Log.info (client, "Ignoring portal check for clients without camera role") return end -- Update permissions allowed = hasPermission (permissions, app_id, "yes") Log.info (client, "setting permissions: " .. tostring(allowed)) setPermissions (client, allowed, allowed) end -- Create portal clients object manager clients_om = ObjectManager { Interest { type = "client", Constraint { "pipewire.access", "=", "portal" }, } } -- Set permissions to portal clients from the permission store if loaded pps_plugin = Plugin.find("portal-permissionstore") if pps_plugin then nodes_om = ObjectManager { Interest { type = "node", Constraint { "media.role", "=", "Camera" }, Constraint { "media.class", "=", "Video/Source" }, } } nodes_om:activate() clients_om:connect("object-added", function (om, client) local new_perms = pps_plugin:call("lookup", "devices", "camera"); updateClientPermissions (client, new_perms) end) nodes_om:connect("object-added", function (om, node) local new_perms = pps_plugin:call("lookup", "devices", "camera"); for client in clients_om:iterate() do updateClientPermissions (client, new_perms) end end) pps_plugin:connect("changed", function (p, table, id, deleted, permissions) if table == "devices" or id == "camera" then for app_id, _ in pairs(permissions) do for client in clients_om:iterate { Constraint { "pipewire.access.portal.app_id", "=", app_id } } do updateClientPermissions (client, permissions) end end end end) else -- Otherwise, just set all permissions to all portal clients clients_om:connect("object-added", function (om, client) local id = client["bound-id"] Log.info(client, "Granting ALL access to client " .. id) client:update_permissions { ["any"] = "all" } end) end clients_om:activate()