Skip to content

Reset active language and timezone on requests without an org - #260

Open
norkans7 wants to merge 3 commits into
mainfrom
middleware-locale-leak
Open

Reset active language and timezone on requests without an org#260
norkans7 wants to merge 3 commits into
mainfrom
middleware-locale-leak

Conversation

@norkans7

@norkans7 norkans7 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

SetOrgMiddleware activated an org's language and timezone in thread-local state but never restored them, so requests without an org handled by the same worker thread could render with a previous request's locale settings.

This reworks the middleware to save and restore instead of activate and reset:

  • __call__ now wraps request handling in translation.override(...) and timezone.override(...) context managers when the org supplies a language/timezone, falling back to settings.DEFAULT_LANGUAGE for orgs without a configured language. These snapshot the prior thread-local state and restore it after the response is generated, so no state leaks between requests — including the response phase.
  • Requests without an org don't touch language or timezone state at all, so they keep whatever was negotiated earlier in the middleware chain (e.g. by LocaleMiddleware) rather than being forced to settings.LANGUAGE_CODE. This matters because org-less pages (login, org chooser, account management) are exactly the ones where a user's negotiated language would otherwise be stomped.
  • The set_language/set_timezone hook methods that mutated global state are removed.

Tests cover: org state being restored after the response (no leak into subsequent org-less requests on the same thread), a pre-negotiated language surviving an org-less request unchanged, and the default language fallback for orgs without a configured language.

norkans7 added 3 commits July 27, 2026 13:33
Previously SetOrgMiddleware activated an org's language and timezone in
thread-local state but never reset them, so org-less requests handled by
the same thread could render with a previous request's locale settings.
Instead of activating state in process_request and resetting to defaults
on org-less requests, wrap request handling in translation.override and
timezone.override when an org supplies a language/timezone. Prior state
is snapshotted and restored, so nothing leaks between requests on the
same thread and org-less requests keep whatever language was negotiated
earlier in the middleware chain (e.g. by LocaleMiddleware).
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