Commit c39e7960 authored by Frédéric Mangano-Tarumi's avatar Frédéric Mangano-Tarumi Committed by Lukas Fleischer
Browse files

Build a translation facility for FastAPI


Signed-off-by: Lukas Fleischer's avatarLukas Fleischer <lfleischer@archlinux.org>
parent 30f0366d
...@@ -16,3 +16,25 @@ class Translator: ...@@ -16,3 +16,25 @@ class Translator:
self._localedir, self._localedir,
languages=[lang]) languages=[lang])
return self._translator[lang].gettext(s) return self._translator[lang].gettext(s)
def get_translator_for_request(request):
"""
Determine the preferred language from a FastAPI request object and build a
translator function for it.
Example:
```python
_ = get_translator_for_request(request)
print(_("Hello"))
```
"""
lang = request.cookies.get("AURLANG")
if lang is None:
lang = aurweb.config.get("options", "default_lang")
translator = Translator()
def translate(message):
return translator.translate(message, lang)
return translate
...@@ -14,6 +14,7 @@ from starlette.requests import Request ...@@ -14,6 +14,7 @@ from starlette.requests import Request
import aurweb.config import aurweb.config
import aurweb.db import aurweb.db
from aurweb.l10n import get_translator_for_request
from aurweb.schema import Bans, Sessions, Users from aurweb.schema import Bans, Sessions, Users
router = fastapi.APIRouter() router = fastapi.APIRouter()
...@@ -46,13 +47,13 @@ def is_account_suspended(conn, user_id): ...@@ -46,13 +47,13 @@ def is_account_suspended(conn, user_id):
return row is not None and bool(row[0]) return row is not None and bool(row[0])
def open_session(conn, user_id): def open_session(request, conn, user_id):
""" """
Create a new user session into the database. Return its SID. Create a new user session into the database. Return its SID.
""" """
# TODO Handle translations.
if is_account_suspended(conn, user_id): if is_account_suspended(conn, user_id):
raise HTTPException(status_code=403, detail='Account suspended') _ = get_translator_for_request(request)
raise HTTPException(status_code=403, detail=_('Account suspended'))
# TODO This is a terrible message because it could imply the attempt at # TODO This is a terrible message because it could imply the attempt at
# logging in just caused the suspension. # logging in just caused the suspension.
# TODO apply [options] max_sessions_per_user # TODO apply [options] max_sessions_per_user
...@@ -81,25 +82,26 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)): ...@@ -81,25 +82,26 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)):
Receive an OpenID Connect ID token, validate it, then process it to create Receive an OpenID Connect ID token, validate it, then process it to create
an new AUR session. an new AUR session.
""" """
# TODO Handle translations
if is_ip_banned(conn, request.client.host): if is_ip_banned(conn, request.client.host):
_ = get_translator_for_request(request)
raise HTTPException( raise HTTPException(
status_code=403, status_code=403,
detail='The login form is currently disabled for your IP address, ' detail=_('The login form is currently disabled for your IP address, '
'probably due to sustained spam attacks. Sorry for the ' 'probably due to sustained spam attacks. Sorry for the '
'inconvenience.') 'inconvenience.'))
token = await oauth.sso.authorize_access_token(request) token = await oauth.sso.authorize_access_token(request)
user = await oauth.sso.parse_id_token(request, token) user = await oauth.sso.parse_id_token(request, token)
sub = user.get("sub") # this is the SSO account ID in JWT terminology sub = user.get("sub") # this is the SSO account ID in JWT terminology
if not sub: if not sub:
raise HTTPException(status_code=400, detail="JWT is missing its `sub` field.") _ = get_translator_for_request(request)
raise HTTPException(status_code=400, detail=_("JWT is missing its `sub` field."))
aur_accounts = conn.execute(select([Users.c.ID]).where(Users.c.SSOAccountID == sub)) \ aur_accounts = conn.execute(select([Users.c.ID]).where(Users.c.SSOAccountID == sub)) \
.fetchall() .fetchall()
if not aur_accounts: if not aur_accounts:
return "Sorry, we don’t seem to know you Sir " + sub return "Sorry, we don’t seem to know you Sir " + sub
elif len(aur_accounts) == 1: elif len(aur_accounts) == 1:
sid = open_session(conn, aur_accounts[0][Users.c.ID]) sid = open_session(request, conn, aur_accounts[0][Users.c.ID])
response = RedirectResponse("/") response = RedirectResponse("/")
# TODO redirect to the referrer # TODO redirect to the referrer
response.set_cookie(key="AURSID", value=sid, httponly=True, response.set_cookie(key="AURSID", value=sid, httponly=True,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment