Promote the 2026-08-30 review security fixes and supplies ordering to main

This commit is contained in:
2026-08-31 09:24:13 -04:00
parent 6680c3c5de
commit 0e3d5a6226
30 changed files with 991 additions and 98 deletions

View File

@@ -107,17 +107,24 @@ class BasePlugin(ABC):
def get_guest_grantable_permissions(self) -> List[str]:
"""Permissions this plugin allows a site to grant to the GUEST role.
A guest is anyone with no account. Any `.view` or `.read` permission is
grantable without asking a plugin - reading is the safe default. This
hook is for the exception: a WRITE that is genuinely meant to be usable
by somebody who never signs in.
A guest is anyone with no account. EVERY permission of this plugin's
that a site may grant one has to be named here, reads included.
Reads used to be automatic: anything ending `.view` or `.read` was
grantable. That treats a name as a decision, and it went wrong in the
obvious way - permissions that gated installer bytes, backup payloads
and a search across the staff directory were all anonymous-grantable
because of how they were spelled. So the plugin that owns a permission
now says, having looked at what its routes return.
Naming one here does not open it. It makes the checkbox available in
the role grid; a site still has to tick it. Return [] (the default) and
none of this plugin's writes can ever be made anonymous.
nothing of this plugin's can be made anonymous.
The bar: could this action be attributed to nobody, forever, and still
be defensible in the audit log? If not, leave it out.
The bar for a read: could an anonymous visitor hold this, forever, and
would the site be content with everything the routes return - every
column of every serializer, not just the ones the UI happens to show?
For a write, add that the act can never be attributed to anybody.
"""
return []