Plug-ins: a grant that can't be removed keeps the module it covers

plugin.install of a module that lists no permissions ignored the result
of removing the id's grant. When grants.json could not be updated, the
formerly approved bytes could still be installed without approval. The
store now gets the old module back, so the grant and the module it
covers stay together. The new module stays when the old one can't be
read back and when grants.json can't be read, since such a file approves
nothing. Deleting the last grant now reports a failure.

plugin.remove had the same fault. It now moves the settings and cache
aside and removes the grant before anything is deleted. When the grant
can't be removed, the folder is moved back, the command returns an
error and the plug-in stays installed.
This commit is contained in:
dotCooCoo
2026-11-08 17:25:09 -08:00
parent 480648d6cf
commit b79e89de1d
5 changed files with 194 additions and 29 deletions
+2 -1
View File
@@ -6570,7 +6570,8 @@ an error naming the permissions needed. The grant is kept with the module's hash
same bytes install again without `grant`, and a module with other bytes has `needsApproval: true` and needs a new
`grant` even when it lists the same permissions. `plugin.install` does not check that a person approved `grant`: it
trusts the client that sends it. `plugin.remove` forgets the grant, and so does installing a module that lists no
permissions under that id: the earlier bytes then need a new `grant`. A
permissions under that id: the earlier bytes then need a new `grant`. When `plugin.remove` can't remove the grant from
the plug-in store, it returns an error and the plug-in stays installed. A
filter without `doc.write` or `state` that returns output needing them gets an error and the document is unchanged.
A plug-in of API level 2 (`api: 2` in its entry) that lists `progress` may report its progress, see Cancel and write
log lines: `notifications/cancelled` makes its `vc_cancelled` return 1, and its log lines go to the server's log
+8 -4
View File
@@ -181,10 +181,14 @@ capability model proposed for PhotoCraft plug-ins
fails as well, the folder holds the new module with the old grant, the grant does not cover that module, and the
plug-in is skipped at the next start until it is approved again. A grant whose hash is not 64 lower-case
hexadecimal digits covers nothing. `plugin.remove` forgets the grant, and so does a successful `plugin.install` of a
module that lists no permissions under that id, so the earlier bytes need a new approval. A refused install leaves
the grant as it is. When such an install can't write the module to the `Plug-ins` folder, the module already stored
there stays and `grants.json` keeps its grant. When VectorCraft loads the `Plug-ins` folder, it forgets any grant
for an id whose stored module lists no permissions. In Safe Mode, and for a stored module that the user disabled,
module that lists no permissions under that id, so the earlier bytes need a new approval. When `plugin.remove` can't
remove the grant from `grants.json`, it returns an error, the plug-in stays installed, and a second `plugin.remove`
tries again. A refused install leaves
the grant as it is. When such an install can't write the module to the `Plug-ins` folder, or can't remove the grant
from `grants.json`, the folder keeps the module it held and `grants.json` keeps the grant. The new module runs until
the session ends. When the grant can't be removed and the module already stored can't be read back, the new module
stays in the folder. A `grants.json` that can't be read grants nothing, and the new module stays in the folder then
too. When VectorCraft loads the `Plug-ins` folder, it forgets any grant for an id whose stored module lists no permissions. In Safe Mode, and for a stored module that the user disabled,
VectorCraft does not read the module, and `grants.json` keeps the grant for its id. The Additional Plug-ins Folder
and `plugin.reload` do not change the `Plug-ins` folder: when they leave a module that lists no permissions under an
id, the process forgets its own grant for that id, and a grant kept in `grants.json` stays with the stored module it