Compare commits

...

21 Commits

Author SHA1 Message Date
651d7e198c deliverables 2022-10-09 23:17:56 +02:00
ba3da19b69 cleanup 2022-10-09 23:15:25 +02:00
309d60e3d7 dsds 2022-10-09 22:56:02 +02:00
9bd0825a66 fixxxxxxxxxx 2022-10-09 22:26:10 +02:00
cc8e861859 sdsd 2022-10-09 22:11:12 +02:00
94d13bb245 auth fix 2022-10-09 21:53:21 +02:00
e184874163 fix voor valeria 2022-10-09 21:42:18 +02:00
f9dcf49ae1 fix 2022-10-09 21:34:10 +02:00
0fc26b1900 fix 2022-10-09 21:31:25 +02:00
159792c008 perm fix 2022-10-09 21:28:56 +02:00
1f61f877fe fix 2022-10-09 17:20:09 +02:00
048eea106e implemented encyption 2022-10-09 15:14:14 +02:00
274549f04b added postcode validation 2022-10-09 14:32:55 +02:00
8a09d27bf4 added logging system 2022-10-09 14:27:22 +02:00
6398dcdf1b added log viewer 2022-10-07 23:51:20 +02:00
155a86ab06 fixed backup 2022-10-07 23:23:57 +02:00
87229a654e added backup system! 2022-10-07 22:53:23 +02:00
879ee79a90 fix 2022-10-07 20:26:44 +02:00
2da5591e0e another one 2022-10-07 20:15:19 +02:00
93796f613a fix 2022-10-07 20:14:31 +02:00
b56b687f73 working on project 2022-10-07 20:10:08 +02:00
30 changed files with 510 additions and 263 deletions

BIN
ffs.pdf Normal file

Binary file not shown.

View File

@@ -1,13 +0,0 @@
from models.database import Database
from models.user import User
class Auth:
def check_auth(username, password):
if username == "superadmin" and password == "Admin321!":
su_user = User(None, -1, "superadmin", "", "", "", "", "", "", "", "", "SUPER_ADMIN")
return su_user
user = User(Database.connection, None, username)
if user.load_by_username() and user.password == password:
return user
return None

View File

