slides: grantable slides.manage permission for non-admin curators

This commit is contained in:
2026-07-29 08:41:53 -04:00
parent 02147827f0
commit eeae042aa8
8 changed files with 106 additions and 10 deletions

View File

@@ -23,3 +23,67 @@ def test_slides_feed_unknown_surface_falls_back(client, db):
resp = client.get('/api/slides/feed?surface=../etc')
assert resp.status_code == 200
assert resp.get_json()['surface'] == 'lobby'
# ---------------------------------------------------------------------------
# Management routes are gated on the slides.manage permission (both surfaces).
# A curator role holding it works without full admin; auth alone does not.
# ---------------------------------------------------------------------------
def _headers_for(client, username, password):
resp = client.post('/api/auth/login',
json={'username': username, 'password': password})
assert resp.status_code == 200, f'Login failed: {resp.get_json()}'
return {'Authorization': f"Bearer {resp.get_json()['data']['access_token']}"}
def test_slides_manage_requires_permission(client, db):
"""Authenticated but permission-less user cannot list slides (403)."""
from werkzeug.security import generate_password_hash
from shopdb.core.models import User
user = User(username='plainuser', email='plain@test.local',
passwordhash=generate_password_hash('testpass'))
db.session.add(user)
db.session.commit()
resp = client.get('/api/slides/lobby',
headers=_headers_for(client, 'plainuser', 'testpass'))
assert resp.status_code == 403
def test_slides_manage_curator_allowed(client, db):
"""A non-admin role holding slides.manage can reach the management routes."""
from werkzeug.security import generate_password_hash
from shopdb.core.models import User, Role, Permission
perm = Permission(name='slides.manage',
description='Manage lobby display and screensaver slides',
category='slides')
role = Role(rolename='slidecurator', description='Slide curator')
role.permissions.append(perm)
db.session.add_all([perm, role])
db.session.flush()
user = User(username='curator', email='curator@test.local',
passwordhash=generate_password_hash('testpass'))
user.roles.append(role)
db.session.add(user)
db.session.commit()
headers = _headers_for(client, 'curator', 'testpass')
# The login payload advertises the permission to the frontend authStore.
login = client.post('/api/auth/login',
json={'username': 'curator', 'password': 'testpass'})
assert 'slides.manage' in login.get_json()['data']['user']['permissions']
# And the management route is reachable (200, not 403).
resp = client.get('/api/slides/lobby', headers=headers)
assert resp.status_code == 200
def test_slides_manage_admin_allowed(client, db, auth_headers):
"""Admin keeps access via the require_permission admin bypass."""
resp = client.get('/api/slides/lobby', headers=auth_headers)
assert resp.status_code == 200