From c8a4bc1820bd6e7338c8bd01e73f25a489e11aba Mon Sep 17 00:00:00 2001 From: "s0wlz (Matthias Puchstein)" Date: Wed, 6 May 2026 15:46:54 +0200 Subject: [PATCH] fix: superadmin course access + navigate to correct course from courses page Backend: list_students, add_student, import_students now bypass tutor_courses check for superadmins, matching the existing pattern in list_assigned_tutors. A superadmin creating a new course was getting 401 when accessing it because no tutor_courses row exists for them. Frontend: courses page passes ?courseId= to students/sessions links; both pages now pre-select the matching course on mount instead of always defaulting to courses[0]. --- backend/src/routes/courses.rs | 15 +++++++++------ frontend/src/routes/admin/courses/+page.svelte | 4 ++-- frontend/src/routes/admin/sessions/+page.svelte | 6 ++++-- frontend/src/routes/admin/students/+page.svelte | 6 ++++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/backend/src/routes/courses.rs b/backend/src/routes/courses.rs index d9c5321..6580a05 100644 --- a/backend/src/routes/courses.rs +++ b/backend/src/routes/courses.rs @@ -126,13 +126,14 @@ async fn list_assigned_tutors( Ok(Json(tutors)) } -// Fix 3: verify tutor has access to this course async fn list_students( claims: TutorClaims, State(pool): State, Path(course_id): Path, ) -> Result>, AppError> { - super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + if !claims.is_superadmin { + super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + } let students = sqlx::query_as::<_, Student>( "SELECT id, course_id, name FROM students WHERE course_id = ? ORDER BY id", ) @@ -142,14 +143,15 @@ async fn list_students( Ok(Json(students)) } -// Fix 3: verify tutor has access to this course async fn add_student( claims: TutorClaims, State(pool): State, Path(course_id): Path, Json(req): Json, ) -> Result<(StatusCode, Json), AppError> { - super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + if !claims.is_superadmin { + super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + } let id = sqlx::query("INSERT INTO students (course_id, name) VALUES (?, ?)") .bind(course_id) .bind(&req.name) @@ -162,14 +164,15 @@ async fn add_student( )) } -// Fix 3 + Fix 4: verify access, validate CSV header, wrap in transaction, size check async fn import_students( claims: TutorClaims, State(pool): State, Path(course_id): Path, mut multipart: Multipart, ) -> Result<(StatusCode, Json), AppError> { - super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + if !claims.is_superadmin { + super::verify_tutor_course_access(&pool, claims.sub, course_id).await?; + } let mut count = 0i64; diff --git a/frontend/src/routes/admin/courses/+page.svelte b/frontend/src/routes/admin/courses/+page.svelte index 39a6b44..884c028 100644 --- a/frontend/src/routes/admin/courses/+page.svelte +++ b/frontend/src/routes/admin/courses/+page.svelte @@ -139,8 +139,8 @@ {/if} diff --git a/frontend/src/routes/admin/sessions/+page.svelte b/frontend/src/routes/admin/sessions/+page.svelte index 455aa3f..0a6e939 100644 --- a/frontend/src/routes/admin/sessions/+page.svelte +++ b/frontend/src/routes/admin/sessions/+page.svelte @@ -1,5 +1,6 @@