I created a simple login program that works how I wanted them to work. I separated the GUI and database codes into two different python files. I named the files as login.py and dbaseManip.py. The login.py consist of Tkinter syntax and all stuff related to GUI. On the other hand, dbaseManip.py holds the database related syntax such as the connection and the queries.
login.py
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
import dbaseManip as db
class loginForm(ttk.Frame):
def __init__(self,parent,*arags,**kwargs):
tk.Frame.__init__(self,parent)
self.parent = parent
self.parent.protocol("WM_DELETE_WINDOW",self.closing_window)
window_width = 350
window_height = 100
screen_width = self.parent.winfo_screenwidth()
screen_height = self.parent.winfo_screenheight()
x_position = int((screen_width/2) - (window_width/2))
y_position = int((screen_height/2) - (window_height/2))
self.parent.geometry("{}x{}+{}+{}".format(window_width,window_height,x_position,y_position))
self.widgeter()
def widgeter(self):
self.ent_username = ttk.Entry(self.parent)
self.ent_username.insert(0,"username")
self.ent_username.bind("<FocusIn>",self.foc_in_username)
self.ent_username.bind("<FocusOut>",self.foc_out_username)
self.ent_password = ttk.Entry(self.parent)
self.ent_password.insert(0,"password")
self.ent_password.bind("<FocusIn>",self.foc_in_password)
self.ent_password.bind("<FocusOut>",self.foc_out_password)
btn_login = ttk.Button(self.parent,text="Login",command=self.submit)
btn_exit = ttk.Button(self.parent,text="Exit",command=self.closing_window)
self.ent_username.grid(row=0,column=0,columnspan=3,sticky="nsew")
self.ent_password.grid(row=1,column=0,columnspan=3,sticky="nsew")
btn_login.grid(row=2,column=0,sticky="nsw")
btn_exit.grid(row=2,column=1,sticky="nse")
def foc_in_username(self, *args):
if self.ent_username.get() == "username":
self.ent_username.delete(0, tk.END)
def foc_out_username(self,*args):
if not self.ent_username.get():
self.ent_username.insert(0,"username")
def foc_in_password(self,*args):
if self.ent_password.get() == "password":
self.ent_password.delete(0,tk.END)
self.ent_password.configure(show="*")
def foc_out_password(self,*args):
if not self.ent_password.get():
self.ent_password.insert(0,"password")
self.ent_password.configure(show="")
def closing_window(self):
answer = messagebox.askyesno("Exit","You want to exit the program?")
if answer == True:
self.parent.destroy()
def submit(self):
__verify = db.DatabaseManip(self.ent_username.get(),self.ent_password.get())
__str_verify = str(__verify)
if __str_verify == "correct":
self.initialize_mainApplication()
elif __str_verify is "incorrect":
messagebox.showerror("Incorrect Password","You have entered incorrect password")
# add deleter
elif __str_verify == "notexist":
messagebox.showerror("Username does not exist","The username you entered does not exist")
def initialize_mainApplication(self):
self.parent.destroy()
self.parent = tk.Tk()
self.mainApp = mainApplicaiton(self.parent)
self.parent.mainloop()
class mainApplicaiton(tk.Frame):
def __init__(self,parent):
self.parent = parent
if __name__ == "__main__":
root = tk.Tk()
loginForm(root)
root.mainloop()
dbaseManip.py
import mysql.connector
class DatabaseManip():
def __init__(self,username,password):
self.username = username
self.password = password
#
# print(self.username)
# print(self.password)
self.dbaseInitializer()
def dbaseInitializer(self):
mydb = mysql.connector.connect(
host="127.0.0.1",
user="root",
password="admin123",
database="testdb"
)
self.myCursor = mydb.cursor()
query_user_exists = "SELECT EXISTS(SELECT * FROM users WHERE username = %s)"
self.myCursor.execute(query_user_exists,(self.username,))
tuple_user_exists = self.myCursor.fetchone()
total_user_exists = int(tuple_user_exists[0])
if total_user_exists != 0:
query_pass_validation = "SELECT password FROM users WHERE username = %s"
self.myCursor.execute(query_pass_validation,(self.username,))
__tuple_valid_pass = self.myCursor.fetchone()
__password_validation = __tuple_valid_pass[0]
if __password_validation == self.password:
self.verdict = "correct"
else:
self.verdict = "incorrect"
else:
self.verdict = "notexist"
def __str__(self):
return self.verdict
@property
def username(self):
return self.__username
@username.setter
def username(self,username):
self.__username = username
@property
def password(self):
return self.__password
@password.setter
def password(self,password):
self.__password = password
This is how the system works:
- The login form will pop up
- After the user submitting their username and password, it will call the class DatabaseManip() that exists in dbaseManip.py.
- The DatabaseManip Class will validate the user's account.
- HERE COMES MY PROBLEM If the username does not exist in the database, it will assign a string "notexist" to a class variable called verdict. If the password is wrong, it will assign "incorrect". And lastly, if the validation is correct; it will assign "correct".
- The verdict result (which is either "correct","incorrect" or "notexist") will be returned to the GUI class in login.py using the
__str__
method. - In the loginForm class, a conditional statement will determine if the verdict from the databaseManip class is either "correct","incorrect" or "notexist". If it is "correct", a new window will pop-up. On the other hand, if it is either "incorrect" or "notexist", it will show an error message.
I think my way of coding this is extremely bad in terms of security and integrity. I'm not confident in the "correct", "incorrect", and "notexit" part. I would like to ask for advice to make this program more secure and not as wacky as the current state.