Package: manabi
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 argumentpriorto 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.InstallMake sure libsodium exists on the system, for example execute:apkadd--no-cachelibsodium
apt-getinstall-ylibsodium23ConfigCallmanabi-keygenand add the key toconfig["manabi"]["key"]. The key is
shared between the caluma/alexandria backend and the WebDAV server.mount_pathPrefix that gets passed to wsgidav, if URL rewrites remove any prefixes use"/"lock_storageThe ManabiLockLockStorage forces the WebDav log-timeout totoken-refresh-time / 2provider_mappingExtends the FilesystemProvider any will only serve files if the token is validpre_write_hookA hook to enhance the API's capabilities, for example versioning of documents.middleware_stackBased on the default middleware_stack but HTTPAuthenticator is replace by
ManabiAuthenticator, which validates the tokens.manabi.keyShared-key between the server that creates tokens to grant access and wsgi-davmanabi.refreshHow often tokens are refreshed in seconds, we recommend 10 minutes:600manabi.initialThe 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.frommanabiimportManabiDAVApp# All hooks and callbacks are optionalcb_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)DevEnable dev-env:pyenvinstall3.11.4
poetryenvuse$HOME/.pyenv/versions/3.11.4/bin/python3.11
poetryinstall
poetryrunpython-mmanabi.mypy_fix
poetryshell
docker-composeup-ddb(cdmanabi_django&&./manage.pymigratemanabi_migrations)Typing rulesMy typing rules for this project (there are no company rules):In tests# type: ignoreis allowed if fixing the issue does not help production-codeIn production-code# type: ignoreis allowed if a manual check happens or
we can guarantee some runtime behavior. For example we guarantee that a
weakref is always valid. Similar tounsafein rust.