Skip to content

Refactor permissions logic with Pundit gem and write policies for user roles#367

Open
cycomachead wants to merge 1 commit intomainfrom
cycomachead/71-refactor-permissions-with-pundit/1
Open

Refactor permissions logic with Pundit gem and write policies for user roles#367
cycomachead wants to merge 1 commit intomainfrom
cycomachead/71-refactor-permissions-with-pundit/1

Conversation

@cycomachead
Copy link
Copy Markdown
Contributor

General Info

Changes

This PR replaces the existing ad-hoc role-checking logic scattered across controllers with a centralized, policy-based authorization system using the Pundit gem.

Why

The previous approach used manual @role == 'instructor' checks and custom before_action guard methods in individual controllers. This was inconsistent, hard to test in isolation, and didn't correctly handle the leadta role (lead TAs were silently denied access to actions they should have been permitted to perform due to a bug in Course#user_role).

What Changed

Bug Fix

  • Course#user_role now correctly maps leadta to 'instructor', fixing a regression where lead TAs were denied all access.

Authorization Architecture

  • Added pundit gem and pundit-matchers for testing
  • Included Pundit::Authorization in ApplicationController with a centralized rescue_from Pundit::NotAuthorizedError handler
  • Created 6 policy classes (CoursePolicy, RequestPolicy, CourseSettingsPolicy, FormSettingPolicy, AssignmentPolicy, UserToCoursePolicy) with an ApplicationPolicy base

Controller Refactoring

  • Removed custom before_action guards (ensure_instructor_role, check_instructor_permission, ensure_course_admin) from CourseSettingsController, FormSettingsController, RequestsController, and UserToCoursesController
  • Replaced inline role checks with authorize calls in CoursesController, AssignmentsController, and RequestsController
  • Fixed CoursesController#index to include leadta in the staff courses query

Permissions Matrix

Action Site Admin Teacher Lead TA Regular TA Student
View/import course page
View course Own only
Edit course settings
Delete course
View enrollments
Toggle extended circumstances
Sync assignments/enrollments
Approve/reject requests
Toggle assignment enabled
Edit form settings
Manage own requests

Testing

Added comprehensive policy specs in spec/policies/ covering all user roles (site admin, teacher, lead TA, regular TA, student, unenrolled) for every policy action using pundit-matchers. Also added :as_leadta and :as_ta factory traits to spec/factories/user_to_course.rb to support the new specs.

Existing controller specs should continue to pass as the authorization behavior is preserved — only the implementation mechanism has changed.

Documentation

No external documentation required. The policy classes are self-documenting and the permissions matrix above captures the intended behavior.

Checklist

  • Name of branch corresponds to story

Superconductor Ticket Implementation | App Preview | Guided Review

Refactor permissions logic using the Pundit gem to replace manual role
checks. This introduces a granular policy-based system to manage
permissions for site admins, teachers, lead TAs, regular TAs, and students.

- Add Pundit and pundit-matchers gems
- Create policies for Courses, Requests, Assignments, and Settings
- Update controllers to use `authorize` calls
- Fix Course model to correctly identify lead TAs as instructors
- Add comprehensive policy specs for all user roles

Co-authored-by: Claude Code <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant