From bd371dfcf27d00e79e0a1cd0002469817d15be4b Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Sat, 18 Dec 2021 01:56:52 +0100 Subject: [PATCH] fix(users): Register: validate `mail`, handle duplicated `userid`, only send password mail if `mail` was set --- flaschengeist/controller/userController.py | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/flaschengeist/controller/userController.py b/flaschengeist/controller/userController.py index c2ca7f2..059edc2 100644 --- a/flaschengeist/controller/userController.py +++ b/flaschengeist/controller/userController.py @@ -1,4 +1,5 @@ import secrets +import re from io import BytesIO from sqlalchemy import exc from flask import current_app @@ -214,29 +215,40 @@ def delete_user(user: User): db.session.commit() -def register(data): +def register(data, passwd=None): + """Register a new user + Args: + data: dictionary containing valid user properties + passwd: optional a password, default: 16byte random + """ allowed_keys = User().serialize().keys() values = {key: value for key, value in data.items() if key in allowed_keys} roles = values.pop("roles", []) if "birthday" in data: values["birthday"] = from_iso_format(data["birthday"]).date() + if "mail" in data and not re.match(r"[^@]+@[^@]+\.[^@]+", data["mail"]): + raise BadRequest("Invalid mail given") user = User(**values) set_roles(user, roles) - password = secrets.token_urlsafe(16) + password = passwd if passwd else secrets.token_urlsafe(16) current_app.config["FG_AUTH_BACKEND"].create_user(user, password) - db.session.add(user) - db.session.commit() + try: + db.session.add(user) + db.session.commit() + except exc.IntegrityError: + raise BadRequest("userid already in use") - reset = _generate_password_reset(user) + if user.mail: + reset = _generate_password_reset(user) - subject = str(config["MESSAGES"]["welcome_subject"]).format(name=user.display_name, username=user.userid) - text = str(config["MESSAGES"]["welcome_text"]).format( - name=user.display_name, - username=user.userid, - password_link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}', - ) - messageController.send_message(messageController.Message(user, text, subject)) + subject = str(config["MESSAGES"]["welcome_subject"]).format(name=user.display_name, username=user.userid) + text = str(config["MESSAGES"]["welcome_text"]).format( + name=user.display_name, + username=user.userid, + password_link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}', + ) + messageController.send_message(messageController.Message(user, text, subject)) find_user(user.userid)