Skip to main content

Provide WebDAV access for documents.

Project description

Manabi

  ┌───────────┐             ┌───────────┐
  │           │   Token     │           │
  │   Manabi  ├────────────►│    API    │
  │           │   Hook      │           │
  └───────────┘             └─────┬─────┘
        ▲                         │
        │                         │ doc API
WebDAV  │  PUT                    │
        │                   Token │
        │  Token                  ▼
 ┌──────┴──────┐           ┌─────────────┐
 │             │   Token   │             │
 │  Word / LO  │◄──────────┤  Frontend   │
 │             │    Link   │             │
 └─────────────┘           └─────────────┘

Case: Users should have the capability to edit documents in Word and LibreOffice.

Problem: We need to ensure the integrity and authenticity of the WebDAV link passed to Word/LO, confirming that it has not been tampered with or generated by an unauthorized third party.

Solution:

  • The API generates an ephemeral branca token. This token is a temporary and short-lived cryptographic token that contains the file-path as an encrypted payload.
  • Both the API and Manabi share a key. In a symmetric shared-key scenario, encryption can also be employed to verify the data.
  • The frontend displays a link that includes the ephemeral token along with the document, allowing users to easily edit it in Word/LO.
  • When the user clicks the link, the document opens in Word/LO.
  • Manabi retrieves the token from the request URI, checks its validity, and proceeds to open the document if the token is verified.
  • The token is updated and stored as a cookie within Word/LO for future reference.
  • Due to the ephemeral WebDAV lock, Word/LO must regularly contact Manabi to refresh the lock. Consequently, we leverage this mechanism to also refresh the token.

cb_hook_config: We provide an optional write-hooks/callbacks feature that enhances the API's capabilities by adding a versioning system. The pre-write- hook/callback is invoked with the token as an argument prior to the document being saved using WebDAV-PUT. The API has the ability to verify this token and subsequently create a new version of the document. Once the hook operation is successfully completed, Manabi takes over and saves the document. Manabi then continues and invokes the post-write-hook/callback.

Install

Make sure libsodium exists on the system, for example execute:

apk add --no-cache libsodium
apt-get install -y libsodium23

Config

Call manabi-keygen and add the key to config["manabi"]["key"]. The key is shared between the caluma/alexandria backend and the WebDAV server.

mount_path

Prefix that gets passed to wsgidav, if URL rewrites remove any prefixes use "/"

lock_storage

The ManabiLockLockStorage forces the WebDav log-timeout to token-refresh-time / 2

provider_mapping

Extends the FilesystemProvider any will only serve files if the token is valid

pre_write_hook

A hook to enhance the API's capabilities, for example versioning of documents.

middleware_stack

Based on the default middleware_stack but HTTPAuthenticator is replace by ManabiAuthenticator, which validates the tokens.

manabi.key

Shared-key between the server that creates tokens to grant access and wsgi-dav

manabi.refresh

How often tokens are refreshed in seconds, we recommend 10 minutes: 600

manabi.initial

The time from the token being generated till it has to be refreshed the first time, we recommend 1 minues: 60. In case tokens leak, for example via cache on a computer, tokens should be expired by the time an adversary gets them.

from manabi import ManabiDAVApp

# All hooks and callbacks are optional
cb_hook_config = CallbackHookConfig(
    pre_write_hook=_pre_write_hook,
    pre_write_callback=_pre_write_callback,
    post_write_hook=_post_write_hook,
    post_write_callback=_post_write_callback,
)

postgres_dsn = "dbname=manabi user=manabi host=localhost password=manabi"
config = {
    "mount_path": "/dav",
    "lock_storage": ManabiDbLockStorage(refresh, postgres_dsn),
    "provider_mapping": {
        "/": ManabiProvider(settings.MEDIA_ROOT, cb_hook_config=cb_hook_config),
    },
    "middleware_stack": [
        WsgiDavDebugFilter,
        ErrorPrinter,
        ManabiAuthenticator,
        WsgiDavDirBrowser,
        RequestResolver,
    ],
    "manabi": {
        "key": key,
        "refresh": refresh,
        "initial": settings.MANABI_TOKEN_ACTIVATE_TIMEOUT,
    },
}
dav_app = ManabiDAVApp(config)

Dev

Enable dev-env:

pyenv install 3.11.4
poetry env use $HOME/.pyenv/versions/3.11.4/bin/python3.11
poetry install
poetry run python -m manabi.mypy_fix
poetry shell
docker-compose up -d db
(cd manabi_django && ./manage.py migrate manabi_migrations)

Typing rules

My typing rules for this project (there are no company rules):

  • In tests # type: ignore is allowed if fixing the issue does not help production-code
  • In production-code # type: ignore is allowed if a manual check happens or we can guarantee some runtime behavior. For example we guarantee that a weakref is always valid. Similar to unsafe in rust.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

manabi-1.4.0.tar.gz (31.0 kB view hashes)

Uploaded Source

Built Distribution

manabi-1.4.0-py3-none-any.whl (32.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page