Skip to content

Upgrade django-oauth-toolkit 1.7.1 to 3.3.0#376

Merged
cigamit merged 1 commit into
ctrliq:mainfrom
blaipr:feature/django-oauth-toolkit-3
Jun 11, 2026
Merged

Upgrade django-oauth-toolkit 1.7.1 to 3.3.0#376
cigamit merged 1 commit into
ctrliq:mainfrom
blaipr:feature/django-oauth-toolkit-3

Conversation

@blaipr

@blaipr blaipr commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Removes the long-standing django-oauth-toolkit<2.0.0 cap ("breaking changes that will need to be worked out") and upgrades to 3.3.0, working out those changes:

  • Migration 0198 brings the swapped models up to date with the new abstract models. OAuth2AccessToken.token_checksum is added in three stages exactly like django-oauth-toolkit's own 0012_add_token_checksum migration (nullable column → data migration computing checksums for existing tokens → unique + indexed), so existing access tokens keep working. token becomes a TextField. OAuth2Application gains post_logout_redirect_uris, allowed_origins and hash_client_secret.
  • hash_client_secret defaults to False on our model. AWX stores client secrets encrypted (reversible) via OAuth2ClientSecretField, not hashed. django-oauth-toolkit's _check_secret() falls back to constant-time comparison for non-hashed secrets, so existing application client credentials continue to authenticate unchanged, and new secrets keep AWX's encrypted storage (DOT's hashing field is fully overridden by ours).
  • The stale django-oauth-toolkit UPGRADE BLOCKER section in requirements/README.md (which suggested "may be fixable by creating a migration on our end?") is updated — that is what this PR does.
  • oauthlib 3.2.2 → 3.3.1 comes along as DOT 3.3's requirement.

Verified conflict-free against every other open PR via pairwise git merge-tree.

ISSUE TYPE

  • New or Enhanced Feature

COMPONENT NAME

  • API

ASCENDER VERSION

awx: 25.4.1.dev5+gcda0899.d20260610

ADDITIONAL INFORMATION

  • awx-manage migrate applied cleanly to a populated dev database (including DOT's own packaged 0006–0014 migrations for the non-swapped RefreshToken/IDToken models).
  • Full suite against exactly this branch state (unmodified main + only this change), fully clean:
py.test --create-db -n auto --dist=loadfile awx/main/tests/unit awx/main/tests/functional awx/conf/tests awx/sso/tests
3476 passed, 6 skipped
  • Heads-up on suite flakiness seen while validating (pre-existing on unmodified main, unrelated to this PR): the four TransactionTestCase classes commit real rows to the per-worker SQLite DB, and Django's whole-DB FK check_constraints() at rollback-test teardown can trip over the leaked state — the victim test varies with xdist scheduling (test_update_model, test_secret_key_regeneration, test_survey_spec). All victims pass in isolation.
  • Note for whoever merges: if another migration lands before this, 0198 needs renumbering (regenerate with make dbchange).

Removes the long-standing <2.0.0 cap. Migration 0198 brings the swapped
OAuth2 models up to date with the new abstract models:

- OAuth2AccessToken gains token_checksum, added in three stages exactly
  like django-oauth-toolkit's own 0012 migration (nullable column, data
  migration computing checksums for existing tokens, then unique+indexed)
  so existing tokens keep working; token becomes a TextField.
- OAuth2Application gains post_logout_redirect_uris, allowed_origins and
  hash_client_secret.

hash_client_secret defaults to False on our model: AWX stores client
secrets encrypted (reversible) via OAuth2ClientSecretField rather than
hashed, and django-oauth-toolkit's validator falls back to a
constant-time comparison for non-hashed secrets, so existing client
credentials continue to authenticate unchanged.

The stale django-oauth-toolkit UPGRADE BLOCKER note in
requirements/README.md is updated to describe the new state.
@blaipr

blaipr commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the flakiness note in this PR's description: the 'TransactionTestCase classes commit rows / check_constraints trips over leaked state' explanation turned out to be wrong — those classes are innocent (their flush verifiably leaves all tables empty). The real cause is a cross-test mock leak (task.model.objects.get = mock.Mock(...) in six unit tests), found with per-test manager instrumentation and fixed in #388. It accounts for all three failure families, including the orphan-FK teardown error. Nothing to change in this PR; merging #388 first makes the suite deterministic for reviewing it (five consecutive clean 3476-passed validation runs).

@cigamit cigamit 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.

Tested and working.

@cigamit cigamit merged commit 758c014 into ctrliq:main Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants