login si signin done
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
from .login import login
|
||||||
|
from app.models import Login
|
||||||
|
from app.models import User
|
||||||
|
from .signup import signup
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/login")
|
||||||
|
async def login_router(login_info: Login):
|
||||||
|
return await login(login_info)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/sign_up")
|
||||||
|
async def signup_router(user: User):
|
||||||
|
return await signup(user)
|
||||||
|
|||||||
@@ -1 +1,13 @@
|
|||||||
|
from fastapi import HTTPException
|
||||||
from app.models.login import Login
|
from app.models.login import Login
|
||||||
|
from database.queries.user import get_user_by_email
|
||||||
|
|
||||||
|
|
||||||
|
async def login(login_info: Login):
|
||||||
|
result = get_user_by_email(login_info.email)
|
||||||
|
if not result:
|
||||||
|
raise HTTPException(status_code=404, detail='User not in system.')
|
||||||
|
|
||||||
|
password, email = result[2], result[3]
|
||||||
|
if login_info.email != email or login_info.password != password:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid credentials.")
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
from fastapi import HTTPException
|
||||||
|
from app.models.user import User
|
||||||
|
from database.queries.user import get_user_by_email, create_user_db
|
||||||
|
|
||||||
|
|
||||||
|
async def signup(user: User):
|
||||||
|
result = get_user_by_email(user.email)
|
||||||
|
if result:
|
||||||
|
raise HTTPException(status_code=409, detail='User already exists.')
|
||||||
|
|
||||||
|
print(user.username, user.email, user.password)
|
||||||
|
|
||||||
|
create_user_db(username=user.username, password=user.password, email=user.email)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -6,12 +6,13 @@ from database.queries.user import get_user_by_email, create_user_db
|
|||||||
async def create_user(user: User):
|
async def create_user(user: User):
|
||||||
result = get_user_by_email(user.email)
|
result = get_user_by_email(user.email)
|
||||||
if result:
|
if result:
|
||||||
raise HTTPException(status_code=409, detail='User already exists')
|
raise HTTPException(status_code=409, detail='User already exists.')
|
||||||
|
|
||||||
|
print(user.username, user.email, user.password)
|
||||||
|
|
||||||
create_user_db(username=user.username, password=user.password, email=user.email)
|
create_user_db(username=user.username, password=user.password, email=user.email)
|
||||||
created_user = get_user_by_email(user.email)
|
created_user = get_user_by_email(user.email)
|
||||||
created_user_dict = {
|
created_user_dict = {
|
||||||
"id": created_user[0],
|
|
||||||
"username": created_user[1],
|
"username": created_user[1],
|
||||||
"password": created_user[2],
|
"password": created_user[2],
|
||||||
"email": created_user[3],
|
"email": created_user[3],
|
||||||
|
|||||||
Binary file not shown.
@@ -1,8 +1,10 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from api.v1.endpoints.users import router as users_router
|
from api.v1.endpoints.users import router as users_router
|
||||||
from api.v1.endpoints.messages import router as messages_router
|
from api.v1.endpoints.messages import router as messages_router
|
||||||
|
from api.v1.endpoints.auth import router as auth_router
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
app.include_router(users_router, tags=["Users"], prefix="/users")
|
app.include_router(users_router, tags=["Users"], prefix="/users")
|
||||||
app.include_router(messages_router, tags=["Messages"], prefix="/messages")
|
app.include_router(messages_router, tags=["Messages"], prefix="/messages")
|
||||||
|
app.include_router(auth_router, tags=["Auth"], prefix="/auth")
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
from .user import User
|
from .user import User
|
||||||
from .message import Message
|
from .message import Message
|
||||||
|
from .login import Login
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,6 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
id: int
|
|
||||||
username: str
|
username: str
|
||||||
password: str
|
password: str
|
||||||
email: str
|
email: str
|
||||||
|
|||||||
@@ -3,26 +3,32 @@ from .request_handler import _HttpRequestHandler
|
|||||||
|
|
||||||
class RequestBuilder:
|
class RequestBuilder:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.url = ""
|
self.__url = ""
|
||||||
self.headers = {}
|
self.__headers = {}
|
||||||
self.body = None
|
self.__body = None
|
||||||
self.method = "GET"
|
self.__params = None
|
||||||
|
self.__method = "GET"
|
||||||
|
|
||||||
def set_url(self, url):
|
def set_url(self, url=str):
|
||||||
self.url = url
|
self.__url = url
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_headers(self, headers):
|
def set_headers(self, headers=dict):
|
||||||
self.headers = headers
|
self.__headers = headers
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_body(self, body):
|
def set_body(self, body=dict):
|
||||||
self.body = body
|
self.__body = body
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_method(self, method):
|
def set_params(self, params=dict):
|
||||||
self.method = method
|
self.__params = params
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_method(self, method=str):
|
||||||
|
self.__method = method
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
return _HttpRequestHandler(self.url)
|
return _HttpRequestHandler(url=self.__url, method=self.__method, body=self.__body,
|
||||||
|
params=self.__params, headers=self.__headers)
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class _HttpRequestHandler:
|
class _HttpRequestHandler:
|
||||||
def __init__(self, base_url):
|
def __init__(self, url, method="GET", params=None, headers=None, body=None):
|
||||||
self.base_url = base_url
|
self.url = url
|
||||||
|
self.method = method
|
||||||
|
self.headers = headers
|
||||||
|
print(body)
|
||||||
|
self.body = json.dumps(body)
|
||||||
|
self.params = params
|
||||||
|
|
||||||
def make_request(self, method, endpoint, params=None, data=None, headers=None):
|
def make_request(self):
|
||||||
url = f"{self.base_url}/{endpoint}"
|
print(self.body)
|
||||||
response = requests.request(method, url, params=params, data=data, headers=headers)
|
response = requests.request(method=self.method, url=self.url,
|
||||||
|
params=self.params, data=self.body, headers=self.headers)
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -12,21 +12,26 @@ class MainApplication(tk.Tk):
|
|||||||
|
|
||||||
screen_height = self.winfo_screenheight()
|
screen_height = self.winfo_screenheight()
|
||||||
self.geometry(f"{screen_height // 2}x{screen_height // 2}")
|
self.geometry(f"{screen_height // 2}x{screen_height // 2}")
|
||||||
|
|
||||||
# Create instances of the views
|
|
||||||
self.login_view = LoginView(self)
|
|
||||||
self.initial_view = InitialView(self)
|
|
||||||
self.signup_view = SignupView(self)
|
|
||||||
self.main_view = tk.Label(self, text="Main View")
|
|
||||||
|
|
||||||
self.current_view = None
|
self.current_view = None
|
||||||
self.change_view(self.initial_view)
|
|
||||||
|
self.change_to_initial_view()
|
||||||
|
|
||||||
|
def change_to_initial_view(self):
|
||||||
|
self.change_view(InitialView(self))
|
||||||
|
|
||||||
|
def change_to_sing_in_view(self):
|
||||||
|
self.change_view(SignupView(self))
|
||||||
|
|
||||||
|
def change_to_login_view(self):
|
||||||
|
self.change_view(LoginView(self))
|
||||||
|
|
||||||
def change_view(self, view: tk.Frame):
|
def change_view(self, view: tk.Frame):
|
||||||
if self.current_view:
|
if self.current_view:
|
||||||
self.current_view.pack_forget()
|
self.current_view.destroy()
|
||||||
|
|
||||||
self.current_view = view
|
self.current_view = view
|
||||||
self.current_view.pack(expand=True, fill=tk.BOTH)
|
self.current_view.pack(expand=True, fill=tk.BOTH)
|
||||||
self.current_view.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
|
self.current_view.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
from .login import LoginRequestModel
|
||||||
|
from .signup import SignupRequestModel
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class LoginRequestModel:
|
||||||
|
def __init__(self, email, password):
|
||||||
|
self.email = email
|
||||||
|
self.password = password
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class SignupRequestModel:
|
||||||
|
def __init__(self, username, email, password):
|
||||||
|
self.username = username
|
||||||
|
self.email = email
|
||||||
|
self.password = password
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
from .login import LoginModel
|
||||||
|
from .signup import SignupModel
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class LoginModel:
|
||||||
|
def __init__(self, password: str, email: str):
|
||||||
|
self.password = password
|
||||||
|
self.email = email
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# Check if username, password, and email are provided
|
||||||
|
if not self.email:
|
||||||
|
errors.append("Email is required.")
|
||||||
|
|
||||||
|
email_pattern = re.compile(r"[^@]+@[^@]+\.[^@]+")
|
||||||
|
if not email_pattern.match(self.email):
|
||||||
|
errors.append("Invalid email format.")
|
||||||
|
|
||||||
|
if not self.password:
|
||||||
|
errors.append("Password is required.")
|
||||||
|
if len(self.password) < 8:
|
||||||
|
errors.append("Password must be at least 8 characters.")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
return False, errors
|
||||||
|
|
||||||
|
# If all validations pass, return True
|
||||||
|
return True, []
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import re
|
|||||||
|
|
||||||
|
|
||||||
class SignupModel:
|
class SignupModel:
|
||||||
def __init__(self, username:str, password:str, email:str):
|
def __init__(self, username: str, password: str, email: str):
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
self.email = email
|
self.email = email
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ class InitialView(tk.Frame):
|
|||||||
signin_button.pack(side=tk.RIGHT, padx=5)
|
signin_button.pack(side=tk.RIGHT, padx=5)
|
||||||
|
|
||||||
def on_login(self):
|
def on_login(self):
|
||||||
self.master.change_view(self.master.login_view)
|
self.master.change_to_login_view()
|
||||||
|
|
||||||
def on_signin(self):
|
def on_signin(self):
|
||||||
self.master.change_view(self.master.signup_view)
|
self.master.change_to_sing_in_view()
|
||||||
pass
|
|
||||||
|
|
||||||
@@ -1,36 +1,102 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
import tkinter as tk
|
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):
|
class LoginView(tk.Frame):
|
||||||
def __init__(self, master=None):
|
def __init__(self, master=None):
|
||||||
super().__init__(master)
|
super().__init__(master)
|
||||||
|
self.form_frame = None
|
||||||
|
self.define_http_params()
|
||||||
self.create_widgets()
|
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):
|
def create_widgets(self):
|
||||||
# Username Label and Entry
|
# Create a frame to hold the entry fields and labels
|
||||||
username_label = tk.Label(self, text="Username:")
|
self.form_frame = tk.Frame(self)
|
||||||
username_label.pack(pady=5)
|
|
||||||
self.username_entry = tk.Entry(self)
|
# Error label
|
||||||
self.username_entry.pack(pady=5)
|
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
|
# Password Label and Entry
|
||||||
password_label = tk.Label(self, text="Password:")
|
self.password_label = tk.Label(label_frame, text="Password:")
|
||||||
password_label.pack(pady=5)
|
self.password_label.grid(row=2, column=0, pady=5, sticky="w")
|
||||||
self.password_entry = tk.Entry(self, show="*") # Use show="*" to hide password characters
|
|
||||||
self.password_entry.pack(pady=5)
|
self.password_entry = tk.Entry(entry_frame, show="*")
|
||||||
|
self.password_entry.grid(row=2, column=0, pady=5, sticky="e")
|
||||||
|
|
||||||
# Login Button
|
# Login Button
|
||||||
login_button = tk.Button(self, text="Submit", command=self.on_login)
|
self.signup_button = tk.Button(self.form_frame, text="Login", command=self.on_login)
|
||||||
login_button.pack(pady=10)
|
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):
|
def on_login(self):
|
||||||
# Retrieve username and password values
|
# Retrieve values from entry fields
|
||||||
username = self.username_entry.get()
|
email = self.email_entry.get()
|
||||||
password = self.password_entry.get()
|
password = self.password_entry.get()
|
||||||
|
|
||||||
# Example: Check credentials (you'll need to implement your own logic)
|
model = LoginModel(email=email, password=password)
|
||||||
if username == "example" and password == "password":
|
validation, errors = model.validate()
|
||||||
self.master.show_main_view()
|
|
||||||
|
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.change_to_initial_view()
|
||||||
else:
|
else:
|
||||||
print("Invalid credentials")
|
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)
|
||||||
@@ -1,27 +1,46 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from app.models.view_models.signup import SignupModel
|
from app.models.view_models import SignupModel
|
||||||
|
from app.http import request_builder
|
||||||
|
from app.models.http_models import SignupRequestModel
|
||||||
|
|
||||||
|
|
||||||
|
def hash_password(password):
|
||||||
|
sha256_hash = hashlib.sha256()
|
||||||
|
sha256_hash.update(password.encode('utf-8'))
|
||||||
|
hashed_output = sha256_hash.hexdigest()
|
||||||
|
return hashed_output
|
||||||
|
|
||||||
|
|
||||||
class SignupView(tk.Frame):
|
class SignupView(tk.Frame):
|
||||||
def __init__(self, master=None):
|
def __init__(self, master=None):
|
||||||
super().__init__(master)
|
super().__init__(master)
|
||||||
|
self.form_frame = None
|
||||||
|
self.define_http_params()
|
||||||
self.create_widgets()
|
self.create_widgets()
|
||||||
|
|
||||||
|
def define_http_params(self):
|
||||||
|
self.url = "http://localhost:8000/auth/sign_up"
|
||||||
|
self.headers = {"Content-Type": "application/json"}
|
||||||
|
self.method = "POST"
|
||||||
|
self.params = None
|
||||||
|
|
||||||
def create_widgets(self):
|
def create_widgets(self):
|
||||||
# Create a frame to hold the entry fields and labels
|
# Create a frame to hold the entry fields and labels
|
||||||
form_frame = tk.Frame(self)
|
self.form_frame = tk.Frame(self)
|
||||||
|
|
||||||
# Error label
|
# Error label
|
||||||
self.error_var = tk.StringVar() # Variable to store error message
|
self.error_var = tk.StringVar() # Variable to store error message
|
||||||
self.error_label = tk.Label(form_frame, textvariable=self.error_var, fg="red")
|
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
|
self.error_label.grid(row=0, column=0, pady=5, columnspan=2) # Span columns for full width
|
||||||
|
|
||||||
# Left frame for labels
|
# Left frame for labels
|
||||||
label_frame = tk.Frame(form_frame)
|
label_frame = tk.Frame(self.form_frame)
|
||||||
label_frame.grid(row=1, column=0, pady=5, padx=5, sticky="w")
|
label_frame.grid(row=1, column=0, pady=5, padx=5, sticky="w")
|
||||||
|
|
||||||
# Right frame for entry widgets
|
# Right frame for entry widgets
|
||||||
entry_frame = tk.Frame(form_frame)
|
entry_frame = tk.Frame(self.form_frame)
|
||||||
entry_frame.grid(row=1, column=1, pady=5, padx=5, sticky="e")
|
entry_frame.grid(row=1, column=1, pady=5, padx=5, sticky="e")
|
||||||
|
|
||||||
# Username Label and Entry
|
# Username Label and Entry
|
||||||
@@ -46,10 +65,17 @@ class SignupView(tk.Frame):
|
|||||||
self.password_entry.grid(row=2, column=0, pady=5, sticky="e")
|
self.password_entry.grid(row=2, column=0, pady=5, sticky="e")
|
||||||
|
|
||||||
# Signup Button
|
# Signup Button
|
||||||
self.signup_button = tk.Button(form_frame, text="Signup", command=self.on_signup)
|
self.signup_button = tk.Button(self.form_frame, text="Sign up", command=self.on_signup)
|
||||||
self.signup_button.grid(row=2, column=0, columnspan=2, pady=10) # Span columns for full width
|
self.signup_button.grid(row=2, column=0, pady=10) # No columnspan for the signup button
|
||||||
|
|
||||||
form_frame.pack()
|
# 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_signup(self):
|
def on_signup(self):
|
||||||
# Retrieve values from entry fields
|
# Retrieve values from entry fields
|
||||||
@@ -64,5 +90,22 @@ class SignupView(tk.Frame):
|
|||||||
self.error_var.set(errors[0])
|
self.error_var.set(errors[0])
|
||||||
self.error_label.grid(row=0, column=0, pady=5)
|
self.error_label.grid(row=0, column=0, pady=5)
|
||||||
|
|
||||||
# Print or handle the values as needed
|
request_builder.set_url(self.url)
|
||||||
print(f"Username: {username}, Email: {email}, Password: {password}")
|
request_builder.set_headers(self.headers)
|
||||||
|
request_builder.set_params(self.params)
|
||||||
|
request_builder.set_body(
|
||||||
|
SignupRequestModel(
|
||||||
|
username=username,
|
||||||
|
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.change_to_initial_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)
|
||||||
|
|||||||
Reference in New Issue
Block a user