mirror of
https://github.com/chatmail/relay.git
synced 2026-05-20 04:48:06 +00:00
make read/write user data atomic
This commit is contained in:
@@ -60,7 +60,7 @@ def is_allowed_to_create(config: Config, user, cleartext_password) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_user_data(db, config: Config, user):
|
def get_user_data(db, config: Config, user, conn=None):
|
||||||
if user == f"echo@{config.mail_domain}":
|
if user == f"echo@{config.mail_domain}":
|
||||||
return dict(
|
return dict(
|
||||||
home=str(config.get_user_maildir(user)),
|
home=str(config.get_user_maildir(user)),
|
||||||
@@ -68,8 +68,12 @@ def get_user_data(db, config: Config, user):
|
|||||||
gid="vmail",
|
gid="vmail",
|
||||||
)
|
)
|
||||||
|
|
||||||
with db.read_connection() as conn:
|
if conn is None:
|
||||||
|
with db.read_connection() as conn:
|
||||||
|
result = conn.get_user(user)
|
||||||
|
else:
|
||||||
result = conn.get_user(user)
|
result = conn.get_user(user)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
result["home"] = str(config.get_user_maildir(user))
|
result["home"] = str(config.get_user_maildir(user))
|
||||||
result["uid"] = "vmail"
|
result["uid"] = "vmail"
|
||||||
@@ -97,17 +101,19 @@ def lookup_passdb(db, config: Config, user, cleartext_password):
|
|||||||
password=encrypt_password(password),
|
password=encrypt_password(password),
|
||||||
)
|
)
|
||||||
|
|
||||||
with db.read_connection() as conn:
|
userdata = get_user_data(db, config, user)
|
||||||
userdata = conn.get_user(user)
|
if userdata:
|
||||||
if userdata:
|
return userdata
|
||||||
userdata["home"] = str(config.get_user_maildir(user))
|
if not is_allowed_to_create(config, user, cleartext_password):
|
||||||
userdata["uid"] = "vmail"
|
return
|
||||||
userdata["gid"] = "vmail"
|
|
||||||
return userdata
|
|
||||||
if not is_allowed_to_create(config, user, cleartext_password):
|
|
||||||
return
|
|
||||||
|
|
||||||
|
# reading and writing user data needs to be atomic
|
||||||
|
# to allow concurrent logins to succeed.
|
||||||
with db.write_transaction() as conn:
|
with db.write_transaction() as conn:
|
||||||
|
userdata = get_user_data(db, config, user, conn=conn)
|
||||||
|
if userdata:
|
||||||
|
return userdata
|
||||||
|
|
||||||
encrypted_password = encrypt_password(cleartext_password)
|
encrypted_password = encrypt_password(cleartext_password)
|
||||||
q = "INSERT INTO users (addr, password) VALUES (?, ?)"
|
q = "INSERT INTO users (addr, password) VALUES (?, ?)"
|
||||||
conn.execute(q, (user, encrypted_password))
|
conn.execute(q, (user, encrypted_password))
|
||||||
|
|||||||
Reference in New Issue
Block a user