~homeworkprod/byceps

c6301afa56dec2cb58868bd20fb8f6914abdbf36 — Jochen Kupperschmidt 9 months ago 418e9a1
Include site ID in persisted user login event
M byceps/blueprints/admin/user/service.py => byceps/blueprints/admin/user/service.py +8 -0
@@ 19,6 19,7 @@ from ....services.newsletter.transfer.models import List as NewsletterList
from ....services.party import service as party_service
from ....services.party.transfer.models import Party
from ....services.shop.order import service as order_service
from ....services.site import service as site_service
from ....services.ticketing.models.ticket import Ticket as DbTicket
from ....services.ticketing import attendance_service, ticket_service
from ....services.user import event_service


@@ 335,6 336,13 @@ def _get_additional_data(
        }
        yield 'details', details

    if event.event_type == 'user-logged-in':
        site_id = event.data.get('site_id')
        if site_id:
            site = site_service.find_site(site_id)
            if site is not None:
                yield 'site', site


def _get_additional_data_for_user_initiated_event(
    event: DbUserEvent, users_by_id: Dict[str, User]

M byceps/blueprints/admin/user/templates/admin/user/view_events.html => byceps/blueprints/admin/user/templates/admin/user/view_events.html +5 -1
@@ 86,7 86,11 @@
          {%- set icon_name = 'log-in' %}
          {%- set body %}
            <span class="user-link">{{ render_user_avatar_20_and_admin_link(user) }}</span>
            hat sich von IP-Adresse {{ event.data.ip_address }} <strong>erfolgreich angemeldet</strong>.
            hat sich von IP-Adresse {{ event.data.ip_address }} <strong>erfolgreich angemeldet</strong>
            {%- if event.site is defined %}
            auf Site &quot;{{ event.site.title }}&quot;
            {%- endif -%}
            .
          {%- endset %}
        {%- elif event.event == 'user-screen-name-changed' %}
          {%- set icon_name = 'user' %}

M byceps/blueprints/site/authentication/login/views.py => byceps/blueprints/site/authentication/login/views.py +3 -1
@@ 103,7 103,9 @@ def login():

    # Authorization succeeded.

    auth_token = session_service.log_in_user(user.id, request.remote_addr)
    auth_token = session_service.log_in_user(
        user.id, request.remote_addr, site_id=g.site_id
    )
    user_session.start(user.id, auth_token, permanent=permanent)
    flash_success(
        gettext(

M byceps/services/authentication/session/service.py => byceps/services/authentication/session/service.py +10 -3
@@ 14,6 14,7 @@ from uuid import UUID, uuid4
from ....database import db, insert_ignore_on_conflict, upsert
from ....typing import UserID

from ...site.transfer.models import SiteID
from ...user import event_service as user_event_service
from ...user.transfer.models import User



@@ 103,19 104,25 @@ def _is_token_valid_for_user(token: str, user_id: UserID) -> bool:
    return db.session.query(subquery).scalar()


def log_in_user(user_id: UserID, ip_address: str) -> str:
def log_in_user(
    user_id: UserID, ip_address: str, *, site_id: Optional[SiteID] = None
) -> str:
    """Create a session token and record the log in."""
    session_token = get_session_token(user_id)

    create_login_event(user_id, ip_address)
    create_login_event(user_id, ip_address, site_id=site_id)
    record_recent_login(user_id)

    return session_token.token


def create_login_event(user_id: UserID, ip_address: str) -> None:
def create_login_event(
    user_id: UserID, ip_address: str, *, site_id: Optional[SiteID] = None
) -> None:
    """Create an event that represents a user login."""
    data = {'ip_address': ip_address}
    if site_id:
        data['site_id'] = site_id
    user_event_service.create_event('user-logged-in', user_id, data)



M tests/integration/blueprints/site/test_login.py => tests/integration/blueprints/site/test_login.py +5 -2
@@ 21,7 21,7 @@ def test_login_form(client):
    assert response.status_code == 200


def test_login_succeeds(client, make_user):
def test_login_succeeds(site, client, make_user):
    screen_name = 'SiteLoginTester'
    password = 'correct horse battery staple'



@@ 49,7 49,10 @@ def test_login_succeeds(client, make_user):
    login_events_after = event_service.get_events_of_type_for_user(user.id, 'user-logged-in')
    assert len(login_events_after) == 1
    login_event = login_events_after[0]
    assert login_event.data == {'ip_address': '127.0.0.1'}
    assert login_event.data == {
        'ip_address': '127.0.0.1',
        'site_id': site.id,
    }

    assert session_service.find_recent_login(user.id) is not None