Skip to content

Server mode: selected UI language doesn't persist beyond the request that set it #10347

Description

@dpage

Describe the bug

In server mode, get_locale() (web/pgadmin/__init__.py:308-339) only resolves the correct language on the single request that includes a language field in the POSTed form (e.g. the login form, or the "Miscellaneous > User language" preferences save). On every other request it falls through to English, because its session/cookie fallback is broken:

data = request.form
if 'language' in data:
    language = data['language'] or language
    setattr(session, 'PGADMIN_LANGUAGE', language)
elif hasattr(session, 'PGADMIN_LANGUAGE'):
    language = getattr(session, 'PGADMIN_LANGUAGE', language)
elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'):
    language = getattr(
        request.cookies, 'PGADMIN_LANGUAGE', language
    )
  • session (Flask's SecureCookieSession) and request.cookies (a MultiDict) are dict-likes, not objects that expose their keys as attributes. setattr(session, 'PGADMIN_LANGUAGE', language) sets a plain Python instance attribute that is never merged into the session's actual dict contents, so it's never serialised into the session cookie and doesn't survive past the current request object.
  • hasattr(request.cookies, 'PGADMIN_LANGUAGE') and the matching getattr(...) never succeed either, for the same reason — cookie values live in the dict, not as attributes.

Confirmed with a quick REPL check against flask.sessions.SecureCookieSession and werkzeug.datastructures.ImmutableMultiDict: both hasattr checks are always False, and the setattr value never appears in dict(session).

Net effect: elsewhere in the app (e.g. web/pgadmin/preferences/__init__.py:292-296 and web/pgadmin/browser/__init__.py:454-457) a PGADMIN_LANGUAGE cookie is correctly written to the browser via response.set_cookie(...), but get_locale() can never read it back on subsequent requests, so the UI silently reverts to English as soon as the request no longer includes the language form field.

To Reproduce

  1. Run pgAdmin in server mode with more than one configured LANGUAGES entry.
  2. Log in choosing a non-English language on the login page (or set a non-English language in Preferences > Miscellaneous > User language and save).
  3. Navigate to any other page / reload.
  4. The UI reverts to English rather than staying in the selected language.

Expected behavior

The selected language should persist for the session/browser (via the PGADMIN_LANGUAGE cookie that is already being set correctly elsewhere) across requests, not just the one request that submitted it.

Suggested fix

Read the cookie/session properly, e.g.:

elif 'PGADMIN_LANGUAGE' in session:
    language = session.get('PGADMIN_LANGUAGE', language)
elif 'PGADMIN_LANGUAGE' in request.cookies:
    language = request.cookies.get('PGADMIN_LANGUAGE', language)

and set the session value with session['PGADMIN_LANGUAGE'] = language rather than setattr.

Found while re-verifying #5692 (login page language selection) — the login page itself reads the cookie correctly via request.cookies.get(...) in login_user.html, but this get_locale() path is what governs the language of every other page, and it doesn't work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions