User management with native gui and further improvements
This commit is contained in:
+37
-34
@@ -163,26 +163,25 @@
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="lvw_user">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="tvw_user">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<signal name="row-activated" handler="on_tvw_user_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -191,11 +190,12 @@
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<object class="GtkButton" id="but_user_new">
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="on_but_user_new_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
@@ -204,11 +204,12 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<object class="GtkButton" id="but_user_del">
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="on_but_user_del_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
@@ -220,7 +221,7 @@
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
@@ -262,7 +263,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<object class="GtkEntry" id="ent_user_login">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
</object>
|
||||
@@ -272,7 +273,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<object class="GtkEntry" id="ent_user_displayname">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
</object>
|
||||
@@ -304,7 +305,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox">
|
||||
<object class="GtkComboBox" id="cmb_user_role">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
@@ -314,7 +315,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox">
|
||||
<object class="GtkComboBox" id="cmb_user_lang">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
@@ -335,7 +336,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<object class="GtkEntry" id="ent_user_pass">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
</object>
|
||||
@@ -345,11 +346,12 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<object class="GtkButton" id="but_user_newpass">
|
||||
<property name="label" translatable="yes">Create</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="on_but_user_newpass_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
@@ -357,7 +359,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<object class="GtkCheckButton" id="chk_user_locked">
|
||||
<property name="label" translatable="yes">Locked</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
@@ -370,7 +372,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<object class="GtkCheckButton" id="chk_user_deleted">
|
||||
<property name="label" translatable="yes">Deleted</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
@@ -446,11 +448,12 @@
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<object class="GtkButton" id="but_user_save">
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="on_but_user_save_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
@@ -480,7 +483,7 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Lists</property>
|
||||
<property name="label" translatable="yes">User</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
@@ -560,7 +563,7 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">User</property>
|
||||
<property name="label" translatable="yes">Lists</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
@@ -846,7 +849,7 @@
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkTreeView" id="tvw_equipment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
@@ -1831,7 +1834,7 @@
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkTreeView" id="tvw_provisions">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
@@ -2040,7 +2043,7 @@
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkTreeView" id="tvw_maintenance">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
@@ -2270,7 +2273,7 @@
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkTreeView" id="tvw_projects">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
@@ -2500,7 +2503,7 @@
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkTreeView" id="tvw_documents">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
|
||||
+78
-9
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user