~homeworkprod/byceps

e1ca961f2d40aabe64b2f7ead02fbe8ec1b3c3c6 — Jochen Kupperschmidt 9 months ago 0575590
Provide session locale to current user, load Babel locale from there
M byceps/application.py => byceps/application.py +5 -0
@@ 56,6 56,7 @@ def create_app(
    set_locale(app.config['LOCALE'])  # Fail if not configured.

    babel = Babel(app)
    babel.locale_selector_func = _get_locale

    # Initialize database.
    db.init_app(app)


@@ 74,6 75,10 @@ def create_app(
    return app


def _get_locale() -> Optional[str]:
    return g.user.locale


def _add_static_file_url_rules(app: Flask) -> None:
    """Add URL rules to for static files."""
    app.add_url_rule(

M byceps/blueprints/common/core/views.py => byceps/blueprints/common/core/views.py +10 -3
@@ 21,7 21,10 @@ from ....util.authorization import (
)
from ....util.framework.blueprint import create_blueprint
from ....util.navigation import Navigation
from ....util.user_session import get_current_user
from ....util.user_session import (
    get_current_user,
    get_locale as get_session_locale,
)

from ...admin.core.authorization import AdminPermission



@@ 86,9 89,11 @@ def provide_app_mode():
    app_mode = config.get_app_mode()
    g.app_mode = app_mode

    locale = get_session_locale()

    if app_mode.is_admin():
        required_permissions = {AdminPermission.access}
        g.user = get_current_user(required_permissions)
        g.user = get_current_user(required_permissions, locale)
    elif app_mode.is_site():
        site_id = config.get_current_site_id()
        site = site_service.get_site(site_id)


@@ 103,4 108,6 @@ def provide_app_mode():
        g.party_id = party_id

        required_permissions = set()
        g.user = get_current_user(required_permissions, party_id=party_id)
        g.user = get_current_user(
            required_permissions, locale, party_id=party_id
        )

M byceps/services/authentication/session/models/current_user.py => byceps/services/authentication/session/models/current_user.py +2 -1
@@ 8,7 8,7 @@ byceps.services.authentication.session.models.current_user

from dataclasses import dataclass
from enum import Enum
from typing import Set
from typing import Optional, Set

from .....services.user.transfer.models import User



@@ 19,6 19,7 @@ class CurrentUser(User):

    authenticated: bool
    permissions: Set[Enum]
    locale: Optional[str]

    def __eq__(self, other) -> bool:
        return (other is not None) and (self.id == other.id)

M byceps/services/authentication/session/service.py => byceps/services/authentication/session/service.py +4 -2
@@ 167,7 167,7 @@ def _record_recent_login(user_id: UserID, occurred_at: datetime) -> None:
ANONYMOUS_USER_ID = UUID('00000000-0000-0000-0000-000000000000')


def get_anonymous_current_user() -> CurrentUser:
def get_anonymous_current_user(locale: Optional[str]) -> CurrentUser:
    """Return an anonymous current user object."""
    return CurrentUser(
        id=ANONYMOUS_USER_ID,


@@ 178,11 178,12 @@ def get_anonymous_current_user() -> CurrentUser:
        is_orga=False,
        authenticated=False,
        permissions=frozenset(),
        locale=locale,
    )


def get_authenticated_current_user(
    user: User, permissions: Set[Enum]
    user: User, permissions: Set[Enum], locale: Optional[str]
) -> CurrentUser:
    """Return an authenticated current user object."""
    return CurrentUser(


@@ 194,4 195,5 @@ def get_authenticated_current_user(
        is_orga=user.is_orga,
        authenticated=True,
        permissions=permissions,
        locale=locale,
    )

M byceps/util/user_session.py => byceps/util/user_session.py +6 -3
@@ 44,20 44,23 @@ def end() -> None:

def get_current_user(
    required_permissions: Set[Enum],
    locale: Optional[str],
    *,
    party_id: Optional[PartyID] = None,
) -> CurrentUser:
    user = get_user(party_id=party_id)

    if user is None:
        return session_service.get_anonymous_current_user()
        return session_service.get_anonymous_current_user(locale)

    permissions = get_permissions_for_user(user.id)

    if not required_permissions.issubset(permissions):
        return session_service.get_anonymous_current_user()
        return session_service.get_anonymous_current_user(locale)

    return session_service.get_authenticated_current_user(user, permissions)
    return session_service.get_authenticated_current_user(
        user, permissions, locale
    )


def get_user(*, party_id: Optional[PartyID] = None) -> Optional[User]:

M tests/integration/services/authentication/test_current_user.py => tests/integration/services/authentication/test_current_user.py +7 -2
@@ 10,7 10,9 @@ from byceps.util.authorization import create_permission_enum


def test_get_anonymous_current_user():
    current_user = session_service.get_anonymous_current_user()
    locale = 'en'

    current_user = session_service.get_anonymous_current_user(locale)

    assert current_user.id == UUID('00000000-0000-0000-0000-000000000000')
    assert current_user.screen_name is None


@@ 20,6 22,7 @@ def test_get_anonymous_current_user():
    assert not current_user.is_orga
    assert not current_user.authenticated
    assert len(current_user.permissions) == 0
    assert current_user.locale == 'en'


def test_get_authenticated_current_user(user):


@@ 28,9 31,10 @@ def test_get_authenticated_current_user(user):
        permission_enum.do_this,
        permission_enum.do_that,
    }
    locale = 'de'

    current_user = session_service.get_authenticated_current_user(
        user, permissions
        user, permissions, locale
    )

    assert current_user.id == user.id


@@ 41,3 45,4 @@ def test_get_authenticated_current_user(user):
    assert not current_user.is_orga
    assert current_user.authenticated
    assert current_user.permissions == permissions
    assert current_user.locale == 'de'