@@ -1,69 +0,0 @@
from models.database import Database
from models.user import User
class Search:
@staticmethod
def search_members(query):
cur = Database.connection.cursor()
cur.execute("""
SELECT * FROM users WHERE
id LIKE ? OR
username LIKE ? OR
firstname LIKE ? OR
lastname LIKE ? OR
email LIKE ? OR
phone LIKE ?
""", (f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%"))
rows = cur.fetchall()
payload = []
for row in rows:
user = User(Database.connection)._set_row_values(row)
if user.role == "MEMBER":
payload.append(user)
return payload
@staticmethod
def search_advisors(query):
cur = Database.connection.cursor()
cur.execute("""
SELECT * FROM users WHERE
id LIKE ? OR
username LIKE ? OR
firstname LIKE ? OR
lastname LIKE ? OR
email LIKE ? OR
phone LIKE ?
""", (f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%"))
rows = cur.fetchall()
payload = []
for row in rows:
user = User(Database.connection)._set_row_values(row)
if user.role == "ADVISOR":
payload.append(user)
return payload
@staticmethod
def search_admins(query):
cur = Database.connection.cursor()
cur.execute("""
SELECT * FROM users WHERE
id LIKE ? OR
username LIKE ? OR
firstname LIKE ? OR
lastname LIKE ? OR
email LIKE ? OR
phone LIKE ?
""", (f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%", f"%{query}%"))
rows = cur.fetchall()
payload = []
for row in rows:
user = User(Database.connection)._set_row_values(row)
if user.role == "SYSTEM_ADMIN":
payload.append(user)
return payload

View File

@@ -1,7 +0,0 @@
import os
class Utils:
@staticmethod
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')

View File

@@ -2,7 +2,7 @@ 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 services.search import Search
from ui.input_menu import InputMenu, EMAIL_VALIDATOR from ui.input_menu import InputMenu
from views.login_menu import LoginMenu from views.login_menu import LoginMenu
from services.log import LogService from services.log import LogService
@@ -11,8 +11,4 @@ def main():
DatabaseUtils.init_city_data() DatabaseUtils.init_city_data()
LoginMenu.display() LoginMenu.display()
# test = InputMenu("test")
# test.add_option("EMAIL", "email", "STR", "nick.leeman@hotmail.com", 0, 40, EMAIL_VALIDATOR)
# test.do_input()
# print(test.get_value("EMAIL"))
main() main()

View File

@@ -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
@@ -55,7 +55,7 @@ class City:
def delete(self): def delete(self):
cur = self.connection.cursor() cur = self.connection.cursor()
cur.execute("""DELETE FROM logs WHERE id = ?""", (self.id)) cur.execute("""DELETE FROM cities WHERE id = ?""", (self.id))
self.connection.commit() self.connection.commit()
cur.close() cur.close()
return True return True
@@ -63,3 +63,4 @@ class City:
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

View File

@@ -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()

View File

@@ -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,26 +26,11 @@ 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()
cur.close()
return True
def update(self):
cur = self.connection.cursor()
cur.execute("""
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()
@@ -60,9 +45,10 @@ class Log:
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

View File

@@ -1,5 +1,7 @@
import sqlite3 import sqlite3
from datetime import datetime from datetime import datetime
from models.database import Database
from services.encryption import Encryption
class User: 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): 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):
@@ -30,15 +32,21 @@ class User:
def load_by_username(self): def load_by_username(self):
cur = self.connection.cursor() cur = self.connection.cursor()
row = cur.execute("SELECT * FROM users WHERE username = ?", (self.username,)).fetchone() rows = cur.execute("SELECT * FROM users").fetchall()
if row == None: found_user = None
return False for row in rows:
user = User(Database.connection)._set_row_values(row)
self._set_row_values(row) if user.username == self.username:
self._set_row_values(row)
found_user = user
break
cur.close() cur.close()
return True if found_user:
return True
else:
return False
def save(self): def save(self):
cur = self.connection.cursor() cur = self.connection.cursor()
@@ -46,7 +54,7 @@ class User:
cur.execute(""" cur.execute("""
INSERT INTO users INSERT INTO users
(id, username, firstname, lastname, address, zipcode, city_id, email, phone, password, role, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) (id, username, firstname, lastname, address, zipcode, city_id, email, phone, password, role, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (self.id, self.username, self.firstname, self.lastname, self.address, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, current_date)) """, (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() self.connection.commit()
cur.close() cur.close()
@@ -67,7 +75,7 @@ class User:
password = ?, password = ?,
role = ? role = ?
WHERE id = ? WHERE id = ?
""", (self.username, self.firstname, self.lastname, self.address, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, 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), self.role, self.id))
self.connection.commit() self.connection.commit()
cur.close() cur.close()
@@ -82,15 +90,15 @@ class User:
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.firstname = row[2] self.firstname = Encryption.decrypt(row[2])
self.lastname = row[3] self.lastname = Encryption.decrypt(row[3])
self.address = row[4] self.address = Encryption.decrypt(row[4])
self.zipcode = row[5] self.zipcode = Encryption.decrypt(row[5])
self.city_id = row[6] self.city_id = row[6]
self.email = row[7] self.email = Encryption.decrypt(row[7])
self.phone = row[8] self.phone = Encryption.decrypt(row[8])
self.password = row[9] self.password = Encryption.decrypt(row[9])
self.role = row[10] self.role = Encryption.decrypt(row[10])
self.created = row[11] self.created = row[11]
return self return self

28
src/services/auth.py Normal file
View 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

View File

@@ -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)

View File

@@ -5,10 +5,21 @@ from models.database import Database
class LogService: class LogService:
@staticmethod @staticmethod
def createlog(username, description, additional_information, suspicious): def create_log(username, description, additional_information, suspicious):
now = datetime.now() now = datetime.now()
date_string = now.strftime("%d-%m-%Y") date_string = now.strftime("%d-%m-%Y")
time_string = now.strftime("%H:%M:%S") time_string = now.strftime("%H:%M:%S")
new_log = Log(Database.connection, None, username, date_string, time_string, description, additional_information, suspicious) new_log = Log(Database.connection, None, username, date_string, time_string, description, additional_information, suspicious)
new_log.save() 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
View 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

View File

@@ -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
View 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")

View File

@@ -34,6 +34,11 @@ class Validator:
regex = re.compile(r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,31}$') regex = re.compile(r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,31}$')
return re.fullmatch(regex, input) 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: class InputMenu:
def __init__(self, title): def __init__(self, title):

View File

@@ -1,7 +1,8 @@
from click import edit
from models.database import Database from models.database import Database
from models.user import User from models.user import User
from services.state import State
from services.log import LogService
from services.search import Search from services.search import Search
from ui.input_menu import InputMenu, Validator from ui.input_menu import InputMenu, Validator
from ui.selection_menu import SelectionMenu from ui.selection_menu import SelectionMenu
@@ -43,6 +44,16 @@ class AdvisorMenu:
return users[select_form.get_value("INDEX")] 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 @staticmethod
def add_advisor(): def add_advisor():
@@ -51,13 +62,14 @@ class AdvisorMenu:
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None) form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
form.add_option("LASTNAME", "Lastname", "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("ADDRESS", "Address", "STR", None, 1, 250, None)
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, None) form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
form.add_option("CITY_ID", "City", "STR", None, 1, 250, None)
form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email) 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("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password) form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
form.do_input() form.do_input()
city_id = AdvisorMenu.select_city()
new_user = User(Database.connection, new_user = User(Database.connection,
None, None,
form.get_value("USERNAME"), form.get_value("USERNAME"),
@@ -65,7 +77,7 @@ class AdvisorMenu:
form.get_value("LASTNAME"), form.get_value("LASTNAME"),
form.get_value("ADDRESS"), form.get_value("ADDRESS"),
form.get_value("ZIPCODE"), form.get_value("ZIPCODE"),
form.get_value("CITY_ID"), city_id,
form.get_value("EMAIL"), form.get_value("EMAIL"),
"+31-6" + form.get_value("PHONE"), "+31-6" + form.get_value("PHONE"),
form.get_value("PASSWORD"), form.get_value("PASSWORD"),
@@ -73,6 +85,7 @@ class AdvisorMenu:
) )
new_user.save() 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.") input("Added new Advisor! Press any key to return.")
@staticmethod @staticmethod
@@ -84,29 +97,51 @@ class AdvisorMenu:
edit_form.add_option("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None) 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("LASTNAME", "Lastname", "STR", user.lastname, 1, 250, None)
edit_form.add_option("ADDRESS", "Address", "STR", user.address, 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, None) edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
edit_form.add_option("CITY_ID", "City", "STR", user.city_id, 1, 250, None)
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email) 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.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
edit_form.add_option("PASSWORD", "Password", "STR", user.phone, 1, 255, Validator.check_password)
edit_form.do_input() 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.username = edit_form.get_value("USERNAME")
user.firstname = edit_form.get_value("FIRSTNAME") user.firstname = edit_form.get_value("FIRSTNAME")
user.lastname = edit_form.get_value("LASTNAME") user.lastname = edit_form.get_value("LASTNAME")
user.address = edit_form.get_value("ADDRESS") user.address = edit_form.get_value("ADDRESS")
user.zipcode = edit_form.get_value("ZIPCODE") user.zipcode = edit_form.get_value("ZIPCODE")
user.city_id = edit_form.get_value("CITY_ID")
user.email = edit_form.get_value("EMAIL") user.email = edit_form.get_value("EMAIL")
user.phone = edit_form.get_value("PHONE") user.phone = edit_form.get_value("PHONE")
user.password = edit_form.get_value("PASSWORD")
user.update() user.update()
LogService.create_log(State.CURRENT_USER.username, "Updated advisor", f"Advisor: {user.username}", True)
input("Updated Advisor! Press any key to return.") 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 @staticmethod
def remove_advisor(): def remove_advisor():
user = AdvisorMenu.search_advisor(False) 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 = SelectionMenu("Do you want to delete selected Advisor?")
confirm.add_option("Yes", True).add_option("No", False).display() confirm.add_option("Yes", True).add_option("No", False).display()
@@ -114,8 +149,9 @@ class AdvisorMenu:
if option == True: if option == True:
user.delete() user.delete()
LogService.create_log(State.CURRENT_USER.username, "Deleted advisor", f"Advisor: {user.username}", True)
input("Deleted Advisor! Press any key to return.") input("Deleted Advisor! Press any key to return.")
@staticmethod @staticmethod
def browse_advisor(): def browse_advisor():
AdvisorMenu.search_member(True) AdvisorMenu.search_advisor(True)

32
src/views/backup_menu.py Normal file
View 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.")

View File

@@ -12,7 +12,7 @@ class LoginMenu:
while True: while True:
Utils.clear_screen() Utils.clear_screen()
login_form = InputMenu("Login Into Furnicur Family System") login_form = InputMenu("Login Into Furnicur Family System")
login_form.add_option("USERNAME", "Username", "STR", "superadmin", 1, 250, None).add_option("PASSWORD", "Password", "STR", "Admin321!", 1, 250, None).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
View 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.")

View File

@@ -1,9 +1,10 @@
from click import edit
from models.database import Database from models.database import Database
from models.user import User from models.user import User
from services.state import State
from services.log import LogService
from services.search import Search from services.search import Search
from ui.input_menu import InputMenu, EMAIL_VALIDATOR from ui.input_menu import InputMenu, Validator
from ui.selection_menu import SelectionMenu from ui.selection_menu import SelectionMenu
@@ -44,18 +45,30 @@ class MemberMenu:
return users[select_form.get_value("INDEX")] 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 @staticmethod
def add_member(): def add_member():
form = InputMenu("Add new Member") form = InputMenu("Add new Member")
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None) form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
form.add_option("LASTNAME", "Lastname", "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("ADDRESS", "Address", "STR", None, 1, 250, None)
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, None) form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
form.add_option("CITY_ID", "City", "STR", None, 1, 250, None) form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email)
form.add_option("EMAIL", "Email", "STR", None, 1, 250, EMAIL_VALIDATOR)
form.add_option("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None) form.add_option("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
form.do_input() form.do_input()
city_id = MemberMenu.select_city()
new_user = User(Database.connection, new_user = User(Database.connection,
None, None,
"", "",
@@ -63,7 +76,7 @@ class MemberMenu:
form.get_value("LASTNAME"), form.get_value("LASTNAME"),
form.get_value("ADDRESS"), form.get_value("ADDRESS"),
form.get_value("ZIPCODE"), form.get_value("ZIPCODE"),
form.get_value("CITY_ID"), city_id,
form.get_value("EMAIL"), form.get_value("EMAIL"),
"+31-6" + form.get_value("PHONE"), "+31-6" + form.get_value("PHONE"),
"", "",
@@ -71,6 +84,7 @@ class MemberMenu:
) )
new_user.save() 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.") input("Added new Member! Press any key to return.")
@staticmethod @staticmethod
@@ -81,12 +95,17 @@ class MemberMenu:
edit_form.add_option("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None) 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("LASTNAME", "Lastname", "STR", user.lastname, 1, 250, None)
edit_form.add_option("ADDRESS", "Address", "STR", user.address, 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, None) edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
edit_form.add_option("CITY_ID", "City", "STR", user.city_id, 1, 250, None) edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email)
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, EMAIL_VALIDATOR)
edit_form.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None) edit_form.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
edit_form.do_input() 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.firstname = edit_form.get_value("FIRSTNAME")
user.lastname = edit_form.get_value("LASTNAME") user.lastname = edit_form.get_value("LASTNAME")
user.address = edit_form.get_value("ADDRESS") user.address = edit_form.get_value("ADDRESS")
@@ -96,18 +115,23 @@ class MemberMenu:
user.phone = edit_form.get_value("PHONE") user.phone = edit_form.get_value("PHONE")
user.update() 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.") input("Updated Member! Press any key to return.")
@staticmethod @staticmethod
def remove_member(): def remove_member():
user = MemberMenu.search_member(False) user = MemberMenu.search_member(False)
if user == None:
return
confirm = SelectionMenu("Do you want to delete selected Member?") confirm = SelectionMenu("Do you want to delete selected Member?")
confirm.add_option("Yes", True).add_option("No", False).display() confirm.add_option("Yes", True).add_option("No", False).display()
option = confirm.input_option() option = confirm.input_option()
if option == True: if option == True:
user.delete() 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.") input("Deleted Member! Press any key to return.")
@staticmethod @staticmethod

View File

@@ -1,7 +1,8 @@
from click import edit
from models.database import Database from models.database import Database
from models.user import User from models.user import User
from services.state import State
from services.log import LogService
from services.search import Search from services.search import Search
from ui.input_menu import InputMenu, Validator from ui.input_menu import InputMenu, Validator
from ui.selection_menu import SelectionMenu from ui.selection_menu import SelectionMenu
@@ -43,6 +44,16 @@ class SystemAdminMenu:
return users[select_form.get_value("INDEX")] 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 @staticmethod
def add_admin(): def add_admin():
@@ -51,21 +62,22 @@ class SystemAdminMenu:
form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None) form.add_option("FIRSTNAME", "Firstname", "STR", None, 1, 250, None)
form.add_option("LASTNAME", "Lastname", "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("ADDRESS", "Address", "STR", None, 1, 250, None)
form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, None) form.add_option("ZIPCODE", "Zipcode", "STR", None, 6, 6, Validator.check_postcode)
form.add_option("CITY_ID", "City", "STR", None, 1, 250, None)
form.add_option("EMAIL", "Email", "STR", None, 1, 250, Validator.check_email) 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("PHONE", "Phone (+31-6)", "STR", None, 8, 8, None)
form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password) form.add_option("PASSWORD", "Password", "STR", None, 1, 255, Validator.check_password)
form.do_input() form.do_input()
city_id = SystemAdminMenu.select_city()
new_user = User(Database.connection, new_user = User(Database.connection,
None, None,
"", form.get_value("USERNAME"),
form.get_value("FIRSTNAME"), form.get_value("FIRSTNAME"),
form.get_value("LASTNAME"), form.get_value("LASTNAME"),
form.get_value("ADDRESS"), form.get_value("ADDRESS"),
form.get_value("ZIPCODE"), form.get_value("ZIPCODE"),
form.get_value("CITY_ID"), city_id,
form.get_value("EMAIL"), form.get_value("EMAIL"),
"+31-6" + form.get_value("PHONE"), "+31-6" + form.get_value("PHONE"),
form.get_value("PASSWORD"), form.get_value("PASSWORD"),
@@ -73,37 +85,60 @@ class SystemAdminMenu:
) )
new_user.save() 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.") input("Added new system admin! Press any key to return.")
@staticmethod @staticmethod
def edit_admin(): def edit_admin():
user = SystemAdminMenu.search_admins(False) 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 = 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("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("FIRSTNAME", "Firstname", "STR", user.firstname, 1, 250, None)
edit_form.add_option("LASTNAME", "Lastname", "STR", user.lastname, 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("ADDRESS", "Address", "STR", user.address, 1, 250, None)
edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, None) edit_form.add_option("ZIPCODE", "Zipcode", "STR", user.zipcode, 6, 6, Validator.check_postcode)
edit_form.add_option("CITY_ID", "City", "STR", user.city_id, 1, 250, None)
edit_form.add_option("EMAIL", "Email", "STR", user.email, 1, 250, Validator.check_email) 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.add_option("PHONE", "Phone (+31-6)", "STR", user.phone, 8, 8, None)
edit_form.add_option("PASSWORD", "Password", "STR", user.phone, 1, 255, Validator.check_password)
edit_form.do_input() 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.username = edit_form.get_value("USERNAME")
user.firstname = edit_form.get_value("FIRSTNAME") user.firstname = edit_form.get_value("FIRSTNAME")
user.lastname = edit_form.get_value("LASTNAME") user.lastname = edit_form.get_value("LASTNAME")
user.address = edit_form.get_value("ADDRESS") user.address = edit_form.get_value("ADDRESS")
user.zipcode = edit_form.get_value("ZIPCODE") user.zipcode = edit_form.get_value("ZIPCODE")
user.city_id = edit_form.get_value("CITY_ID")
user.email = edit_form.get_value("EMAIL") user.email = edit_form.get_value("EMAIL")
user.phone = edit_form.get_value("PHONE") user.phone = edit_form.get_value("PHONE")
user.password = edit_form.get_value("PASSWORD")
user.update() 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.") 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 @staticmethod
def remove_admin(): def remove_admin():
user = SystemAdminMenu.search_admins(False) user = SystemAdminMenu.search_admins(False)
@@ -114,6 +149,7 @@ class SystemAdminMenu:
if option == True: if option == True:
user.delete() 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.") input("Deleted advisor! Press any key to return.")
@staticmethod @staticmethod

View File

@@ -1,86 +0,0 @@
import os
from services.state import State
from services.utils import Utils
from ui.selection_menu import SelectionMenu
from views.member_menu import MemberMenu
from views.system_admin_menu import SystemAdminMenu
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", None)
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)
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 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)
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", MemberMenu.add_member)
menu.add_option("Edit Advisor", MemberMenu.edit_member)
menu.add_option("Remove Advisor", MemberMenu.remove_member)
menu.add_option("Browse Advisor", 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_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("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()