Plugins: the hello example
The smallest plugin of Vumlo (ADR-0066): a Python
file with no dependencies. For every submitted work it counts the words and posts a report that
staff read at GET /api/v1/submissions/{id}/plugin-reports.
- Set
VUMLO__PLUGINS__SECRET_KEY(32 characters or more) where the server andvumlo-clirun. - Start the plugin with no credentials, so the core can read its manifest:
PORT=9000 python3 plugin.py - Install it and approve what it asks for:
vumlo-cli plugin install http://127.0.0.1:9000 --grant submissions:read,reports:writeIt prints a token and a secret, once. - Stop the plugin and start it with them:
PORT=9000 VUMLO_API=http://127.0.0.1:8080/api/v1 VUMLO_PLUGIN_TOKEN=... VUMLO_WEBHOOK_SECRET=... python3 plugin.py - A student submits; within a few seconds the report is there.
It also has a page. Every assignment gets a tab Words (the address gains &tab=hello); a teacher sees how
many words were submitted for it in all, a student is told the numbers are for teachers. How it works, for a
plugin of your own:
- The page is shown in a frame that has no cookie and no access to the web app, so it cannot ask the API
anything as the person looking. It sends
{type: "vumlo.ready", v: 1}to its parent and gets backvumlo.context: the assignment, alaunchtoken, thetheme, thelanguageandtokens, the design tokens of the web app, which it sets on its:rootand draws with (var(--text),var(--accent), …). - Its own server learns who is looking from the launch token, which the core signed with the webhook secret:
payload.signature, wheresignatureis the HMAC-SHA256 of"vumlo-launch." + payload. Seelaunch_claims. Check the signature,expandplugin; never trust the assignment or the role the page says, only the token. - The page sends
vumlo.resizewith its height. The frame’s origin isnull, so the page’s server answers its calls with CORS; the page sends its own strict CSP (this one hashes its script and style). - Set
VUMLO_ORIGINto the origin of the web app so that nobody else can frame the page, andPUBLIC_URLif the core reaches the plugin by an address other thanhttp://127.0.0.1:PORT.
vumlo-cli plugin disable hello stops the events and refuses the token at once; the tab is gone the next time
the web app loads its list of pages (a tab that is still open can no longer get a launch token).
python3 plugin.py --check-vector checks its signature and launch-token code against the vectors the core’s tests use.
The code is plugin.py, a single file. The design of plugins, with what a plugin may and may not do, is in ADR-0066.
Version v0.4.1. This page on GitHub