From 666924246bf1e6768e9c643157ee727680cca452 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Fri, 13 Jan 2023 21:36:35 +0100
Subject: [PATCH] =?UTF-8?q?Registrace=20pou=C5=BE=C3=ADv=C3=A1=20find=5For?=
 =?UTF-8?q?=5Fcreate=5Fuser?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Tím se zavírá race condition při zakládání řádků v tabulce user.
---
 mo/web/acct.py | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/mo/web/acct.py b/mo/web/acct.py
index d1497402..e54311a2 100644
--- a/mo/web/acct.py
+++ b/mo/web/acct.py
@@ -498,31 +498,23 @@ class Reg2:
         email = mo.users.normalize_email(rr.email)      # Pro jistotu
         sess = db.get_session()
 
-        if db.get_session().query(db.User).with_for_update().filter_by(email=email).one_or_none():
+        try:
+            user, is_new, _ = mo.users.find_or_create_user(email, first_name, last_name, is_org=False, reason='register')
+        except mo.CheckError as e:
+            app.logger.info(f'Reg2: Založení účtu {email} selhalo: {e}')
+            self.status = RegStatus.already_exists
+            return False
+
+        if not is_new:
             # Účet mohl začít existovat mezi 1. a 2. krokem registrace
             app.logger.info(f'Reg2: Účet s e-mailem {email} začal během registrace existovat')
             self.status = RegStatus.already_exists
             return False
 
-        user = db.User(
-            email=email,
-            first_name=first_name,
-            last_name=last_name,
-        )
         mo.users.set_password(user, passwd)
-
+        mo.users.login(user)
         rr.used_at = mo.now
-        sess.add(user)
-        sess.flush()
 
-        app.logger.info(f'Reg2: Založen uživatel user=#{user.user_id} email=<{user.email}>')
-        mo.util.log(
-            type=db.LogType.user,
-            what=user.user_id,
-            details={'action': 'register', 'new': db.row2dict(user)},
-        )
-
-        mo.users.login(user)
         sess.commit()
         self.user = user
         return True
-- 
GitLab