Remediate the 2026-09-03 feature-test findings
This commit is contained in:
@@ -39,6 +39,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity, current_user
|
||||
from shopdb.api import (
|
||||
db, cache, Setting, client_ip,
|
||||
success_response, error_response, ErrorCodes,
|
||||
caller_holds,
|
||||
)
|
||||
|
||||
from ..models import SecureSecret
|
||||
@@ -155,7 +156,9 @@ def create_secret():
|
||||
ErrorCodes.VALIDATION_ERROR,
|
||||
'Too many links from this address. Try again shortly.',
|
||||
http_code=429)
|
||||
elif not current_user.haspermission('tools.secrets'):
|
||||
# caller_holds, for the same reason as the endpoints elevated gate: a
|
||||
# scoped token is a narrower caller than the person who minted it.
|
||||
elif not caller_holds('tools.secrets'):
|
||||
return error_response(
|
||||
ErrorCodes.FORBIDDEN,
|
||||
'You do not have permission to create secret links.',
|
||||
|
||||
@@ -86,13 +86,21 @@ class ToolsPlugin(BasePlugin):
|
||||
from where, and never who. That is the cost, and it is why this is the
|
||||
only write in the product offered to guests at all.
|
||||
|
||||
tools.view rides along because tools.secrets without it is a page a
|
||||
guest holds permission to use and no way to reach: it gates the nav
|
||||
entry, and the browser tools behind it (codes, conversions) run client
|
||||
side and touch no data at all. Declared explicitly rather than inferred
|
||||
from the .view suffix, which is what the grantable rule now asks for.
|
||||
tools.secrets is NOT here, and that is the fix for a grant that did
|
||||
nothing. Whether a guest may create a secret link is decided by the
|
||||
securesend_allow_guests setting - which fails closed, carries the rate
|
||||
limit, and is read straight from the row rather than the cache. The
|
||||
route never consulted the guest ROLE, so ticking tools.secrets for
|
||||
guests in the role grid was accepted, stored, and ignored: the site
|
||||
looked open and was not, or looked closed and was not. Two mechanisms
|
||||
for one decision, and the setting is the one with the safeguards.
|
||||
|
||||
tools.view stays grantable: it gates the nav entry, and the browser
|
||||
tools behind it (codes, conversions) run client side and touch no data
|
||||
at all. Declared explicitly rather than inferred from the .view suffix,
|
||||
which is what the grantable rule now asks for.
|
||||
"""
|
||||
return ['tools.secrets', 'tools.view']
|
||||
return ['tools.view']
|
||||
|
||||
def get_settings_defaults(self) -> List[dict]:
|
||||
"""The one switch this plugin owns.
|
||||
|
||||
Reference in New Issue
Block a user