fix login not working after registration #57

Merged
Typhus merged 1 commits from bugfux/fix-login-not-working-after-registration into main 2026-02-23 22:50:42 +00:00
6 changed files with 93 additions and 103 deletions

View File

@ -1 +1 @@
0.3.5 0.3.6

View File

@ -3,6 +3,7 @@ import logging
import sys import sys
from pathlib import Path from pathlib import Path
from uuid import uuid4
from rio import App, Theme, Color, Font, ComponentPage, Session from rio import App, Theme, Color, Font, ComponentPage, Session
from from_root import from_root from from_root import from_root
@ -10,6 +11,7 @@ from from_root import from_root
from src.ezgg_lan_manager import pages, init_services, LocalDataService from src.ezgg_lan_manager import pages, init_services, LocalDataService
from src.ezgg_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard from src.ezgg_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard
from src.ezgg_lan_manager.services.LocalDataService import LocalData from src.ezgg_lan_manager.services.LocalDataService import LocalData
from src.ezgg_lan_manager.types.UserSession import UserSession
logger = logging.getLogger("EzggLanManager") logger = logging.getLogger("EzggLanManager")
@ -33,6 +35,8 @@ if __name__ == "__main__":
lan_info = default_attachments[3].get_lan_info() lan_info = default_attachments[3].get_lan_info()
async def on_session_start(session: Session) -> None: async def on_session_start(session: Session) -> None:
# Use this line to fake being any user without having to log in
session.attach(UserSession(id=uuid4(), user_id=30, is_team_member=True))
await session.set_title(lan_info.name) await session.set_title(lan_info.name)
if session[LocalData].stored_session_token: if session[LocalData].stored_session_token:
user_session = session[LocalDataService].verify_token(session[LocalData].stored_session_token) user_session = session[LocalDataService].verify_token(session[LocalData].stored_session_token)

View File

@ -1,38 +0,0 @@
from asyncio import sleep
from rio import Text, Component, TextStyle
class AnimatedText(Component):
def __post_init__(self) -> None:
self._display_printing: list[bool] = [False]
self.text_comp = Text("")
async def display_text(self, success: bool, text: str, speed: float = 0.06, font_size: float = 0.9) -> None:
if self._display_printing[0]:
return
else:
self._display_printing[0] = True
self.text_comp.text = ""
if success:
self.text_comp.style = TextStyle(
fill=self.session.theme.success_color,
font_size=font_size
)
for c in text:
self.text_comp.text = self.text_comp.text + c
self.text_comp.force_refresh()
await sleep(speed)
else:
self.text_comp.style = TextStyle(
fill=self.session.theme.danger_color,
font_size=font_size
)
for c in text:
self.text_comp.text = self.text_comp.text + c
self.text_comp.force_refresh()
await sleep(speed)
self._display_printing[0] = False
def build(self) -> Component:
return self.text_comp

View File

