137 lines
4.7 KiB
Python
137 lines
4.7 KiB
Python
# -*- 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 is not None:
|
|
self.user_id = int(user_id)
|
|
self.load()
|
|
else:
|
|
self.login = None
|
|
self.displayname = None
|
|
self.language = 'en'
|
|
self.role = 'undef'
|
|
self.flags = []
|
|
|
|
def load(self, user_id=0):
|
|
sql = (
|
|
"SELECT login, displayname, language, role, flags "
|
|
"FROM user "
|
|
"WHERE userid=%s")
|
|
self.cur.execute(sql, (self.user_id, ))
|
|
row = self.cur.fetchone()
|
|
if row:
|
|
self.data = row
|
|
self.login = row['login']
|
|
self.displayname = row['displayname']
|
|
self.language = row['language']
|
|
self.role = row['role']
|
|
self.flags = row['flags'].split(',') if row['flags'] else []
|
|
else:
|
|
self.data = None
|
|
|
|
def save(self):
|
|
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):
|
|
sql = "UPDATE user SET last_login=NOW() WHERE username=%s"
|
|
self.cur.execute(sql, (self.username, ))
|
|
self.conn.commit()
|
|
|
|
def mark_logout(self):
|
|
sql = "UPDATE user SET last_logout=NOW() WHERE username=%s"
|
|
self.cur.execute(sql, (self.username, ))
|
|
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
|
|
return out
|
|
|
|
def __str__(self):
|
|
# Prettyprint
|
|
out = "User(%d) - %s\n" % (self.user_id, self.displayname)
|
|
out += " F: %s\n" % self.flags
|
|
out += " R: %s\n" % self.role
|
|
out += " L: %s\n" % self.language
|
|
return out
|
|
|