146 lines
7.3 KiB
Python
146 lines
7.3 KiB
Python
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.",
|
|
),
|
|
)
|