add register page

This commit is contained in:
David Rodenkirchen 2024-08-27 00:20:06 +02:00
parent 704184d6f9
commit fe5566749d
4 changed files with 216 additions and 2 deletions

View File

@ -6,7 +6,7 @@ from rio import App, Theme, Color, Font, Page, Session
from from_root import from_root from from_root import from_root
from src.ez_lan_manager import pages, init_services from src.ez_lan_manager import pages, init_services
from src.ez_lan_manager.helpers.LoggedInGuard import logged_in_guard from src.ez_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard
from src.ez_lan_manager.types.SessionStorage import SessionStorage from src.ez_lan_manager.types.SessionStorage import SessionStorage
logger = logging.getLogger(__name__.split(".")[-1]) logger = logging.getLogger(__name__.split(".")[-1])
@ -99,12 +99,14 @@ if __name__ == "__main__":
Page( Page(
name="Register", name="Register",
page_url="register", page_url="register",
build=lambda: pages.PlaceholderPage(placeholder_name="Registrierung"), build=pages.RegisterPage,
guard=not_logged_in_guard
), ),
Page( Page(
name="ForgotPassword", name="ForgotPassword",
page_url="forgot-password", page_url="forgot-password",
build=pages.ForgotPasswordPage, build=pages.ForgotPasswordPage,
guard=not_logged_in_guard
), ),
Page( Page(
name="EditProfile", name="EditProfile",

View File

@ -5,6 +5,12 @@ from rio import Session, URL
from src.ez_lan_manager.types.SessionStorage import SessionStorage from src.ez_lan_manager.types.SessionStorage import SessionStorage
# Guards pages against access from users that are NOT logged in
def logged_in_guard(session: Session, _) -> Optional[URL]: def logged_in_guard(session: Session, _) -> Optional[URL]:
if session[SessionStorage].user_id is None: if session[SessionStorage].user_id is None:
return URL("./") return URL("./")
# Guards pages against access from users that ARE logged in
def not_logged_in_guard(session: Session, _) -> Optional[URL]:
if session[SessionStorage].user_id is not None:
return URL("./")

View File

@ -0,0 +1,205 @@
import logging
from asyncio import sleep
from typing import Optional
from email_validator import validate_email, EmailNotValidError
from rio import Column, Component, event, Text, TextStyle, TextInput, TextInputChangeEvent, Button
from src.ez_lan_manager import ConfigurationService, UserService, MailingService
from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox
from src.ez_lan_manager.pages import BasePage
MINIMUM_PASSWORD_LENGTH = 6
logger = logging.getLogger(__name__.split(".")[-1])
class RegisterPage(Component):
def on_pw_change(self, _: TextInputChangeEvent) -> None:
if not (self.pw_1.text == self.pw_2.text) or len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH:
self.pw_1.is_valid = False
self.pw_2.is_valid = False
return
self.pw_1.is_valid = True
self.pw_2.is_valid = True
def on_email_changed(self, change_event: TextInputChangeEvent) -> None:
try:
validate_email(change_event.text, check_deliverability=False)
self.email_input.is_valid = True
except EmailNotValidError:
self.email_input.is_valid = False
async def on_submit_button_pressed(self) -> None:
self.submit_button.is_loading = True
await self.submit_button.force_refresh()
if len(self.user_name_input.text) < 1:
await self.display_save_result_animation(False, optional_text="Nutzername darf nicht leer sein!")
self.submit_button.is_loading = False
return
if not (self.pw_1.text == self.pw_2.text):
await self.display_save_result_animation(False, optional_text="Passwörter stimmen nicht überein!")
self.submit_button.is_loading = False
return
if len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH:
await self.display_save_result_animation(False, optional_text=f"Passwort muss mindestens {MINIMUM_PASSWORD_LENGTH} Zeichen lang sein!")
self.submit_button.is_loading = False
return
if not self.email_input.is_valid or len(self.email_input.text) < 3:
await self.display_save_result_animation(False, optional_text="E-Mail Adresse ungültig!")
self.submit_button.is_loading = False
return
user_service = self.session[UserService]
mailing_service = self.session[MailingService]
lan_info = self.session[ConfigurationService].get_lan_info()
if user_service.get_user(self.email_input.text) is not None or user_service.get_user(self.user_name_input.text) is not None:
await self.display_save_result_animation(False, optional_text="Benutzername oder E-Mail bereits regestriert!")
self.submit_button.is_loading = False
return
try:
new_user = user_service.create_user(self.user_name_input.text, self.email_input.text, self.pw_1.text)
if not new_user:
raise RuntimeError("User could not be created")
except Exception as e:
logger.error(f"Unknown error during new user registration: {e}")
await self.display_save_result_animation(False, optional_text="Es ist ein unbekannter Fehler aufgetreten :(")
self.submit_button.is_loading = False
return
await mailing_service.send_email(
subject="Erfolgreiche Registrierung",
body=f"Hallo {self.user_name_input.text},\n\n"
f"Du hast dich erfolgreich beim EZ-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"Liebe Grüße\nDein {lan_info.name} - Team",
receiver=self.email_input.text
)
self.submit_button.is_loading = False
await self.display_save_result_animation(True, optional_text="Erfolgreich registriert!")
async def display_save_result_animation(self, success: bool, optional_text: Optional[str] = None) -> None:
self.info_text.text = ""
if success:
self.info_text.style = TextStyle(
fill=self.session.theme.success_color,
font_size=1
)
t = "Gespeichert!" if not optional_text else optional_text
for c in t:
self.info_text.text = self.info_text.text + c
await self.info_text.force_refresh()
await sleep(0.04)
else:
self.info_text.style = TextStyle(
fill=self.session.theme.danger_color,
font_size=1
)
t = "Fehler!" if not optional_text else optional_text
for c in t:
self.info_text.text = self.info_text.text + c
await self.info_text.force_refresh()
await sleep(0.04)
@event.on_populate
async def on_populate(self) -> None:
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Registrieren")
def build(self) -> Component:
self.user_name_input = TextInput(
label="Benutzername",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True
)
self.email_input = TextInput(
label="E-Mail Adresse",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
on_change=self.on_email_changed
)
self.pw_1 = TextInput(
label="Passwort",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
is_secret=True,
on_change=self.on_pw_change
)
self.pw_2 = TextInput(
label="Passwort wiederholen",
text="",
margin_left=1,
margin_right=1,
margin_bottom=1,
grow_x=True,
is_secret=True,
on_change=self.on_pw_change
)
self.submit_button = Button(
content=Text(
"Registrieren",
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9),
align_x=0.5
),
grow_x=True,
margin_top=2,
margin_left=1,
margin_right=1,
margin_bottom=1,
shape="rectangle",
style="minor",
color=self.session.theme.secondary_color,
on_press=self.on_submit_button_pressed
)
self.info_text = Text(
text="",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=1
),
margin_top=2,
margin_left=1,
margin_right=1,
margin_bottom=2,
wrap=True
)
return BasePage(
content=Column(
MainViewContentBox(
content=Column(
Text(
"Neues Konto anlegen",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=1.2
),
margin_top=2,
margin_bottom=2,
align_x=0.5
),
self.user_name_input,
self.email_input,
self.pw_1,
self.pw_2,
self.submit_button,
self.info_text
)
),
align_y=0,
)
)

View File

@ -5,3 +5,4 @@ from .Logout import LogoutPage
from .Account import AccountPage from .Account import AccountPage
from .EditProfile import EditProfilePage from .EditProfile import EditProfilePage
from .ForgotPassword import ForgotPasswordPage from .ForgotPassword import ForgotPasswordPage
from .RegisterPage import RegisterPage