add optional permissions filter

This commit is contained in:
Peter Bieringer
2026-02-22 12:27:14 +01:00
parent be16a41681
commit 54e33d8ca2

View File

@@ -20,11 +20,12 @@ import logging
import posixpath import posixpath
import sys import sys
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from typing import Optional from typing import Optional, Union
from radicale import (auth, config, hook, httputils, pathutils, rights, from radicale import (auth, config, hook, httputils, pathutils, rights,
storage, types, utils, web, xmlutils) storage, types, utils, web, xmlutils)
from radicale.log import logger from radicale.log import logger
from radicale.rights import intersect
# HACK: https://github.com/tiran/defusedxml/issues/54 # HACK: https://github.com/tiran/defusedxml/issues/54
import defusedxml.ElementTree as DefusedET # isort:skip import defusedxml.ElementTree as DefusedET # isort:skip
@@ -106,15 +107,19 @@ class Access:
permissions: str permissions: str
_rights: rights.BaseRights _rights: rights.BaseRights
_parent_permissions: Optional[str] _parent_permissions: Optional[str]
_permissions_filter: Union[str | None] = None
def __init__(self, rights: rights.BaseRights, user: str, path: str def __init__(self, rights: rights.BaseRights, user: str, path: str, permissions_filter: Union[str | None] = None
) -> None: ) -> None:
self._rights = rights self._rights = rights
self.user = user self.user = user
self.path = path self.path = path
self.parent_path = pathutils.unstrip_path( self.parent_path = pathutils.parent_path(path)
posixpath.dirname(pathutils.strip_path(path)), True)
self.permissions = self._rights.authorization(self.user, self.path) self.permissions = self._rights.authorization(self.user, self.path)
if permissions_filter is not None:
self._permissions_filter = permissions_filter
permissions_filtered = intersect(self.permissions, permissions_filter)
self.permissions = permissions_filtered
self._parent_permissions = None self._parent_permissions = None
@property @property
@@ -124,6 +129,9 @@ class Access:
if self._parent_permissions is None: if self._parent_permissions is None:
self._parent_permissions = self._rights.authorization( self._parent_permissions = self._rights.authorization(
self.user, self.parent_path) self.user, self.parent_path)
if self._permissions_filter is not None:
parent_permissions_filtered = intersect(self._parent_permissions, self._permissions_filter)
self._parent_permissions = parent_permissions_filtered
return self._parent_permissions return self._parent_permissions
def check(self, permission: str, def check(self, permission: str,