Skip to content

Conversation

@ajeety4
Copy link
Contributor

@ajeety4 ajeety4 commented Dec 17, 2025

Product Description

Fixes the order of authentication classes for DRF APIs and removes the ununsed TokenAuthentication class

No UI facing change.

Technical Summary

Ticket

Issue
API requests made with an invalid or expired OAuth2 bearer token were returning 403 Forbidden instead of the expected 401 Unauthorized. This made it unclear to API clients that re-authentication was required.

Root Cause
Django REST Framework determines whether to return 401 or 403 based on the first authentication class in DEFAULT_AUTHENTICATION_CLASSES. Previously, SessionAuthentication was listed first. Since session auth does not return a WWW-Authenticate header, DRF downgraded authentication failures to 403, even when OAuth2 authentication was involved.

Fix
Reordered the authentication classes to make OAuth2Authentication the primary mechanism. Also since the TokenAuthentication class is not being used anywhere, it was removed.

"DEFAULT_AUTHENTICATION_CLASSES": (
    "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
    "rest_framework.authentication.SessionAuthentication",
),

This ensures invalid or expired OAuth2 tokens correctly return 401 Unauthorized, while preserving session-based access.

Safety Assurance

Safety story

The order in which authentication happens is modified, with the primary authentication mehtod OAuth2 so the change is quite safe.
Affects DRF APIs.

Automated test coverage

A test case added to ensure correct error is returned.

QA Plan

None

Labels & Review

  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@ajeety4 ajeety4 marked this pull request as ready for review December 17, 2025 13:02
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Walkthrough

Adds a new unauthenticated payment confirmation test, updates the Swagger API docs test to expect HTTP 401 for a normal user, and changes REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES to remove TokenAuthentication and place OAuth2Authentication before SessionAuthentication.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Files to inspect closely:
    • commcare_connect/opportunity/tests/test_api_views.py — new unauthenticated test behavior and fixtures
    • commcare_connect/users/tests/test_swagger.py — changed expected status code
    • config/settings/base.py — modification of REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES (removal of TokenAuthentication and reordering)

Possibly related PRs

Suggested reviewers

  • calellowitz
  • zandre-eng

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: reordering authentication classes in Django REST Framework configuration to prioritize OAuth2 authentication.
Description check ✅ Passed The PR description clearly explains the issue, root cause, fix, and testing approach. It directly addresses the changes made to authentication class ordering and TokenAuthentication removal.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ay/auth-classes-fix-ordering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Charl1996
Copy link
Contributor

Are we using token authentication for any process (i.e. the TokenAuthentication class)? Maybe a question for @calellowitz

@Charl1996
Copy link
Contributor

I'm fine with this PR as is and I think it might work, but @calellowitz made an interesting suggestion on slack which I'm thinking we could explore, ie. to remove the other two auth classes.

To quote Cal:

i am curious how many other views this actually affects though. if this only matters for DRF views, I wonder if the real answer is to just remove the other two auth types from the list (unless there are DRF views that require session auth, like the swagger api docs?)

@ajeety4
Copy link
Contributor Author

ajeety4 commented Dec 18, 2025

I'm fine with this PR as is and I think it might work, but @calellowitz made an interesting suggestion on slack which I'm thinking we could explore, ie. to remove the other two auth classes.

To quote Cal:

i am curious how many other views this actually affects though. if this only matters for DRF views, I wonder if the real answer is to just remove the other two auth types from the list (unless there are DRF views that require session auth, like the swagger api docs?)

Yes, this only matters for DRF views.
I checked, and you are right about Swagger API docs requiring session authentication. I think it is okay to remove TokenAuthentication, but I am not sure if it is used by any other client. I know that both the mobile app and Labs use OAuth2. Is there any other client that consumes the DRF APIs?
FYI @calellowitz

@calellowitz
Copy link
Collaborator

Are we using token authentication for any process (i.e. the TokenAuthentication class)? Maybe a question for @calellowitz

I don't believe we are. We use it (or something similar) in connect-id, but I don't know of any place in this repo

@ajeety4 ajeety4 requested a review from sravfeyn December 22, 2025 06:49
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
Copy link
Member

Choose a reason for hiding this comment

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

The description mentions just re-ordering, however this is removing TokenAuthentication altogether?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the TokenAuthentication is not being used, it has been removed. See comment
Updated the description in that regards. Thanks for catching.

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.

5 participants