diff --git a/Repo-README.-.md b/Repo-README.-.md new file mode 100644 index 0000000..f18db66 --- /dev/null +++ b/Repo-README.-.md @@ -0,0 +1,162 @@ + + +> Mirrored from `/mnt/DATA/git/govoplan-files/README.md`. +> Origin: `repository`. +> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. + +--- +# govoplan-files + + +**Repository type:** module (domain). + + +GovOPlaN Files is the managed file module. It bundles backend storage APIs and the Files WebUI package so file features can be installed as one module. + +## Ownership + +This repository owns: + +- backend module manifest `files` +- file permissions such as `files:file:read`, `files:file:upload`, `files:file:download`, `files:file:organize`, and `files:file:delete` +- file-space, file metadata, share, upload, download, pattern matching, and transfer APIs +- SQLAlchemy file models and module migration registration +- WebUI package `@govoplan/files-webui` +- `/files` route and IconRail navigation contribution + +Core owns auth, tenants, RBAC evaluation, database/session primitives, CSRF/API helpers, and shell layout. + +## Development + +Install through the core environment: + +```bash +cd /mnt/DATA/git/govoplan-core +./.venv/bin/python -m pip install -r requirements-dev.txt +``` + +Run the WebUI from the core host: + +```bash +cd /mnt/DATA/git/govoplan-core/webui +PATH=/home/zemion/.nvm/versions/node/v22.22.3/bin:$PATH /home/zemion/.nvm/versions/node/v22.22.3/bin/npm run dev +``` + +## Module integration + +Backend entry point: + +```toml +[project.entry-points."govoplan.modules"] +files = "govoplan_files.backend.manifest:get_manifest" +``` + +Frontend package: + +```text +@govoplan/files-webui +``` + +The campaign module can integrate with files when both modules are installed, +for example for managed attachment selection and campaign file sharing. Files +does not import campaign internals; campaign share/existence checks use the core +`campaigns.access` capability registered by the campaign module. + +Platform RBAC and governance rules are documented in `govoplan-core/docs/`. + +Managed files can carry source provenance for connector and import workflows. +Upload callers may provide `source_provenance_json` and `source_revision`; the +module stores those values under file metadata, returns normalized +`source_provenance` and `source_revision` fields in file responses, and carries +them into managed campaign attachment matches for frozen execution evidence. + +Connector policy preflight is available through +`POST /api/v1/files/connector-policy/evaluate`, and provenance-bearing uploads +can pass `connector_policy_json` to enforce the same policy before file content +is read. Policy payloads contain ordered `sources`; each source has +`scope_type`, optional `scope_id`, optional `label`, and a `policy` object. The +policy object supports `allow`/`allowlist`/`whitelist` and +`deny`/`denylist`/`blacklist` rules for `connectors`, `providers`, +`external_ids`, `external_paths`, and `external_urls`. Deny rules win across the +hierarchy; allow rules narrow access at each source that defines them. + +Connector endpoint settings are exposed through governed connector profiles. +Profiles can be supplied as JSON through +`GOVOPLAN_FILES_CONNECTOR_PROFILES_JSON`, or from a JSON file path through +`GOVOPLAN_FILES_CONNECTOR_PROFILES_FILE`. Each profile has an `id`, `provider`, +`endpoint_url`, governance `scope_type`/`scope_id`, optional `capabilities`, and +deployment-owned credential references such as `password_env`, `token_env`, or +`secret_ref`. Environment references require an exact name in the deployment-wide +`GOVOPLAN_CONNECTOR_SECRET_ENV_ALLOWLIST`; API-managed profiles cannot select +process environment variables and may use only Files-owned encrypted password or +token values. API-created `secret_ref` values fail closed until Files has an +ownership contract that can confirm provider-side deletion. Legacy external +references are treated as non-owned: deleting a profile or credential detaches +and audits the reference but never passes it to an arbitrary secret provider. +Profile and credential deletion immediately clears encrypted values, credential +identities, deployment references, and private metadata in the same transaction +as the non-secret audit record; an audit failure rolls the deletion back. +`GET /api/v1/files/connectors/profiles` returns only profiles visible to the +current principal (system, tenant, user, group, or accessible campaign scope) and +redacts secret values and environment variable names. Use the returned +`policy_sources` with connector policy preflight before importing files. +`GET /api/v1/files/connectors/providers` exposes provider descriptors for +Seafile, Nextcloud, WebDAV, SMB, NFS, and local filesystem connectors. The +descriptor declares implementation status, optional dependencies, permission +mapping, sync/index strategy, conflict handling, preview behavior, and audit +events so provider coverage remains visible without forcing every optional +protocol dependency to be installed. +`GET /api/v1/files/connectors/profiles/{profile_id}/browse` provides read-only +connector browsing. Browse entries use a shared `library`/`folder`/`file` shape, +run profile policy with the `browse` operation, and support Seafile, +WebDAV/Nextcloud, and SMB when the optional `smb` extra is installed. Seafile +profiles browse libraries and directories via Seafile's read-only API; profiles +can still opt into WebDAV browsing by setting `metadata.webdav_endpoint_url` or +`metadata.browse_protocol` to `webdav`. +`POST /api/v1/files/connectors/profiles/{profile_id}/import` imports a Seafile +or WebDAV/Nextcloud/SMB file into managed storage through the same governance, +conflict handling, source provenance, and connector audit path as direct +uploads. The Seafile provider uses account-token auth and the native file +download-link API; Nextcloud and generic WebDAV profiles use authenticated `GET` +requests against the configured WebDAV endpoint. SMB profiles use +`smb://server[:port]/share[/path]` endpoints and deployment-owned or encrypted +stored credentials through `smbprotocol`. Because that SDK cannot accept a +preconnected socket and may follow DFS referrals to additional hosts, live SMB +access fails closed in both public-only and private-network deployments. It will +remain disabled until every initial connection and referral target can be +policy-validated and pinned. + +The S3 browse/import implementation and S3 managed-storage backend currently +fail closed before creating a `boto3` client. Botocore does not yet use the +GovOPlaN pinned HTTP transport and may manage redirects itself, so neither an +explicit endpoint nor SDK endpoint discovery is allowed until both peer pinning +and redirect revalidation are enforced. + +Destructive Files-module retirement applies the same credential lifecycle before +dropping tables. Every remaining Files-owned encrypted connector secret is +scrubbed and audited first, while legacy non-owned external references are +detached and identified as such in the audit record. Retirement does not claim +or attempt provider-side deletion for references Files cannot prove it owns. + +Local connector development assets live in `dev/connectors/`. The compose stack +boots Nextcloud, Seafile, WebDAV, and SMB endpoints for provider development and +manual interoperability testing. + +Connector and collaboration ownership boundaries are documented in +`docs/CONNECTOR_BOUNDARY.md` and `docs/DOCUMENT_COLLABORATION_BOUNDARY.md`. +The role-adaptive user, administration, integration, and operator guide is the +[Files handbook](docs/FILES_HANDBOOK.md). + +ZIP uploads are processed without buffering the whole archive in memory. The API +spools incoming ZIP request bodies to a bounded temporary file, then extracts +members with per-file and total extracted-size limits before storing managed +files. + +Bulk rename and transfer APIs are owner-scoped: callers must provide the active +user or group file space with `owner_type` and `owner_id`. The storage layer +keeps a named legacy file-only helper for historical callers that lack owner +context, and regression tests cover its write-access checks. + +## Release packaging + +The repository root includes a `package.json` for git-based WebUI installs. It exports the package `@govoplan/files-webui` from `webui/src` so release builds can depend on tagged git refs instead of local `file:` paths.