import hashlib import json import tkinter as tk from app.models.view_models import LoginModel from app.http import request_builder from app.models.http_models import LoginRequestModel def hash_password(password): sha256_hash = hashlib.sha256() sha256_hash.update(password.encode('utf-8')) hashed_output = sha256_hash.hexdigest() return hashed_output class LoginView(tk.Frame): """ This view takes care of the validation of the user in the system. This class receives the login information and validates them. The response is shown to the user. """ def __init__(self, master=None): super().__init__(master) self.form_frame = None self.define_http_params() self.create_widgets() def define_http_params(self): self.url = "http://localhost:8000/auth/login" self.headers = {"Content-Type": "application/json"} self.method = "POST" self.params = None def create_widgets(self): """ Creates the layout of the view """ # Create a frame to hold the entry fields and labels self.form_frame = tk.Frame(self) # Error label self.error_var = tk.StringVar() # Variable to store error message self.error_label = tk.Label(self.form_frame, textvariable=self.error_var, fg="red") self.error_label.grid(row=0, column=0, pady=5, columnspan=2) # Span columns for full width # Left frame for labels label_frame = tk.Frame(self.form_frame) label_frame.grid(row=1, column=0, pady=5, padx=5, sticky="w") # Right frame for entry widgets entry_frame = tk.Frame(self.form_frame) entry_frame.grid(row=1, column=1, pady=5, padx=5, sticky="e") # Email Label and Entry self.email_label = tk.Label(label_frame, text="Email:") self.email_label.grid(row=1, column=0, pady=5, sticky="w") self.email_entry = tk.Entry(entry_frame) self.email_entry.grid(row=1, column=0, pady=5, sticky="e") # Password Label and Entry self.password_label = tk.Label(label_frame, text="Password:") self.password_label.grid(row=2, column=0, pady=5, sticky="w") self.password_entry = tk.Entry(entry_frame, show="*") self.password_entry.grid(row=2, column=0, pady=5, sticky="e") # Login Button self.signup_button = tk.Button(self.form_frame, text="Login", command=self.on_login) self.signup_button.grid(row=2, column=0, pady=10) # No columnspan for the signup button # Return to Main Menu Button self.return_button = tk.Button(self.form_frame, text="Return to Main Menu", command=self.return_to_initial_view) self.return_button.grid(row=2, column=1, pady=10, padx=5) # Place next to the signup button self.form_frame.pack() def return_to_initial_view(self): self.master.change_to_initial_view() def on_login(self): """ After login button pressed, the validation of the provided information starts and will redirect the user to next view if everything is accepted """ # Retrieve values from entry fields email = self.email_entry.get() password = self.password_entry.get() model = LoginModel(email=email, password=password) validation, errors = model.validate() if not validation: self.error_var.set(errors[0]) self.error_label.grid(row=0, column=0, pady=5) request_builder.set_url(self.url) request_builder.set_headers(self.headers) request_builder.set_params(self.params) request_builder.set_body( LoginRequestModel( email=email, password=hash_password(password) ).__dict__) request_builder.set_method(self.method) result = request_builder.build().make_request() if result.status_code == 200: self.master.get_user_information(result.text) self.master.change_to_main_page_view() else: json_data = json.loads(result.text) detail_value = json_data.get('detail') self.error_var.set(detail_value) self.error_label.grid(row=0, column=0, pady=5)