User management with native gui and further improvements

This commit is contained in:
2026-08-17 10:37:19 +02:00
parent 41556cfe73
commit a3c8b4083d
24 changed files with 1004 additions and 159 deletions
+78 -9
View File
@@ -1,13 +1,20 @@
# -*- coding: utf-8 -*-
import MySQLdb.cursors
import bcrypt
import random
import string
class User(object):
@classmethod
def genpass(cls, length=12):
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
def __init__(self, dbconn, user_id=None):
self.conn = dbconn
self.cur = dbconn.cursor(MySQLdb.cursors.DictCursor)
if user_id:
if user_id is not None:
self.user_id = int(user_id)
self.load()
else:
@@ -15,13 +22,13 @@ class User(object):
self.displayname = None
self.language = 'en'
self.role = 'undef'
self.flags = ''
self.flags = []
def load(self):
def load(self, user_id=0):
sql = (
"SELECT login, displayname, language, role, flags "
"FROM user "
"WHERE user_id=%s")
"WHERE userid=%s")
self.cur.execute(sql, (self.user_id, ))
row = self.cur.fetchone()
if row:
@@ -30,15 +37,32 @@ class User(object):
self.displayname = row['displayname']
self.language = row['language']
self.role = row['role']
self.flags = row['flags']
self.flags = row['flags'].split(',') if row['flags'] else []
else:
self.data = None
def save(self):
"""
Speichern eines Benutzers ist momentan nicht vorgesehen
"""
pass
fields = ('login', 'displayname', 'language', 'role')
sqlfield = []
values = []
for field in fields:
newdata = getattr(self, field)
if self.data[field] != newdata:
sqlfield.append(f"{field}=%s")
values.append(newdata)
self.data[field] = newdata
# flags set handled separately
newflags = ','.join(self.flags) if self.flags else None
if self.data['flags'] != newflags:
sqlfield.append(f"flags=%s")
values.append(newflags)
self.data['flags'] = newflags
if values:
# only save if changed values exist
sql = "UPDATE user SET " + ",".join(sqlfield) + " WHERE userid=%s"
values.append(self.user_id)
self.cur.execute(sql, values)
self.conn.commit()
""" unused at the moment
def mark_login(self):
@@ -52,6 +76,51 @@ class User(object):
self.conn.commit()
"""
def create(self):
"""
Creates a new user with the first free id > 0
The role is the lowest possible one
"""
sql = (
"SELECT MIN(u1.userid+1) AS newid "
"FROM user AS u1 LEFT JOIN user AS u2 ON u2.userid=u1.userid+1 "
"WHERE u1.userid>=0 AND u2.userid IS NULL")
self.cur.execute(sql)
newid = self.cur.fetchone()['newid']
self.user_id = newid
# TODO check if login is unused else create other name
# add function for that feature
self.login = f"user{newid}"
self.displayname = f"User #{newid}"
self.language = 'en'
self.role = 'sailor'
self.flags = None
sql = (
"INSERT INTO user (userid, login, pass, displayname, role, flags, language) "
"VALUES (%s,%s,%s,%s,%s,%s,%s)"
)
cryptpass = bcrypt.hashpw(self.genpass().encode(), bcrypt.gensalt())
self.cur.execute(sql, (newid, self.login, cryptpass, self.displayname, self.role, self.flags, self.language))
# create mandatory settings
sql = "INSERT INTO settings (userid, sno, valint) VALUES (%s, 1, 0)"
self.cur.execute(sql, (newid,))
self.conn.commit()
return newid
def delete(self):
sql = "DELETE FROM settings WHERE userid=%s"
self.cur.execute(sql, (self.user_id,))
sql = "DELETE FROM user WHERE userid=%s"
self.cur.execute(sql, (self.user_id,))
self.conn.commit()
def setpass(self, newpass):
sql = "UPDATE user SET pass=%s WHERE userid=%s"
cryptpass = bcrypt.hashpw(newpass.encode(), bcrypt.gensalt())
print(cryptpass, self.user_id)
self.cur.execute(sql, (cryptpass, self.user_id))
self.conn.commit()
def __repr__(self):
# Unique description
out = "User(%d)" % self.user_id