Secure send: guests by setting, and a custom view count

This commit is contained in:
2026-08-21 15:53:42 -04:00
parent 21af2731f3
commit 0b4a1db842
4 changed files with 247 additions and 24 deletions

View File

@@ -54,21 +54,44 @@ class ToolsPlugin(BasePlugin):
return [SecureSecret]
def get_permissions(self) -> List:
"""One permission, on CREATING a secret only.
"""Who may CREATE a secret, when guests are not allowed.
There is deliberately no read permission: the recipient usually has no
account here, and the unguessable token is what authorises the read.
Gating that side would make the tool useless for the case it exists for -
handing somebody a credential while you are on a call with them.
The default access model: signed in, and holding this. Reading needs no
permission at all - the recipient usually has no account here and the
unguessable token is the authorisation.
No delete permission either. A secret is spent by being read or by
expiring, and both remove the row; a hand-delete route would only add a
way to destroy the record of a secret that had not been read yet.
A site that turns on securesend_allow_guests bypasses this for people
with no account; it still applies to anyone who IS signed in, so a
member without it cannot create one while a guest can. That is
deliberate: opening the door to guests is a decision about the door, not
about revoking what a role does or does not hold.
"""
return [
('tools.secrets', 'Create secure send links', 'tools'),
]
def get_settings_defaults(self) -> List[dict]:
"""The one switch this plugin owns.
Public so the create page can read it BEFORE login and show a guest the
form rather than a sign-in wall. It says nothing sensitive: whether the
door is open is visible to anyone who tries the door.
"""
return [
{
'key': 'securesend_allow_guests',
'value': 'false',
'valuetype': 'boolean',
'category': 'tools',
'public': True,
'description': ('Let people with no account create secure send '
'links. Off by default: a guest secret has no '
'creator, so the audit trail can say when and '
'from where but never who. Receiving a secret '
'never needs an account either way.'),
},
]
def get_navigation_items(self) -> List[dict]:
return [
{