Part of #59.
Part of the broken-access-control remediation epic. Depends on Phase 1. These routes authenticate correctly but never check object ownership.
Findings addressed
Definition of Done
Affected files
src/api/handlers/summaries.py, enhancements.py, messaging.py, dashboards.py, advanced_analytics.py
Part of #59.
Part of the broken-access-control remediation epic. Depends on Phase 1. These routes authenticate correctly but never check object ownership.
Findings addressed
summaries.py:104—GET /summaries/{user_id}queriesSummary.student_id == user_idwith no ownership check; the tutor branch trusts a caller-suppliedroleparam. Add ownership/relationship check before the query.enhancements.py:82—get_conversation_contextomits the self-check that its siblingget_conversation_history(:57) already has. Copy that check in.messaging.py:224—GET /messaging/threads?user_id=uses a caller-supplieduser_idinstead of the JWT identity. Reject/ignore auser_idthat isn't the authenticated user (or gate to admin).dashboards.py:29— parent dashboards enforce only role (self-registerable) and return all students. Enforce parent↔student link per Phase 0, or restrict to admin; stop returning all students.advanced_analytics.py:100—engagement/{user_id}returns any student's activity profile to any tutor/parent. Add relationship check or restrict to admin.Definition of Done
403; owner/related/admin still works.dashboardsno longer enumerates all students for non-admins.Affected files
src/api/handlers/summaries.py,enhancements.py,messaging.py,dashboards.py,advanced_analytics.py