Skip to content

Check authorization as default#920

Merged
abcampo-iry merged 5 commits into
mainfrom
check_authorization_as_default
Jul 10, 2026
Merged

Check authorization as default#920
abcampo-iry merged 5 commits into
mainfrom
check_authorization_as_default

Conversation

@abcampo-iry

@abcampo-iry abcampo-iry commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Status

Points for consideration:

  • Security

    • Enables CanCanCan check_authorization for API controllers so actions fail closed if they complete without an explicit CanCan authorization decision.
    • Public/non-resource endpoints are explicitly annotated with action-scoped skip_authorization_check.
    • This guard confirms that authorization happened, but endpoint-specific specs are still needed to prove the correct resource/action is authorized.
  • Performance

    • Minimal expected impact.
    • Adds lightweight after-action authorization verification.
    • A few endpoints now perform explicit CanCan checks, using existing loaded resources or scoped objects.

What's changed?

  • Enabled CanCanCan check_authorization in ApiController.
  • Added explicit skip_authorization_check only: annotations for intentionally public or non-resource API actions.
  • Added missing CanCan authorization checks to audited API actions that read or mutate protected resources.
  • Added authenticated ability rules for user jobs and teacher invitations.
  • Added a regression spec proving an unaudited API action raises CanCan::AuthorizationNotPerformed.

@cla-bot cla-bot Bot added the cla-signed label Jul 9, 2026
@abcampo-iry abcampo-iry marked this pull request as ready for review July 9, 2026 12:43
Copilot AI review requested due to automatic review settings July 9, 2026 12:43

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bb6438f. Configure here.

Comment thread app/controllers/api/teacher_invitations_controller.rb

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR tightens authorization enforcement across ApiController by enabling CanCan’s check_authorization, adds explicit authorize! calls where needed, and introduces targeted skip_authorization_check for endpoints where CanCan is not the access boundary.

Changes:

  • Enforce “fail closed” authorization by adding check_authorization to ApiController and handling CanCan::AuthorizationNotPerformed.
  • Add abilities for authenticated users (UserJobs + TeacherInvitations) and update controllers to call authorize!.
  • Add skip_authorization_check to public/utility endpoints and GraphQL execution.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
spec/requests/api_controller_spec.rb Adds coverage for actions that don’t perform CanCan authorization.
app/models/ability.rb Adds authenticated abilities for reading UserJobs and reading/accepting TeacherInvitations.
app/controllers/graphql_controller.rb Skips controller-level authorization enforcement for GraphQL execute.
app/controllers/api_controller.rb Enables check_authorization and rescues AuthorizationNotPerformed.
app/controllers/api/user_jobs_controller.rb Adds explicit authorization for index/show and refactors job lookup.
app/controllers/api/teacher_invitations_controller.rb Adds CanCan authorization for invitation show/accept.
app/controllers/api/subscriptions_controller.rb Skips CanCan enforcement for public subscription create endpoint.
app/controllers/api/projects/remixes_controller.rb Adds explicit authorization for remix index access.
app/controllers/api/project_errors_controller.rb Skips CanCan enforcement for public error intake endpoint.
app/controllers/api/profile_auth_check_controller.rb Skips CanCan enforcement for token-check utility endpoint.
app/controllers/api/my_school_controller.rb Adds explicit authorization when reading the user’s school.
app/controllers/api/lessons/batch_controller.rb Adds authorization call for the “blank lesson_projects” path.
app/controllers/api/join_controller.rb Skips CanCan enforcement for join-code flow handled elsewhere.
app/controllers/api/features_controller.rb Skips CanCan enforcement for public feature discovery endpoint.
app/controllers/api/events_controller.rb Skips CanCan enforcement for telemetry endpoint gated by authorize_user.
app/controllers/api/default_projects_controller.rb Skips CanCan enforcement for public template endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spec/requests/api_controller_spec.rb
Comment thread app/controllers/api/teacher_invitations_controller.rb
Comment thread app/controllers/api_controller.rb
Comment thread app/models/ability.rb
Comment thread app/controllers/api/user_jobs_controller.rb
@abcampo-iry abcampo-iry marked this pull request as draft July 9, 2026 16:35
@abcampo-iry abcampo-iry marked this pull request as ready for review July 9, 2026 16:40
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Test coverage

92.18% line coverage reported by SimpleCov.
Run: https://github.com/RaspberryPiFoundation/editor-api/actions/runs/29077302208

@raspberrypiherokubot raspberrypiherokubot temporarily deployed to editor-api-p-check-auth-ntaorn July 9, 2026 16:44 Inactive

@zetter-rpf zetter-rpf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! I feel a lot safer having this in place

Add action-scoped skip_authorization_check calls for API endpoints that are intentionally public or use a non-resource access boundary.

Keep each skip limited with only: so future actions in the same controllers still need an explicit authorization decision.
Add CanCan authorization checks to API actions that read or mutate protected resources and were not already making a controller-level authorization decision.

Add authenticated ability rules for user jobs and teacher invitations so those checks preserve the existing ownership and email-match boundaries.
Turn on CanCanCan check_authorization for ApiController so actions cannot silently complete without a CanCan authorization decision.

Preserve existing ApiController error-handling specs with an explicit skip and add a regression spec for an unguarded action raising CanCan::AuthorizationNotPerformed.
Return a generic body when AuthorizationNotPerformed can be rendered safely, while still re-raising after a response has already been performed.

Make invitation email authorization nil-safe and preserve the existing user-job 404 contract for jobs owned by another user.

Add regression coverage for the generic missing-authorization response, nil invitation emails, and cross-user job lookups.
It accurately covers the new allowed and forbidden visibility cases.
@abcampo-iry abcampo-iry force-pushed the check_authorization_as_default branch from b4f5bca to cc2964e Compare July 10, 2026 07:38
@abcampo-iry abcampo-iry merged commit eac5197 into main Jul 10, 2026
5 checks passed
@abcampo-iry abcampo-iry deleted the check_authorization_as_default branch July 10, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants