"""The server's side of SaraView's variables: VarEngine.py (shared with the desktop client) with file access that follows the configured roots and the locks, so a portal can't show what you couldn't open yourself.""" from __future__ import annotations from Core import ResolvePath from Explorer import ClassifyFile, ListDirectory from Locks import IsPathAccessible from Preview import ReadTextFile from VarEngine import MarkerPattern, PortalFileTypes # MarkerPattern: Graph.py finds links with it from VarEngine import ResolvePortals as _ResolvePortals from VarEngine import ResolveSpans as _ResolveSpans __all__ = ["MarkerPattern", "ResolvePortals", "ResolveSpans"] class ServerAccess: def __init__(self, RootName: str, Username: str, UserGroups: list[str]): self.RootName = RootName self.Username = Username self.UserGroups = UserGroups def _Allowed(self, RelativePath: str) -> bool: return IsPathAccessible(self.RootName, RelativePath, self.Username, self.UserGroups) def ReadText(self, RelativePath: str) -> str | None: if not self._Allowed(RelativePath): return None try: FilePath = ResolvePath(self.RootName, RelativePath) except ValueError: return None if not FilePath.is_file() or ClassifyFile(FilePath) not in PortalFileTypes: return None try: return ReadTextFile(FilePath) except (OSError, UnicodeDecodeError): return None def List(self, DirectoryPath: str) -> list[dict] | None: if not self._Allowed(DirectoryPath): return None try: Entries = ListDirectory(self.RootName, DirectoryPath, False, False) except (ValueError, NotADirectoryError, FileNotFoundError): return None return [ Entry for Entry in Entries if self._Allowed(f"{DirectoryPath}/{Entry['Name']}" if DirectoryPath else Entry["Name"]) ] def IsDirectory(self, RelativePath: str) -> bool: try: return ResolvePath(self.RootName, RelativePath).is_dir() except ValueError: return False def ResolvePortals(RootName: str, RelativePath: str, Content: str, Username: str, UserGroups: list[str]) -> str: return _ResolvePortals(RelativePath, Content, ServerAccess(RootName, Username, UserGroups)) def ResolveSpans(RootName: str, RelativePath: str, Content: str, Username: str, UserGroups: list[str]) -> list[dict]: return _ResolveSpans(RelativePath, Content, ServerAccess(RootName, Username, UserGroups))