@ -42,7 +42,7 @@ class CateringSelectionItem(Component):
content=Column( content=Column(
Row( Row(
Text(article_name_top, align_x=0, overflow="wrap", min_width=19, Text(article_name_top, align_x=0, overflow="wrap", min_width=19,
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), strikethrough=not self.is_sensitive), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
Text(AccountingService.make_euro_string_from_decimal(self.article_price), Text(AccountingService.make_euro_string_from_decimal(self.article_price),
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
IconButton( IconButton(
@ -66,8 +66,7 @@ class CateringSelectionItem(Component):
align_x=0, align_x=0,
overflow="wrap", overflow="wrap",
min_width=19, min_width=19,
style=TextStyle(fill=self.session.theme.background_color, font_size=0.6), style=TextStyle(fill=self.session.theme.background_color, font_size=0.6)
strikethrough=not self.is_sensitive
), ),
margin_top=0 margin_top=0
), ),

View File

@ -1,10 +1,10 @@
import logging import logging
from asyncio import sleep, create_task
from email_validator import validate_email, EmailNotValidError from email_validator import validate_email, EmailNotValidError
from rio import Column, Component, event, Text, TextStyle, TextInput, TextInputChangeEvent, Button from rio import Column, Component, event, Text, TextStyle, TextInput, TextInputChangeEvent, Button
from src.ezgg_lan_manager import ConfigurationService, UserService, MailingService from src.ezgg_lan_manager import ConfigurationService, UserService, MailingService
from src.ezgg_lan_manager.components.AnimatedText import AnimatedText
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
MINIMUM_PASSWORD_LENGTH = 6 MINIMUM_PASSWORD_LENGTH = 6
@ -13,125 +13,154 @@ logger = logging.getLogger(__name__.split(".")[-1])
class RegisterPage(Component): class RegisterPage(Component):
pw_1: str = ""
pw_2: str = ""
email: str = ""
user_name: str = ""
pw_1_valid: bool = True
pw_2_valid: bool = True
email_valid: bool = True
submit_button_loading: bool = False
display_text: str = ""
display_text_style: TextStyle = TextStyle()
def on_pw_focus_loss(self, _: TextInputChangeEvent) -> None: def on_pw_focus_loss(self, _: TextInputChangeEvent) -> None:
if not (self.pw_1.text == self.pw_2.text) or len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH: if not (self.pw_1 == self.pw_2) or len(self.pw_1) < MINIMUM_PASSWORD_LENGTH:
self.pw_1.is_valid = False self.pw_1_valid = False
self.pw_2.is_valid = False self.pw_2_valid = False
return return
self.pw_1.is_valid = True self.pw_1_valid = True
self.pw_2.is_valid = True self.pw_2_valid = True
def on_email_focus_loss(self, change_event: TextInputChangeEvent) -> None: def on_email_focus_loss(self, change_event: TextInputChangeEvent) -> None:
try: try:
validate_email(change_event.text, check_deliverability=False) validate_email(change_event.text, check_deliverability=False)
self.email_input.is_valid = True self.email_valid = True
except EmailNotValidError: except EmailNotValidError:
self.email_input.is_valid = False self.email_valid = False
def on_user_name_focus_loss(self, _: TextInputChangeEvent) -> None: def on_user_name_focus_loss(self, _: TextInputChangeEvent) -> None:
current_text = self.user_name_input.text current_text = self.user_name
if len(current_text) > UserService.MAX_USERNAME_LENGTH: if len(current_text) > UserService.MAX_USERNAME_LENGTH:
self.user_name_input.text = current_text[:UserService.MAX_USERNAME_LENGTH] self.user_name = current_text[:UserService.MAX_USERNAME_LENGTH]
async def on_submit_button_pressed(self) -> None: async def on_submit_button_pressed(self) -> None:
self.submit_button.is_loading = True self.submit_button_loading = True
self.submit_button.force_refresh()
if len(self.user_name_input.text) < 1: if len(self.user_name) < 1:
await self.animated_text.display_text(False, "Nutzername darf nicht leer sein!") await self.display_animated_text(False, "Nutzername darf nicht leer sein!")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
if not (self.pw_1.text == self.pw_2.text): if not (self.pw_1 == self.pw_2):
await self.animated_text.display_text(False, "Passwörter stimmen nicht überein!") await self.display_animated_text(False, "Passwörter stimmen nicht überein!")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
if len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH: if len(self.pw_1) < MINIMUM_PASSWORD_LENGTH:
await self.animated_text.display_text(False, f"Passwort muss mindestens {MINIMUM_PASSWORD_LENGTH} Zeichen lang sein!") await self.display_animated_text(False, f"Passwort muss mindestens {MINIMUM_PASSWORD_LENGTH} Zeichen lang sein!")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
if not self.email_input.is_valid or len(self.email_input.text) < 3: if not self.email_valid or len(self.email) < 3:
await self.animated_text.display_text(False, "E-Mail Adresse ungültig!") await self.display_animated_text(False, "E-Mail Adresse ungültig!")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
user_service = self.session[UserService] user_service = self.session[UserService]
mailing_service = self.session[MailingService] mailing_service = self.session[MailingService]
lan_info = self.session[ConfigurationService].get_lan_info() lan_info = self.session[ConfigurationService].get_lan_info()
if await user_service.get_user(self.email_input.text) is not None or await user_service.get_user(self.user_name_input.text) is not None: if await user_service.get_user(self.email) is not None or await user_service.get_user(self.user_name) is not None:
await self.animated_text.display_text(False, "Benutzername oder E-Mail bereits regestriert!") await self.display_animated_text(False, "Benutzername oder E-Mail bereits registriert!")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
try: try:
new_user = await user_service.create_user(self.user_name_input.text, self.email_input.text, self.pw_1.text) new_user = await user_service.create_user(self.user_name, self.email, self.pw_1)
if not new_user: if not new_user:
logger.warning(f"UserService.create_user returned: {new_user}") # ToDo: Seems like the user is created fine, even if not returned #FixMe logger.error(f"create_user returned: {new_user}")
raise Exception(f"create_user returned: {new_user}")
except Exception as e: except Exception as e:
logger.error(f"Unknown error during new user registration: {e}") logger.error(f"Unknown error during new user registration: {e}")
await self.animated_text.display_text(False, "Es ist ein unbekannter Fehler aufgetreten :(") await self.display_animated_text(False, "Es ist ein unbekannter Fehler aufgetreten :(")
self.submit_button.is_loading = False self.submit_button_loading = False
return return
await mailing_service.send_email( await mailing_service.send_email(
subject="Erfolgreiche Registrierung", subject="Erfolgreiche Registrierung",
body=f"Hallo {self.user_name_input.text},\n\n" body=f"Hallo {self.user_name},\n\n"
f"Du hast dich erfolgreich beim EZGG-LAN Manager für {lan_info.name} {lan_info.iteration} registriert.\n\n" f"Du hast dich erfolgreich beim EZGG-LAN Manager für {lan_info.name} {lan_info.iteration} registriert.\n\n"
f"Wenn du dich nicht registriert hast, kontaktiere bitte unser Team über unsere Homepage.\n\n" f"Wenn du dich nicht registriert hast, kontaktiere bitte unser Team über unsere Homepage.\n\n"
f"Liebe Grüße\nDein {lan_info.name} - Team", f"Liebe Grüße\nDein {lan_info.name} - Team",
receiver=self.email_input.text receiver=self.email
) )
self.submit_button.is_loading = False self.submit_button_loading = False
await self.animated_text.display_text(True, "Erfolgreich registriert!") await self.display_animated_text(True, "Erfolgreich registriert!")
@event.on_populate @event.on_populate
async def on_populate(self) -> None: async def on_populate(self) -> None:
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Registrieren") await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Registrieren")
async def display_animated_text(self, success: bool, text: str) -> None:
self.display_text = ""
style = TextStyle(
fill=self.session.theme.success_color if success else self.session.theme.danger_color,
font_size=0.9
)
self.display_text_style = style
_ = create_task(self._animate_text(text))
async def _animate_text(self, text: str) -> None:
for c in text:
self.display_text += c
await sleep(0.06)
def build(self) -> Component: def build(self) -> Component:
self.user_name_input = TextInput( user_name_input = TextInput(
label="Benutzername", label="Benutzername",
text="", text=self.bind().user_name,
margin_left=1, margin_left=1,
margin_right=1, margin_right=1,
margin_bottom=1, margin_bottom=1,
grow_x=True, grow_x=True,
on_lose_focus=self.on_user_name_focus_loss on_lose_focus=self.on_user_name_focus_loss
) )
self.email_input = TextInput( email_input = TextInput(
label="E-Mail Adresse", label="E-Mail Adresse",
text="", text=self.bind().email,
margin_left=1, margin_left=1,
margin_right=1, margin_right=1,
margin_bottom=1, margin_bottom=1,
grow_x=True, grow_x=True,
on_lose_focus=self.on_email_focus_loss on_lose_focus=self.on_email_focus_loss,
is_valid=self.email_valid
) )
self.pw_1 = TextInput( pw_1_input = TextInput(
label="Passwort", label="Passwort",
text="", text=self.bind().pw_1,
margin_left=1, margin_left=1,
margin_right=1, margin_right=1,
margin_bottom=1, margin_bottom=1,
grow_x=True, grow_x=True,
is_secret=True, is_secret=True,
on_lose_focus=self.on_pw_focus_loss on_lose_focus=self.on_pw_focus_loss,
is_valid=self.pw_1_valid
) )
self.pw_2 = TextInput( pw_2_input = TextInput(
label="Passwort wiederholen", label="Passwort wiederholen",
text="", text=self.bind().pw_2,
margin_left=1, margin_left=1,
margin_right=1, margin_right=1,
margin_bottom=1, margin_bottom=1,
grow_x=True, grow_x=True,
is_secret=True, is_secret=True,
on_lose_focus=self.on_pw_focus_loss on_lose_focus=self.on_pw_focus_loss,
is_valid=self.pw_2_valid
) )
self.submit_button = Button( submit_button = Button(
content=Text( content=Text(
"Registrieren", "Registrieren",
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9),
@ -145,13 +174,8 @@ class RegisterPage(Component):
shape="rectangle", shape="rectangle",
style="minor", style="minor",
color=self.session.theme.secondary_color, color=self.session.theme.secondary_color,
on_press=self.on_submit_button_pressed on_press=self.on_submit_button_pressed,
) is_loading=self.submit_button_loading
self.animated_text = AnimatedText(
margin_top=2,
margin_left=1,
margin_right=1,
margin_bottom=2
) )
return Column( return Column(
MainViewContentBox( MainViewContentBox(
@ -166,12 +190,12 @@ class RegisterPage(Component):
margin_bottom=2, margin_bottom=2,
align_x=0.5 align_x=0.5
), ),
self.user_name_input, user_name_input,
self.email_input, email_input,
self.pw_1, pw_1_input,
self.pw_2, pw_2_input,
self.submit_button, submit_button,
self.animated_text Text(self.display_text, margin_top=2, margin_left=1, margin_right=1, margin_bottom=2, style=self.display_text_style)
) )
), ),
align_y=0, align_y=0,

View File

@ -62,7 +62,8 @@ class DatabaseService:
password=self._database_config.db_password, password=self._database_config.db_password,
db=self._database_config.db_name, db=self._database_config.db_name,
minsize=1, minsize=1,
maxsize=40 maxsize=40,
autocommit=True
) )
except aiomysql.OperationalError: except aiomysql.OperationalError:
return False return False