Compare commits
27 Commits
2f38b14a71
...
main
Author | SHA1 | Date | |
---|---|---|---|
651d7e198c | |||
ba3da19b69 | |||
309d60e3d7 | |||
9bd0825a66 | |||
cc8e861859 | |||
94d13bb245 | |||
e184874163 | |||
f9dcf49ae1 | |||
0fc26b1900 | |||
159792c008 | |||
1f61f877fe | |||
048eea106e | |||
274549f04b | |||
8a09d27bf4 | |||
6398dcdf1b | |||
155a86ab06 | |||
87229a654e | |||
879ee79a90 | |||
2da5591e0e | |||
93796f613a | |||
b56b687f73 | |||
e1411e5890 | |||
a55017b23d | |||
9862e1c553 | |||
d120cc63b8 | |||
dac0fea952 | |||
45ad63fe3c |
@@ -1,87 +0,0 @@
|
|||||||
import sqlite3
|
|
||||||
from models.database import Database
|
|
||||||
|
|
||||||
class User:
|
|
||||||
def __init__(self, connection : sqlite3.Connection, id = None, username = None, firstname = None, lastname = None, address = None, zipcode = None, city_id = None, email = None, phone = None, password = None, role = None):
|
|
||||||
self.connection = connection
|
|
||||||
self.id = id
|
|
||||||
self.username = username
|
|
||||||
self.firstname = firstname
|
|
||||||
self.lastname = lastname
|
|
||||||
self.address = address
|
|
||||||
self.zipcode = zipcode
|
|
||||||
self.city_id = city_id
|
|
||||||
self.email = email
|
|
||||||
self.phone = phone
|
|
||||||
self.password = password
|
|
||||||
self.role = role
|
|
||||||
|
|
||||||
def load_by_id(self):
|
|
||||||
cur = Database.connection.cursor()
|
|
||||||
row = cur.execute("SELECT * FROM users WHERE id = ?", (self.id,)).fetchone()
|
|
||||||
|
|
||||||
if row == None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self._set_row_values(row)
|
|
||||||
|
|
||||||
cur.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def load_by_username(self):
|
|
||||||
cur = Database.connection.cursor()
|
|
||||||
row = cur.execute("SELECT * FROM users WHERE username = ?", (self.username,)).fetchone()
|
|
||||||
|
|
||||||
if row == None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self._set_row_values(row)
|
|
||||||
|
|
||||||
cur.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
cur = Database.connection.cursor()
|
|
||||||
cur.execute("""
|
|
||||||
INSERT INTO users
|
|
||||||
(id, username, fistname, lastname, address, zipcode, city_id, email, phone, password, role) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
""", (self.id, self.username, self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role))
|
|
||||||
|
|
||||||
Database.connection.commit()
|
|
||||||
cur.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
cur = Database.connection.cursor()
|
|
||||||
cur.execute("""
|
|
||||||
UPDATE users SET
|
|
||||||
username = ?,
|
|
||||||
fistname = ?,
|
|
||||||
lastname = ?,
|
|
||||||
address = ?,
|
|
||||||
zipcode = ?,
|
|
||||||
city_id = ?,
|
|
||||||
email = ?,
|
|
||||||
phone = ?,
|
|
||||||
password = ?,
|
|
||||||
role = ?,
|
|
||||||
WHERE id = ?
|
|
||||||
""", (self.username, self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, self.id))
|
|
||||||
|
|
||||||
Database.connection.commit()
|
|
||||||
cur.close()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _set_row_values(self, row):
|
|
||||||
self.id = row[0]
|
|
||||||
self.username = row[1]
|
|
||||||
self.firstname = row[2]
|
|
||||||
self.lastname = row[3]
|
|
||||||
self.address = row[4]
|
|
||||||
self.zipcode = row[5]
|
|
||||||
self.city_id = row[6]
|
|
||||||
self.email = row[7]
|
|
||||||
self.phone = row[8]
|
|
||||||
self.password = row[9]
|
|
||||||
self.role = row[10]
|
|
||||||
|
|
@@ -1,9 +0,0 @@
|
|||||||
from models.database import Database
|
|
||||||
from models.user import User
|
|
||||||
|
|
||||||
class Auth:
|
|
||||||
def check_auth(username, password):
|
|
||||||
user = User(Database.connection, None, username)
|
|
||||||
if user.load_by_username() and user.password == password:
|
|
||||||
return user
|
|
||||||
return None
|
|
@@ -1,6 +1,10 @@
|
|||||||
|
from venv import create
|
||||||
from models.utils import DatabaseUtils
|
from models.utils import DatabaseUtils
|
||||||
from models.database import Database
|
from models.database import Database
|
||||||
|
from services.search import Search
|
||||||
|
from ui.input_menu import InputMenu
|
||||||
from views.login_menu import LoginMenu
|
from views.login_menu import LoginMenu
|
||||||
|
from services.log import LogService
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
Database.init()
|
Database.init()
|
@@ -1,7 +1,7 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
class City:
|
class City:
|
||||||
def __init__(self, connection : sqlite3.Connection, id, name):
|
def __init__(self, connection : sqlite3.Connection, id = None, name = None):
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -45,7 +45,7 @@ class City:
|
|||||||
cur = self.connection.cursor()
|
cur = self.connection.cursor()
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
UPDATE cities SET
|
UPDATE cities SET
|
||||||
name = ?,
|
name = ?
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
""", (self.name, self.id))
|
""", (self.name, self.id))
|
||||||
|
|
||||||
@@ -53,6 +53,14 @@ class City:
|
|||||||
cur.close()
|
cur.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
cur.execute("""DELETE FROM cities WHERE id = ?""", (self.id))
|
||||||
|
self.connection.commit()
|
||||||
|
cur.close()
|
||||||
|
return True
|
||||||
|
|
||||||
def _set_row_values(self, row):
|
def _set_row_values(self, row):
|
||||||
self.id = row[0]
|
self.id = row[0]
|
||||||
self.name = row[1]
|
self.name = row[1]
|
||||||
|
return self
|
@@ -16,6 +16,14 @@ class Database:
|
|||||||
Database._init_user_table()
|
Database._init_user_table()
|
||||||
Database._init_city_table()
|
Database._init_city_table()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_tables():
|
||||||
|
cursor = Database.connection.cursor()
|
||||||
|
cursor.execute("DROP TABLE logs")
|
||||||
|
cursor.execute("DROP TABLE users")
|
||||||
|
cursor.execute("DROP TABLE cities")
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _init_log_table():
|
def _init_log_table():
|
||||||
cursor = Database.connection.cursor()
|
cursor = Database.connection.cursor()
|
||||||
@@ -27,7 +35,7 @@ class Database:
|
|||||||
time TEXT,
|
time TEXT,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
additional_information TEXT,
|
additional_information TEXT,
|
||||||
suspicious BOOL
|
suspicious BOOLEAN
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
cursor.close()
|
cursor.close()
|
||||||
@@ -47,7 +55,8 @@ class Database:
|
|||||||
email TEXT,
|
email TEXT,
|
||||||
phone TEXT,
|
phone TEXT,
|
||||||
password TEXT,
|
password TEXT,
|
||||||
role TEXT
|
role TEXT,
|
||||||
|
created TEXT
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
cursor.close()
|
cursor.close()
|
@@ -1,5 +1,5 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
from services.encryption import Encryption
|
||||||
|
|
||||||
class Log:
|
class Log:
|
||||||
def __init__(self, connection : sqlite3.Connection, id = None, username = None, date = None, time = None, description = None, additional_information = None, suspicious = None):
|
def __init__(self, connection : sqlite3.Connection, id = None, username = None, date = None, time = None, description = None, additional_information = None, suspicious = None):
|
||||||
@@ -26,36 +26,29 @@ class Log:
|
|||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
cur = self.connection.cursor()
|
cur = self.connection.cursor()
|
||||||
|
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
INSERT INTO logs
|
INSERT INTO logs
|
||||||
(id, username, date, time, description, additional_information, suspicious) VALUES (?, ?, ?, ?, ?, ?, ?)
|
(id, username, date, time, description, additional_information, suspicious) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
""", (self.id, self.username, self.date, self.time, self.description, self.additional_information, self.suspicious))
|
""", (self.id, Encryption.encrypt(self.username), Encryption.encrypt(self.date), Encryption.encrypt(self.time), Encryption.encrypt(self.description), Encryption.encrypt(self.additional_information), self.suspicious))
|
||||||
|
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self):
|
def delete(self):
|
||||||
cur = self.connection.cursor()
|
cur = self.connection.cursor()
|
||||||
cur.execute("""
|
cur.execute("""DELETE FROM logs WHERE id = ?""", (self.id))
|
||||||
UPDATE logs SET
|
|
||||||
username = ?,
|
|
||||||
date = ?,
|
|
||||||
description = ?,
|
|
||||||
additional_information = ?,
|
|
||||||
suspicious = ?,
|
|
||||||
WHERE id = ?
|
|
||||||
""", (self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, self.id))
|
|
||||||
|
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
cur.close()
|
cur.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _set_row_values(self, row):
|
def _set_row_values(self, row):
|
||||||
self.id = row[0]
|
self.id = row[0]
|
||||||
self.username = row[1]
|
self.username = Encryption.decrypt(row[1])
|
||||||
self.date = row[2]
|
self.date = Encryption.decrypt(row[2])
|
||||||
self.time = row[3]
|
self.time = Encryption.decrypt(row[3])
|
||||||
self.description = row[4]
|
self.description = Encryption.decrypt(row[4])
|
||||||
self.additional_information = row[5]
|
self.additional_information = Encryption.decrypt(row[5])
|
||||||
self.suspicious = row[6]
|
self.suspicious = row[6]
|
||||||
|
return self
|
104
src/models/user.py
Normal file
104
src/models/user.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import sqlite3
|
||||||
|
from datetime import datetime
|
||||||
|
from models.database import Database
|
||||||
|
from services.encryption import Encryption
|
||||||
|
|
||||||
|
class User:
|
||||||
|
def __init__(self, connection : sqlite3.Connection, id = None, username = None, firstname = None, lastname = None, address = None, zipcode = None, city_id = None, email = None, phone = None, password = None, role = None):
|
||||||
|
self.connection = connection
|
||||||
|
self.id = id
|
||||||
|
self.username = username
|
||||||
|
self.firstname = firstname
|
||||||
|
self.lastname = lastname
|
||||||
|
self.address = address
|
||||||
|
self.zipcode = zipcode
|
||||||
|
self.city_id = city_id
|
||||||
|
self.email = email
|
||||||
|
self.phone = phone
|
||||||
|
self.password = password
|
||||||
|
self.role = role
|
||||||
|
|
||||||
|
def load_by_id(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
row = cur.execute("SELECT * FROM users WHERE id = ?", (self.id,)).fetchone()
|
||||||
|
|
||||||
|
if row == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
self._set_row_values(row)
|
||||||
|
|
||||||
|
cur.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def load_by_username(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
rows = cur.execute("SELECT * FROM users").fetchall()
|
||||||
|
|
||||||
|
found_user = None
|
||||||
|
for row in rows:
|
||||||
|
user = User(Database.connection)._set_row_values(row)
|
||||||
|
if user.username == self.username:
|
||||||
|
self._set_row_values(row)
|
||||||
|
found_user = user
|
||||||
|
break
|
||||||
|
|
||||||
|
cur.close()
|
||||||
|
if found_user:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
current_date = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO users
|
||||||
|
(id, username, firstname, lastname, address, zipcode, city_id, email, phone, password, role, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
""", (self.id, Encryption.encrypt(self.username), Encryption.encrypt(self.firstname), Encryption.encrypt(self.lastname), Encryption.encrypt(self.address), Encryption.encrypt(self.zipcode), self.city_id, Encryption.encrypt(self.email), Encryption.encrypt(self.phone), Encryption.encrypt(self.password), Encryption.encrypt(self.role), current_date))
|
||||||
|
|
||||||
|
self.connection.commit()
|
||||||
|
cur.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
cur.execute("""
|
||||||
|
UPDATE users SET
|
||||||
|
username = ?,
|
||||||
|
firstname = ?,
|
||||||
|
lastname = ?,
|
||||||
|
address = ?,
|
||||||
|
zipcode = ?,
|
||||||
|
city_id = ?,
|
||||||
|
email = ?,
|
||||||
|
phone = ?,
|
||||||
|
password = ?,
|
||||||
|
role = ?
|
||||||
|
WHERE id = ?
|
||||||
|
""", (Encryption.encrypt(self.username), Encryption.encrypt(self.firstname), Encryption.encrypt(self.lastname), Encryption.encrypt(self.address), Encryption.encrypt(self.zipcode), self.city_id, Encryption.encrypt(self.email), Encryption.encrypt(self.phone), Encryption.encrypt(self.password), self.role, self.id))
|
||||||
|
|
||||||
|
self.connection.commit()
|
||||||
|
cur.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
cur = self.connection.cursor()
|
||||||
|
cur.execute("""DELETE FROM users WHERE id = ?""", (self.id))
|
||||||
|
self.connection.commit()
|
||||||
|
cur.close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _set_row_values(self, row):
|
||||||
|
self.id = row[0]
|
||||||
|
self.username = Encryption.decrypt(row[1])
|
||||||
|
self.firstname = Encryption.decrypt(row[2])
|
||||||
|
self.lastname = Encryption.decrypt(row[3])
|
||||||
|
self.address = Encryption.decrypt(row[4])
|
||||||
|
self.zipcode = Encryption.decrypt(row[5])
|
||||||
|
self.city_id = row[6]
|
||||||
|
self.email = Encryption.decrypt(row[7])
|
||||||
|
self.phone = Encryption.decrypt(row[8])
|
||||||
|
self.password = Encryption.decrypt(row[9])
|
||||||
|
self.role = Encryption.decrypt(row[10])
|
||||||
|
self.created = row[11]
|
||||||
|
return self
|
28
src/services/auth.py
Normal file
28
src/services/auth.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from services.log import LogService
|
||||||
|
|
||||||
|
class Auth:
|
||||||
|
failed_attempts = 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_auth(username, password):
|
||||||
|
if username == "superadmin" and password == "Admin321!":
|
||||||
|
su_user = User(None, -1, "superadmin", "", "", "", "", "", "", "", "", "SUPER_ADMIN")
|
||||||
|
LogService.create_log(username, "Logged in", "", False)
|
||||||
|
Auth.failed_attempts = 0
|
||||||
|
return su_user
|
||||||
|
|
||||||
|
user = User(Database.connection, None, username)
|
||||||
|
if user.load_by_username() and user.password == password:
|
||||||
|
LogService.create_log(username, "Logged in", "", False)
|
||||||
|
Auth.failed_attempts = 0
|
||||||
|
return user
|
||||||
|
|
||||||
|
if Auth.failed_attempts >= 3:
|
||||||
|
LogService.create_log(username, "Multiple unsuccessful logins", "", True)
|
||||||
|
else:
|
||||||
|
LogService.create_log(username, "Unsuccessful login", f"Attempts: {Auth.failed_attempts}", False)
|
||||||
|
|
||||||
|
Auth.failed_attempts += 1
|
||||||
|
return None
|
@@ -1,4 +1,6 @@
|
|||||||
class Encryption:
|
class Encryption:
|
||||||
|
ENCRYTPION_KEY = "MASTER_KEY"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def vigenere(text: str, key: str, encrypt=True):
|
def vigenere(text: str, key: str, encrypt=True):
|
||||||
result = ''
|
result = ''
|
||||||
@@ -17,9 +19,9 @@ class Encryption:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def encrypt(text: str, key: str):
|
def encrypt(text: str):
|
||||||
return Encryption.vigenere(text=text, key=key, encrypt=True)
|
return Encryption.vigenere(text=text, key=Encryption.ENCRYTPION_KEY, encrypt=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def decrypt(text: str, key: str):
|
def decrypt(text: str):
|
||||||
return Encryption.vigenere(text=text, key=key, encrypt=False)
|
return Encryption.vigenere(text=text, key=Encryption.ENCRYTPION_KEY, encrypt=False)
|
25
src/services/log.py
Normal file
25
src/services/log.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import sqlite3
|
||||||
|
from datetime import datetime
|
||||||
|
from models.log import Log
|
||||||
|
from models.database import Database
|
||||||
|
|
||||||
|
class LogService:
|
||||||
|
@staticmethod
|
||||||
|
def create_log(username, description, additional_information, suspicious):
|
||||||
|
now = datetime.now()
|
||||||
|
date_string = now.strftime("%d-%m-%Y")
|
||||||
|
time_string = now.strftime("%H:%M:%S")
|
||||||
|
new_log = Log(Database.connection, None, username, date_string, time_string, description, additional_information, suspicious)
|
||||||
|
|
||||||
|
new_log.save()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_latest_logs():
|
||||||
|
cur = Database.connection.cursor()
|
||||||
|
cur.execute("SELECT * FROM logs ORDER BY id DESC LIMIT 100;")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
logs = []
|
||||||
|
for row in rows:
|
||||||
|
log = Log(Database.connection)._set_row_values(row)
|
||||||
|
logs.append(log)
|
||||||
|
return logs
|
74
src/services/search.py
Normal file
74
src/services/search.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from models.city import City
|
||||||
|
|
||||||
|
class Search:
|
||||||
|
@staticmethod
|
||||||
|
def search_members(query):
|
||||||
|
cur = Database.connection.cursor()
|
||||||
|
cur.execute("""SELECT * FROM users""")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
payload = []
|
||||||
|
for row in rows:
|
||||||
|
user = User(Database.connection)._set_row_values(row)
|
||||||
|
if str(user.id) == query:
|
||||||
|
payload.append(user)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if user.role == "MEMBER":
|
||||||
|
if user.username in query or user.firstname in query or user.lastname in query or user.email in query or user.phone in query:
|
||||||
|
payload.append(user)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def search_advisors(query):
|
||||||
|
cur = Database.connection.cursor()
|
||||||
|
cur.execute("""SELECT * FROM users""")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
payload = []
|
||||||
|
for row in rows:
|
||||||
|
user = User(Database.connection)._set_row_values(row)
|
||||||
|
if str(user.id) == user.id:
|
||||||
|
payload.append(user)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if user.role == "ADVISOR":
|
||||||
|
if user.username in query or user.firstname in query or user.lastname in query or user.email in query or user.phone in query:
|
||||||
|
payload.append(user)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def search_admins(query):
|
||||||
|
cur = Database.connection.cursor()
|
||||||
|
cur.execute("""SELECT * FROM users""")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
payload = []
|
||||||
|
for row in rows:
|
||||||
|
user = User(Database.connection)._set_row_values(row)
|
||||||
|
if str(user.id) == user.id:
|
||||||
|
payload.append(user)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if user.role == "SYSTEM_ADMIN":
|
||||||
|
if user.username in query or user.firstname in query or user.lastname in query or user.email in query or user.phone in query:
|
||||||
|
payload.append(user)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all_cites():
|
||||||
|
cur = Database.connection.cursor()
|
||||||
|
cur.execute("SELECT * FROM cities")
|
||||||
|
rows = cur.fetchall()
|
||||||
|
|
||||||
|
payload = []
|
||||||
|
for row in rows:
|
||||||
|
city = City(Database.connection)._set_row_values(row)
|
||||||
|
payload.append(city)
|
||||||
|
|
||||||
|
return payload
|
@@ -1,4 +1,3 @@
|
|||||||
from ast import Import
|
|
||||||
from models.user import User
|
from models.user import User
|
||||||
|
|
||||||
class State:
|
class State:
|
31
src/services/utils.py
Normal file
31
src/services/utils.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from models.database import Database
|
||||||
|
|
||||||
|
class Utils:
|
||||||
|
@staticmethod
|
||||||
|
def clear_screen():
|
||||||
|
os.system('cls' if os.name == 'nt' else 'clear')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def export_db():
|
||||||
|
with open(f"./backup.sql", 'w') as f:
|
||||||
|
for line in Database.connection.iterdump():
|
||||||
|
f.write('%s\n' % line)
|
||||||
|
|
||||||
|
with ZipFile("backup.zip", "w") as zip:
|
||||||
|
zip.write("backup.sql")
|
||||||
|
|
||||||
|
os.remove("./backup.sql")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def import_db():
|
||||||
|
with ZipFile("backup.zip", 'r') as zip:
|
||||||
|
zip.extractall("./")
|
||||||
|
with open(f"./backup.sql", 'r') as f:
|
||||||
|
str = f.read()
|
||||||
|
Database.connection.executescript(str)
|
||||||
|
|
||||||
|
os.remove("./backup.sql")
|
121
src/ui/input_menu.py
Normal file
121
src/ui/input_menu.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
from pickle import FALSE
|
||||||
|
import re
|
||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
|
||||||
|
class Validator:
|
||||||
|
@staticmethod
|
||||||
|
def check_email(input):
|
||||||
|
regex = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
|
||||||
|
return re.fullmatch(regex, input)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_username(input):
|
||||||
|
if len(input) < 6 or len(input) > 10:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not f"{input[0]}".isalpha():
|
||||||
|
return False
|
||||||
|
|
||||||
|
regex = re.compile(r'^[0-9A-Za-z_.-]+$')
|
||||||
|
if not re.fullmatch(regex, input):
|
||||||
|
return False
|
||||||
|
|
||||||
|
user = User(Database.connection, None, input)
|
||||||
|
user.load_by_username()
|
||||||
|
|
||||||
|
if user.id != None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_password(input):
|
||||||
|
regex = re.compile(r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,31}$')
|
||||||
|
return re.fullmatch(regex, input)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_postcode(input):
|
||||||
|
regex = re.compile(r'\b\d{4}[A-Z]{2}\b')
|
||||||
|
return re.fullmatch(regex, input)
|
||||||
|
|
||||||
|
class InputMenu:
|
||||||
|
|
||||||
|
def __init__(self, title):
|
||||||
|
self._title = title
|
||||||
|
self._fields = []
|
||||||
|
|
||||||
|
def add_option(self, key, title, type, value, min, max, validator):
|
||||||
|
self._fields.append({"key": key, "title": title, "type": type, "value": value, "min": min, "max": max, "validator": validator})
|
||||||
|
return self
|
||||||
|
|
||||||
|
def do_input(self):
|
||||||
|
print("")
|
||||||
|
print(f"/--[ {self._title} ]-------------")
|
||||||
|
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
data = None
|
||||||
|
|
||||||
|
while True:
|
||||||
|
data = ""
|
||||||
|
|
||||||
|
if self._fields[i]['value'] == None:
|
||||||
|
data = input(f"| ({self._fields[i]['title']}) => ")
|
||||||
|
else:
|
||||||
|
data = input(f"| ({self._fields[i]['title']}) [{self._fields[i]['value']}] => ")
|
||||||
|
|
||||||
|
if self._fields[i]['type'] == "STR":
|
||||||
|
|
||||||
|
# Check if value was preset and entered value was not changed
|
||||||
|
if self._fields[i]['value'] != None and data == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check length
|
||||||
|
if len(data) >= self._fields[i]['min'] and len(data) <= self._fields[i]['max']:
|
||||||
|
|
||||||
|
# Check regex validator id used
|
||||||
|
if self._fields[i]['validator'] != None:
|
||||||
|
if self._fields[i]['validator'](data):
|
||||||
|
# Set value of current field
|
||||||
|
self._fields[i]['value'] = data
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("| Invalid input! Try again. \n|")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Set value of current field
|
||||||
|
self._fields[i]['value'] = data
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
print("| Invalid input! Try again. \n|")
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif self._fields[i]['type'] == "INT":
|
||||||
|
|
||||||
|
# Check if value was preset and entered value was not changed
|
||||||
|
if self._fields[i]['value'] != None and data == "":
|
||||||
|
break
|
||||||
|
|
||||||
|
# Try and parse string into int, set value if no errors occur
|
||||||
|
try:
|
||||||
|
num = int(data)
|
||||||
|
if num >= self._fields[i]['min'] and num <= self._fields[i]['max']:
|
||||||
|
self._fields[i]['value'] = num
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("| Invalid input! Try again. \n|")
|
||||||
|
except:
|
||||||
|
print("| Invalid input! Try again. \n|")
|
||||||
|
else:
|
||||||
|
exit("Invalid input type!")
|
||||||
|
|
||||||
|
print(f"\-------------------------------")
|
||||||
|
print("")
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_value(self, key):
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
if self._fields[i]["key"] == key:
|
||||||
|
return self._fields[i]["value"]
|
||||||
|
return None
|
157
src/views/advisor_menu.py
Normal file
157
src/views/advisor_menu.py
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from services.state import State
|
||||||
|
from services.log import LogService
|
||||||
|
from services.search import Search
|
||||||
|
from ui.input_menu import InputMenu, Validator
|
||||||
|
from ui.selection_menu import SelectionMenu
|
||||||
|
|
||||||
|
|
||||||
|
class AdvisorMenu:
|
||||||
|
@staticmethod
|
||||||
|
def search_advisor(browse_mode):
|
||||||
|
form = InputMenu("Search for Advisors")
|
||||||
|
form.add_option("QUERY", "Query", "STR", None, 1, 250, None)
|
||||||
|
form.do_input()
|
||||||
|
query = form.get_value("QUERY")
|
||||||
|
|
||||||
|
users = Search.search_advisors(query)
|
||||||
|
|
||||||
|
if len(users) == 0:
|
||||||
|
input(f"No Advisors found with query: {query}. Press any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
for index, user in enumerate(users):
|
||||||
|
print(f"/--[{index}]--------------")
|
||||||
|
print(f"| Username: {user.username}")
|
||||||
|
print(f"| Firstname: {user.firstname}")
|
||||||
|
print(f"| Lastname: {user.lastname}")
|
||||||
|
print(f"| Address: {user.lastname}")
|
||||||
|
print(f"| Zipcode: {user.zipcode}")
|
||||||
|
print(f"| City: {user.city_id}")
|
||||||
|
print(f"| Email: {user.email}")
|
||||||
|
print(f"| Phone: {user.phone}")
|
||||||
|
print(f"\--------------------\n")
|
||||||
|
|
||||||
|
if browse_mode:
|
||||||
|
input(f"\nPress any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
select_form = InputMenu("Select Advisor by index")
|
||||||
|
select_form.add_option("INDEX", "Index", "INT", None, 0, len(users) - 1, None)
|
||||||
|
select_form.do_input()
|
||||||
|
|
||||||
|
return users[select_form.get_value("INDEX")]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def select_city():
|
||||||
|
menu = SelectionMenu("Select City")
|
||||||
|
|
||||||
|
cities = Search.get_all_cites()
|
||||||
|
for city in cities:
|
||||||
|
menu.add_option(city.name, city.id)
|
||||||
|
|
||||||
|
option = menu.display().input_option()
|
||||||
|
return option
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_advisor():
|
||||||
|
form = InputMenu("Add new Advisor")
|
||||||
|
form.add_option("USERNAME", "Username", "STR", None, 1, 250, Validator.check_username)
|
||||||
|
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("LASTNAME", "Lastname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ADDRESS", "Address", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
|
||||||
|
form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email)
|
||||||
|
form.add_option("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
|
||||||
|
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
|
||||||
|
form.do_input()
|
||||||
|
|
||||||
|
city_id = AdvisorMenu.select_city()
|
||||||
|
|
||||||
|
new_user = User(Database.connection,
|
||||||
|
None,
|
||||||
|
form.get_value("USERNAME"),
|
||||||
|
form.get_value("FIRSTNAME"),
|
||||||
|
form.get_value("LASTNAME"),
|
||||||
|
form.get_value("ADDRESS"),
|
||||||
|
form.get_value("ZIPCODE"),
|
||||||
|
city_id,
|
||||||
|
form.get_value("EMAIL"),
|
||||||
|
"+31-6" + form.get_value("PHONE"),
|
||||||
|
form.get_value("PASSWORD"),
|
||||||
|
"ADVISOR"
|
||||||
|
)
|
||||||
|
|
||||||
|
new_user.save()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Created advisor", f"Advisor: {new_user.username}", True)
|
||||||
|
input("Added new Advisor! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def edit_advisor():
|
||||||
|
user = AdvisorMenu.search_advisor(False)
|
||||||
|
|
||||||
|
edit_form = InputMenu("Edit Advisor (Leave fields empty to not change)")
|
||||||
|
edit_form.add_option("USERNAME", "Username", "STR", user.username, 1, 250, Validator.check_username)
|
||||||
|
edit_form.add_option("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None)
|
||||||
|
edit_form.add_option("LASTNAME", "Lastname", "STR", user.lastname, 1, 250, None)
|
||||||
|
edit_form.add_option("ADDRESS", "Address", "STR", user.address, 1, 250, None)
|
||||||
|
edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
|
||||||
|
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email)
|
||||||
|
edit_form.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
|
||||||
|
edit_form.do_input()
|
||||||
|
|
||||||
|
select_menu = SelectionMenu("Do want to change the city?")
|
||||||
|
select_menu.add_option("No", False).add_option("Yes", True).display()
|
||||||
|
change_city = select_menu.input_option()
|
||||||
|
if change_city:
|
||||||
|
user.city_id = AdvisorMenu.select_city()
|
||||||
|
|
||||||
|
user.username = edit_form.get_value("USERNAME")
|
||||||
|
user.firstname = edit_form.get_value("FIRSTNAME")
|
||||||
|
user.lastname = edit_form.get_value("LASTNAME")
|
||||||
|
user.address = edit_form.get_value("ADDRESS")
|
||||||
|
user.zipcode = edit_form.get_value("ZIPCODE")
|
||||||
|
user.email = edit_form.get_value("EMAIL")
|
||||||
|
user.phone = edit_form.get_value("PHONE")
|
||||||
|
|
||||||
|
user.update()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Updated advisor", f"Advisor: {user.username}", True)
|
||||||
|
input("Updated Advisor! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_password_advisor():
|
||||||
|
user = AdvisorMenu.search_advisor(False)
|
||||||
|
if user == None:
|
||||||
|
input("Advisor not found. Press any key to continue.")
|
||||||
|
return
|
||||||
|
|
||||||
|
form = InputMenu("Update password")
|
||||||
|
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
|
||||||
|
form.do_input()
|
||||||
|
user.password = form.get_value("PASSWORD")
|
||||||
|
user.update()
|
||||||
|
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Updated password of advisor", f"Advisor: {user.username}", True)
|
||||||
|
input("Updated Advisor Password! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def remove_advisor():
|
||||||
|
user = AdvisorMenu.search_advisor(False)
|
||||||
|
if user == None:
|
||||||
|
input("Advisor not found. Press any key to continue.")
|
||||||
|
return
|
||||||
|
|
||||||
|
confirm = SelectionMenu("Do you want to delete selected Advisor?")
|
||||||
|
confirm.add_option("Yes", True).add_option("No", False).display()
|
||||||
|
option = confirm.input_option()
|
||||||
|
|
||||||
|
if option == True:
|
||||||
|
user.delete()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Deleted advisor", f"Advisor: {user.username}", True)
|
||||||
|
input("Deleted Advisor! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def browse_advisor():
|
||||||
|
AdvisorMenu.search_advisor(True)
|
32
src/views/backup_menu.py
Normal file
32
src/views/backup_menu.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
from os import path
|
||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from services.search import Search
|
||||||
|
from services.utils import Utils
|
||||||
|
from ui.input_menu import InputMenu, Validator
|
||||||
|
from ui.selection_menu import SelectionMenu
|
||||||
|
|
||||||
|
class BackupMenu:
|
||||||
|
@staticmethod
|
||||||
|
def create_backup():
|
||||||
|
print(f"Exporting database to file: backup.zip")
|
||||||
|
Utils.export_db()
|
||||||
|
input(f"Exported database. Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def import_backup():
|
||||||
|
menu = SelectionMenu("Import Backup? This will delete current database!")
|
||||||
|
menu.add_option("Yes", True)
|
||||||
|
menu.add_option("No", False)
|
||||||
|
option = menu.display().input_option()
|
||||||
|
|
||||||
|
if option == False:
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Cleared current database.")
|
||||||
|
Database.delete_tables()
|
||||||
|
|
||||||
|
print(f"Importing database from file: backup.zip")
|
||||||
|
Utils.import_db()
|
||||||
|
input(f"Imported database. Press any key to return.")
|
@@ -1,5 +1,6 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from services.auth import Auth
|
from services.auth import Auth
|
||||||
|
from services.utils import Utils
|
||||||
from ui.input_menu import InputMenu
|
from ui.input_menu import InputMenu
|
||||||
from services.state import State
|
from services.state import State
|
||||||
from views.main_menu import MainMenu
|
from views.main_menu import MainMenu
|
||||||
@@ -9,9 +10,9 @@ class LoginMenu:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def display():
|
def display():
|
||||||
while True:
|
while True:
|
||||||
os.system("clear")
|
Utils.clear_screen()
|
||||||
login_form = InputMenu("Login Into Furnicur Family System")
|
login_form = InputMenu("Login Into Furnicur Family System")
|
||||||
login_form.add_option("USERNAME", "STR", "Username", 1, 250).add_option("PASSWORD", "STR", "Password", 1, 250).do_input()
|
login_form.add_option("USERNAME", "Username", "STR", "", 1, 250, None).add_option("PASSWORD", "Password", "STR", "", 1, 250, None).do_input()
|
||||||
|
|
||||||
user = Auth.check_auth(login_form.get_value("USERNAME"), login_form.get_value("PASSWORD"))
|
user = Auth.check_auth(login_form.get_value("USERNAME"), login_form.get_value("PASSWORD"))
|
||||||
if user:
|
if user:
|
145
src/views/main_menu.py
Normal file
145
src/views/main_menu.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import os
|
||||||
|
from services.state import State
|
||||||
|
from services.utils import Utils
|
||||||
|
from ui.input_menu import InputMenu, Validator
|
||||||
|
from ui.selection_menu import SelectionMenu
|
||||||
|
from views.advisor_menu import AdvisorMenu
|
||||||
|
from views.backup_menu import BackupMenu
|
||||||
|
from views.member_menu import MemberMenu
|
||||||
|
from views.system_admin_menu import SystemAdminMenu
|
||||||
|
from services.log import LogService
|
||||||
|
class MainMenu:
|
||||||
|
@staticmethod
|
||||||
|
def display():
|
||||||
|
while True:
|
||||||
|
Utils.clear_screen()
|
||||||
|
main_menu = SelectionMenu(f"Welcome {State.CURRENT_USER.username}!")
|
||||||
|
|
||||||
|
if State.CURRENT_USER.role == "ADVISOR" or State.CURRENT_USER.role == "SYSTEM_ADMIN":
|
||||||
|
main_menu.add_option("Update My Password", MainMenu.update_password)
|
||||||
|
main_menu.add_option("Manage Members", MainMenu.manage_members)
|
||||||
|
else:
|
||||||
|
main_menu.add_option("Manage Members", MainMenu.manage_members)
|
||||||
|
|
||||||
|
if State.CURRENT_USER.role == "SYSTEM_ADMIN" or State.CURRENT_USER.role == "SUPER_ADMIN":
|
||||||
|
main_menu.add_option("Manage Advisors", MainMenu.manage_advisors)
|
||||||
|
main_menu.add_option("View logs", MainMenu.check_logs)
|
||||||
|
main_menu.add_option("Manage Backups", MainMenu.manage_backups)
|
||||||
|
|
||||||
|
if State.CURRENT_USER.role == "SUPER_ADMIN":
|
||||||
|
main_menu.add_option("Manage Admins", MainMenu.manage_admins)
|
||||||
|
|
||||||
|
main_menu.add_option("Exit...", None)
|
||||||
|
|
||||||
|
selected_option = main_menu.display().input_option()
|
||||||
|
if selected_option == None:
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
selected_option()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_password():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
menu = SelectionMenu(f"Do you want to update your own password?")
|
||||||
|
menu.add_option("Yes", True)
|
||||||
|
menu.add_option("No", False)
|
||||||
|
|
||||||
|
selected_option = menu.display().input_option()
|
||||||
|
if selected_option == False:
|
||||||
|
return
|
||||||
|
|
||||||
|
form = InputMenu("Set new password")
|
||||||
|
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
|
||||||
|
form.do_input()
|
||||||
|
State.CURRENT_USER.password = form.get_value("PASSWORD")
|
||||||
|
State.CURRENT_USER.update()
|
||||||
|
|
||||||
|
input("Current password updated! Press any key to continue.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def manage_members():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
menu = SelectionMenu(f"Manage Members")
|
||||||
|
menu.add_option("Add Member", MemberMenu.add_member)
|
||||||
|
menu.add_option("Edit Member", MemberMenu.edit_member)
|
||||||
|
|
||||||
|
if State.CURRENT_USER.role == "SYSTEM_ADMIN" or State.CURRENT_USER.role == "SUPER_ADMIN":
|
||||||
|
menu.add_option("Remove Member", MemberMenu.remove_member)
|
||||||
|
|
||||||
|
menu.add_option("Browse Member", MemberMenu.browse_member)
|
||||||
|
menu.add_option("Back to main menu", None)
|
||||||
|
|
||||||
|
selected_option = menu.display().input_option()
|
||||||
|
if selected_option == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
selected_option()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def manage_advisors():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
menu = SelectionMenu(f"Manage Advisors")
|
||||||
|
menu.add_option("Add Advisor", AdvisorMenu.add_advisor)
|
||||||
|
menu.add_option("Edit Advisor", AdvisorMenu.edit_advisor)
|
||||||
|
menu.add_option("Reset Password Advisor", AdvisorMenu.update_password_advisor)
|
||||||
|
menu.add_option("Remove Advisor", AdvisorMenu.remove_advisor)
|
||||||
|
menu.add_option("Browse Advisor", AdvisorMenu.browse_advisor)
|
||||||
|
menu.add_option("Back to main menu", None)
|
||||||
|
|
||||||
|
selected_option = menu.display().input_option()
|
||||||
|
if selected_option == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
selected_option()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def manage_admins():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
menu = SelectionMenu(f"Manage System Admins")
|
||||||
|
menu.add_option("Add System Admin", SystemAdminMenu.add_admin)
|
||||||
|
menu.add_option("Edit System Admin", SystemAdminMenu.edit_admin)
|
||||||
|
menu.add_option("Reset Password System Admin", SystemAdminMenu.update_password_admin)
|
||||||
|
menu.add_option("Remove System Admin", SystemAdminMenu.remove_admin)
|
||||||
|
menu.add_option("Browse System Admin", SystemAdminMenu.browse_admins)
|
||||||
|
menu.add_option("Back to main menu", None)
|
||||||
|
|
||||||
|
selected_option = menu.display().input_option()
|
||||||
|
if selected_option == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
selected_option()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def manage_backups():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
menu = SelectionMenu(f"Manage Backups")
|
||||||
|
menu.add_option("Create Backup", BackupMenu.create_backup)
|
||||||
|
menu.add_option("Import Backup", BackupMenu.import_backup)
|
||||||
|
menu.add_option("Back to main menu", None)
|
||||||
|
|
||||||
|
selected_option = menu.display().input_option()
|
||||||
|
if selected_option == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
selected_option()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_logs():
|
||||||
|
Utils.clear_screen()
|
||||||
|
|
||||||
|
logs = LogService.get_latest_logs()
|
||||||
|
for log in logs:
|
||||||
|
print(f"/--[ {log.id} ]---------")
|
||||||
|
print(f"| Username: {log.username}")
|
||||||
|
print(f"| Description: {log.description}")
|
||||||
|
print(f"| Additional Information: {log.additional_information}")
|
||||||
|
print(f"| Suspicious: {log.suspicious}")
|
||||||
|
print(f"| Date: {log.date} {log.time}")
|
||||||
|
print(f"\-------------\n")
|
||||||
|
|
||||||
|
input("Press any key to continue.")
|
139
src/views/member_menu.py
Normal file
139
src/views/member_menu.py
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
|
||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from services.state import State
|
||||||
|
from services.log import LogService
|
||||||
|
from services.search import Search
|
||||||
|
from ui.input_menu import InputMenu, Validator
|
||||||
|
from ui.selection_menu import SelectionMenu
|
||||||
|
|
||||||
|
|
||||||
|
class MemberMenu:
|
||||||
|
@staticmethod
|
||||||
|
def search_member(browse_mode):
|
||||||
|
form = InputMenu("Search for Member")
|
||||||
|
form.add_option("QUERY", "Query", "STR", None, 1, 250, None)
|
||||||
|
form.do_input()
|
||||||
|
query = form.get_value("QUERY")
|
||||||
|
|
||||||
|
users = Search.search_members(query)
|
||||||
|
|
||||||
|
if len(users) == 0:
|
||||||
|
input(f"No Members found with query: {query}. Press any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
for index, user in enumerate(users):
|
||||||
|
print(f"/--[{index}]--------------")
|
||||||
|
print(f"| Username: {user.username}")
|
||||||
|
print(f"| Firstname: {user.firstname}")
|
||||||
|
print(f"| Lastname: {user.lastname}")
|
||||||
|
print(f"| Address: {user.lastname}")
|
||||||
|
print(f"| Zipcode: {user.zipcode}")
|
||||||
|
print(f"| City: {user.city_id}")
|
||||||
|
print(f"| Email: {user.email}")
|
||||||
|
print(f"| Phone: {user.phone}")
|
||||||
|
print(f"\--------------------\n")
|
||||||
|
|
||||||
|
if browse_mode:
|
||||||
|
input(f"\nPress any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
select_form = InputMenu("Select Member by index")
|
||||||
|
select_form.add_option("INDEX", "Index", "INT", None, 0, len(users) - 1, None)
|
||||||
|
select_form.do_input()
|
||||||
|
|
||||||
|
return users[select_form.get_value("INDEX")]
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def select_city():
|
||||||
|
menu = SelectionMenu("Select City")
|
||||||
|
|
||||||
|
cities = Search.get_all_cites()
|
||||||
|
for city in cities:
|
||||||
|
menu.add_option(city.name, city.id)
|
||||||
|
|
||||||
|
option = menu.display().input_option()
|
||||||
|
return option
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_member():
|
||||||
|
form = InputMenu("Add new Member")
|
||||||
|
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("LASTNAME", "Lastname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ADDRESS", "Address", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
|
||||||
|
form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email)
|
||||||
|
form.add_option("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
|
||||||
|
form.do_input()
|
||||||
|
|
||||||
|
city_id = MemberMenu.select_city()
|
||||||
|
|
||||||
|
new_user = User(Database.connection,
|
||||||
|
None,
|
||||||
|
"",
|
||||||
|
form.get_value("FIRSTNAME"),
|
||||||
|
form.get_value("LASTNAME"),
|
||||||
|
form.get_value("ADDRESS"),
|
||||||
|
form.get_value("ZIPCODE"),
|
||||||
|
city_id,
|
||||||
|
form.get_value("EMAIL"),
|
||||||
|
"+31-6" + form.get_value("PHONE"),
|
||||||
|
"",
|
||||||
|
"MEMBER"
|
||||||
|
)
|
||||||
|
|
||||||
|
new_user.save()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Added member", f"Member: {new_user.firstname} {new_user.lastname}", False)
|
||||||
|
input("Added new Member! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def edit_member():
|
||||||
|
user = MemberMenu.search_member(False)
|
||||||
|
|
||||||
|
edit_form = InputMenu("Edit Member (Leave fields empty to not change)")
|
||||||
|
edit_form.add_option("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None)
|
||||||
|
edit_form.add_option("LASTNAME", "Lastname", "STR", user.lastname, 1, 250, None)
|
||||||
|
edit_form.add_option("ADDRESS", "Address", "STR", user.address, 1, 250, None)
|
||||||
|
edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
|
||||||
|
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email)
|
||||||
|
edit_form.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
|
||||||
|
edit_form.do_input()
|
||||||
|
|
||||||
|
select_menu = SelectionMenu("Do want to change the city?")
|
||||||
|
select_menu.add_option("No", False).add_option("Yes", True).display()
|
||||||
|
change_city = select_menu.input_option()
|
||||||
|
if change_city:
|
||||||
|
user.city_id = MemberMenu.select_city()
|
||||||
|
|
||||||
|
user.firstname = edit_form.get_value("FIRSTNAME")
|
||||||
|
user.lastname = edit_form.get_value("LASTNAME")
|
||||||
|
user.address = edit_form.get_value("ADDRESS")
|
||||||
|
user.zipcode = edit_form.get_value("ZIPCODE")
|
||||||
|
user.city_id = edit_form.get_value("CITY_ID")
|
||||||
|
user.email = edit_form.get_value("EMAIL")
|
||||||
|
user.phone = edit_form.get_value("PHONE")
|
||||||
|
|
||||||
|
user.update()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Updated member", f"Member: {user.firstname} {user.lastname}", False)
|
||||||
|
input("Updated Member! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def remove_member():
|
||||||
|
user = MemberMenu.search_member(False)
|
||||||
|
|
||||||
|
if user == None:
|
||||||
|
return
|
||||||
|
|
||||||
|
confirm = SelectionMenu("Do you want to delete selected Member?")
|
||||||
|
confirm.add_option("Yes", True).add_option("No", False).display()
|
||||||
|
option = confirm.input_option()
|
||||||
|
|
||||||
|
if option == True:
|
||||||
|
user.delete()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Removed member", f"Member: {user.firstname} {user.lastname}", False)
|
||||||
|
input("Deleted Member! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def browse_member():
|
||||||
|
MemberMenu.search_member(True)
|
157
src/views/system_admin_menu.py
Normal file
157
src/views/system_admin_menu.py
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
from models.database import Database
|
||||||
|
from models.user import User
|
||||||
|
from services.state import State
|
||||||
|
from services.log import LogService
|
||||||
|
from services.search import Search
|
||||||
|
from ui.input_menu import InputMenu, Validator
|
||||||
|
from ui.selection_menu import SelectionMenu
|
||||||
|
|
||||||
|
|
||||||
|
class SystemAdminMenu:
|
||||||
|
@staticmethod
|
||||||
|
def search_admins(browse_mode):
|
||||||
|
form = InputMenu("Search for System Admins")
|
||||||
|
form.add_option("QUERY", "Query", "STR", None, 1, 250, None)
|
||||||
|
form.do_input()
|
||||||
|
query = form.get_value("QUERY")
|
||||||
|
|
||||||
|
users = Search.search_admins(query)
|
||||||
|
|
||||||
|
if len(users) == 0:
|
||||||
|
input(f"No System Admins found with query: {query}. Press any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
for index, user in enumerate(users):
|
||||||
|
print(f"/--[{index}]--------------")
|
||||||
|
print(f"| Username: {user.username}")
|
||||||
|
print(f"| Firstname: {user.firstname}")
|
||||||
|
print(f"| Lastname: {user.lastname}")
|
||||||
|
print(f"| Address: {user.lastname}")
|
||||||
|
print(f"| Zipcode: {user.zipcode}")
|
||||||
|
print(f"| City: {user.city_id}")
|
||||||
|
print(f"| Email: {user.email}")
|
||||||
|
print(f"| Phone: {user.phone}")
|
||||||
|
print(f"\--------------------\n")
|
||||||
|
|
||||||
|
if browse_mode:
|
||||||
|
input(f"\nPress any key to continue.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
select_form = InputMenu("Select System Admin by index")
|
||||||
|
select_form.add_option("INDEX", "Index", "INT", None, 0, len(users) - 1, None)
|
||||||
|
select_form.do_input()
|
||||||
|
|
||||||
|
return users[select_form.get_value("INDEX")]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def select_city():
|
||||||
|
menu = SelectionMenu("Select City")
|
||||||
|
|
||||||
|
cities = Search.get_all_cites()
|
||||||
|
for city in cities:
|
||||||
|
menu.add_option(city.name, city.id)
|
||||||
|
|
||||||
|
option = menu.display().input_option()
|
||||||
|
return option
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_admin():
|
||||||
|
form = InputMenu("Add new System Admin")
|
||||||
|
form.add_option("USERNAME", "Username", "STR", None, 1, 250, Validator.check_username)
|
||||||
|
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("LASTNAME", "Lastname", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ADDRESS", "Address", "STR", None, 1, 250, None)
|
||||||
|
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
|
||||||
|
form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email)
|
||||||
|
form.add_option("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
|
||||||
|
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
|
||||||
|
form.do_input()
|
||||||
|
|
||||||
|
city_id = SystemAdminMenu.select_city()
|
||||||
|
|
||||||
|
new_user = User(Database.connection,
|
||||||
|
None,
|
||||||
|
form.get_value("USERNAME"),
|
||||||
|
form.get_value("FIRSTNAME"),
|
||||||
|
form.get_value("LASTNAME"),
|
||||||
|
form.get_value("ADDRESS"),
|
||||||
|
form.get_value("ZIPCODE"),
|
||||||
|
city_id,
|
||||||
|
form.get_value("EMAIL"),
|
||||||
|
"+31-6" + form.get_value("PHONE"),
|
||||||
|
form.get_value("PASSWORD"),
|
||||||
|
"SYSTEM_ADMIN"
|
||||||
|
)
|
||||||
|
|
||||||
|
new_user.save()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Added system admin", f"System Admin: {new_user.username}", False)
|
||||||
|
input("Added new system admin! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def edit_admin():
|
||||||
|
user = SystemAdminMenu.search_admins(False)
|
||||||
|
if user == None:
|
||||||
|
input("Admin not found. Press any key to continue.")
|
||||||
|
return
|
||||||
|
|
||||||
|
edit_form = InputMenu("Edit System Admin (Leave fields empty to not change)")
|
||||||
|
edit_form.add_option("USERNAME", "Username", "STR", user.username, 1, 250, Validator.check_username)
|
||||||
|
edit_form.add_option("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None)
|
||||||
|
edit_form.add_option("LASTNAME", "Lastname", "STR", user.lastname, 1, 250, None)
|
||||||
|
edit_form.add_option("ADDRESS", "Address", "STR", user.address, 1, 250, None)
|
||||||
|
edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
|
||||||
|
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email)
|
||||||
|
edit_form.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
|
||||||
|
edit_form.do_input()
|
||||||
|
|
||||||
|
select_menu = SelectionMenu("Do want to change the city?")
|
||||||
|
select_menu.add_option("No", False).add_option("Yes", True).display()
|
||||||
|
change_city = select_menu.input_option()
|
||||||
|
if change_city:
|
||||||
|
user.city_id = SystemAdminMenu.select_city()
|
||||||
|
|
||||||
|
user.username = edit_form.get_value("USERNAME")
|
||||||
|
user.firstname = edit_form.get_value("FIRSTNAME")
|
||||||
|
user.lastname = edit_form.get_value("LASTNAME")
|
||||||
|
user.address = edit_form.get_value("ADDRESS")
|
||||||
|
user.zipcode = edit_form.get_value("ZIPCODE")
|
||||||
|
user.email = edit_form.get_value("EMAIL")
|
||||||
|
user.phone = edit_form.get_value("PHONE")
|
||||||
|
|
||||||
|
user.update()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Updated system admin", f"System Admin: {user.username}", False)
|
||||||
|
input("Updated System Admin! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_password_admin():
|
||||||
|
user = SystemAdminMenu.search_admins(False)
|
||||||
|
if user == None:
|
||||||
|
input("Admin not found. Press any key to continue.")
|
||||||
|
return
|
||||||
|
|
||||||
|
form = InputMenu("Update password")
|
||||||
|
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
|
||||||
|
form.do_input()
|
||||||
|
user.password = form.get_value("PASSWORD")
|
||||||
|
user.update()
|
||||||
|
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Updated password system admin", f"System Admin: {user.username}", False)
|
||||||
|
input("Updated System Admin password! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def remove_admin():
|
||||||
|
user = SystemAdminMenu.search_admins(False)
|
||||||
|
|
||||||
|
confirm = SelectionMenu("Do you want to delete selected system admin?")
|
||||||
|
confirm.add_option("Yes", True).add_option("No", False).display()
|
||||||
|
option = confirm.input_option()
|
||||||
|
|
||||||
|
if option == True:
|
||||||
|
user.delete()
|
||||||
|
LogService.create_log(State.CURRENT_USER.username, "Removed system admin", f"System Admin: {user.username}", False)
|
||||||
|
input("Deleted advisor! Press any key to return.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def browse_admins():
|
||||||
|
SystemAdminMenu.search_admins(True)
|
@@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
class InputMenu:
|
|
||||||
|
|
||||||
def __init__(self, title):
|
|
||||||
self._title = title
|
|
||||||
self._fields = []
|
|
||||||
|
|
||||||
def add_option(self, key, type, title, min, max):
|
|
||||||
self._fields.append({"key": key, "title": title, "type": type, "value": None, "min": min, "max": max})
|
|
||||||
return self
|
|
||||||
|
|
||||||
def do_input(self):
|
|
||||||
print("")
|
|
||||||
print(f"/--[ {self._title} ]-------------")
|
|
||||||
|
|
||||||
for i in range(len(self._fields)):
|
|
||||||
data = None
|
|
||||||
|
|
||||||
while True:
|
|
||||||
data = input(f"| ({self._fields[i]['title']}) => ")
|
|
||||||
if self._fields[i]['type'] == "STR":
|
|
||||||
if len(data) > self._fields[i]['min'] and len(data) <= self._fields[i]['max']:
|
|
||||||
self._fields[i]['value'] = data
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print("| Invalid input! Try again. \n|")
|
|
||||||
|
|
||||||
elif self._fields[i]['type'] == "INT":
|
|
||||||
try:
|
|
||||||
num = int(data)
|
|
||||||
if num > self._fields[i]['min'] and num <= self._fields[i]['max']:
|
|
||||||
self._fields[i]['value'] = data
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print("| Invalid input! Try again. \n|")
|
|
||||||
except:
|
|
||||||
print("| Invalid input! Try again. \n|")
|
|
||||||
else:
|
|
||||||
exit("Invalid input type!")
|
|
||||||
|
|
||||||
print(f"\-------------------------------")
|
|
||||||
print("")
|
|
||||||
return self
|
|
||||||
|
|
||||||
def get_value(self, key):
|
|
||||||
for i in range(len(self._fields)):
|
|
||||||
if self._fields[i]["key"] == key:
|
|
||||||
return self._fields[i]["value"]
|
|
||||||
return None
|
|
@@ -1,44 +0,0 @@
|
|||||||
import os
|
|
||||||
from services.state import State
|
|
||||||
from ui.selection_menu import SelectionMenu
|
|
||||||
from views.member_menu import MemberMenu
|
|
||||||
|
|
||||||
class MainMenu:
|
|
||||||
@staticmethod
|
|
||||||
def display():
|
|
||||||
while True:
|
|
||||||
os.system("clear")
|
|
||||||
main_menu = SelectionMenu(f"Welcome {State.CURRENT_USER.username}!")
|
|
||||||
|
|
||||||
if State.CURRENT_USER.role == "ADVISOR" or State.CURRENT_USER.role == "SYSTEM_ADMIN":
|
|
||||||
main_menu.add_option("Update My Password", None)
|
|
||||||
main_menu.add_option("Manage Members", MainMenu.manage_members)
|
|
||||||
|
|
||||||
if State.CURRENT_USER.role == "SYSTEM_ADMIN" and State.CURRENT_USER.role == "SUPER_ADMIN":
|
|
||||||
main_menu.add_option("Manage Advisors", None)
|
|
||||||
|
|
||||||
main_menu.add_option("Exit...", None)
|
|
||||||
|
|
||||||
selected_option = main_menu.display().input_option()
|
|
||||||
if selected_option == None:
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
selected_option()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def manage_members():
|
|
||||||
os.system("clear")
|
|
||||||
|
|
||||||
menu = SelectionMenu(f"Manage Members")
|
|
||||||
menu.add_option("Add Member", MemberMenu.add_member)
|
|
||||||
menu.add_option("Edit Member", MemberMenu.edit_member)
|
|
||||||
menu.add_option("Remove Member", MemberMenu.remove_member)
|
|
||||||
menu.add_option("Back to main menu", None)
|
|
||||||
|
|
||||||
selected_option = menu.display().input_option()
|
|
||||||
if selected_option == None:
|
|
||||||
return
|
|
||||||
|
|
||||||
selected_option()
|
|
||||||
|
|
||||||
|
|
@@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
from ui.input_menu import InputMenu
|
|
||||||
|
|
||||||
|
|
||||||
class MemberMenu:
|
|
||||||
@staticmethod
|
|
||||||
def add_member():
|
|
||||||
menu = InputMenu()
|
|
||||||
menu.add_option("USERNAME", "STR", "Username", 1, 250)
|
|
||||||
menu.add_option("FIRSTNAME", "STR", "Firstname", 1, 250)
|
|
||||||
menu.add_option("LASTNAME", "STR", "Lastname", 1, 250)
|
|
||||||
menu.add_option("ADDRESS", "STR", "Address", 1, 250)
|
|
||||||
menu.add_option("ZIPCODE", "STR", "Zipcode", 1, 250)
|
|
||||||
menu.add_option("CITY_ID", "STR", "City", 1, 250)
|
|
||||||
menu.add_option("EMAIL", "STR", "Email", 1, 250)
|
|
||||||
menu.add_option("PHONE", "STR", "Phone", 1, 250)
|
|
||||||
menu.add_option("PASSWORD", "STR", "Password", 1, 250)
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def edit_member():
|
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def remove_member():
|
|
||||||
pass
|
|
@@ -1,4 +0,0 @@
|
|||||||
class SystemAdminMenu:
|
|
||||||
@staticmethod
|
|
||||||
def display():
|
|
||||||
pass
|
|
Reference in New Issue
Block a user