chore: sync GovOPlaN module split state

This commit is contained in:
2026-07-10 12:51:21 +02:00
parent 18e6c3eb9b
commit 13fd7fc3bd
50 changed files with 12678 additions and 1109 deletions

View File

@@ -0,0 +1,145 @@
from __future__ import annotations
from dataclasses import dataclass
from importlib.util import find_spec
CONNECTOR_PROVIDER_CAPABILITY = "files.connector.providers"
@dataclass(frozen=True, slots=True)
class ConnectorProviderDescriptor:
provider: str
label: str
protocol: str
implemented: bool
browse_supported: bool
import_supported: bool
optional_dependency: str | None
permission_model: str
sync_strategy: str
conflict_strategy: str
preview_strategy: str
audit_events: tuple[str, ...]
notes: str | None = None
def to_response(self) -> dict[str, object]:
return {
"provider": self.provider,
"label": self.label,
"protocol": self.protocol,
"implemented": self.implemented,
"installed": self.installed,
"browse_supported": self.browse_supported,
"import_supported": self.import_supported,
"optional_dependency": self.optional_dependency,
"permission_model": self.permission_model,
"sync_strategy": self.sync_strategy,
"conflict_strategy": self.conflict_strategy,
"preview_strategy": self.preview_strategy,
"audit_events": list(self.audit_events),
"notes": self.notes,
}
@property
def installed(self) -> bool:
if self.optional_dependency is None:
return self.implemented
return find_spec(self.optional_dependency) is not None
def connector_provider_descriptors() -> tuple[ConnectorProviderDescriptor, ...]:
freeze_model = "Imported or synced connector files become managed GovOPlaN files with frozen blob/version provenance."
governed_permissions = "GovOPlaN profile scope and connector policy are enforced before browse/import/sync; remote ACLs are still evaluated by the upstream service."
return (
ConnectorProviderDescriptor(
provider="seafile",
label="Seafile",
protocol="seafile-api",
implemented=True,
browse_supported=True,
import_supported=True,
optional_dependency=None,
permission_model=governed_permissions,
sync_strategy="On-demand browse/import/sync; sync updates the managed file version when source content changes and never mutates the remote source.",
conflict_strategy="Managed import/sync uses existing files conflict_strategy handling: reject, overwrite, or rename.",
preview_strategy="Previews are generated from the frozen managed file after import or sync.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Native account-token API for libraries, directories, file detail, and download-link import; WebDAV opt-in remains available.",
),
ConnectorProviderDescriptor(
provider="nextcloud",
label="Nextcloud",
protocol="webdav",
implemented=True,
browse_supported=True,
import_supported=True,
optional_dependency=None,
permission_model=governed_permissions,
sync_strategy="On-demand WebDAV browse/import/sync; sync updates the managed file version when source content changes and never mutates the remote source.",
conflict_strategy="Managed import/sync uses existing files conflict_strategy handling: reject, overwrite, or rename.",
preview_strategy="Previews are generated from the frozen managed file after import or sync.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Uses the configured Nextcloud WebDAV endpoint, basic auth, or bearer token profile credentials.",
),
ConnectorProviderDescriptor(
provider="webdav",
label="WebDAV",
protocol="webdav",
implemented=True,
browse_supported=True,
import_supported=True,
optional_dependency=None,
permission_model=governed_permissions,
sync_strategy="On-demand WebDAV browse/import/sync; sync updates the managed file version when source content changes and never mutates the remote source.",
conflict_strategy="Managed import/sync uses existing files conflict_strategy handling: reject, overwrite, or rename.",
preview_strategy="Previews are generated from the frozen managed file after import or sync.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Generic WebDAV provider for standards-compatible stores.",
),
ConnectorProviderDescriptor(
provider="smb",
label="SMB",
protocol="smb",
implemented=True,
browse_supported=True,
import_supported=True,
optional_dependency="smbprotocol",
permission_model=governed_permissions,
sync_strategy="On-demand browse/import/sync over administrator-declared shares; sync updates managed versions and never mutates the remote share.",
conflict_strategy="Managed import/sync uses existing files conflict_strategy handling after download.",
preview_strategy="Previews are generated from the frozen managed file after import or sync, not directly from the share.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Requires the optional smbprotocol dependency and an smb://server[:port]/share[/path] profile endpoint.",
),
ConnectorProviderDescriptor(
provider="nfs",
label="NFS",
protocol="nfs",
implemented=False,
browse_supported=False,
import_supported=False,
optional_dependency=None,
permission_model=governed_permissions,
sync_strategy="Planned optional provider over administrator-mounted paths or a sidecar service.",
conflict_strategy="Will use managed import conflict_strategy handling after download.",
preview_strategy="Will preview from frozen managed file after import, not directly from the mount.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Kept optional because NFS availability is deployment and host-kernel dependent.",
),
ConnectorProviderDescriptor(
provider="local",
label="Local filesystem",
protocol="file",
implemented=False,
browse_supported=False,
import_supported=False,
optional_dependency=None,
permission_model="Local connector access should be restricted to administrator-declared roots plus GovOPlaN profile and policy checks.",
sync_strategy="Planned optional provider; managed storage local backend already exists separately.",
conflict_strategy=freeze_model,
preview_strategy="Will preview from frozen managed file after import or sync.",
audit_events=("files.connector.imported", "files.connector.synced", "files.connector.accessed"),
notes="Separate from the existing managed-file local storage backend.",
),
)