From e0b04d13f6424aad06de6c8b259890ac45f3c382 Mon Sep 17 00:00:00 2001 From: Luke Else Date: Tue, 2 Jan 2024 22:22:14 +0000 Subject: [PATCH] Created login functinality --- controllers/database/database.py | 7 +++++++ controllers/database/user.py | 28 ++++++++++++++++++++----- controllers/web/endpoints.py | 35 ++++++++++++++++++++++++-------- models/users/admin.py | 28 ++++++++----------------- models/users/customer.py | 12 +++-------- models/users/seller.py | 27 ++++++++---------------- models/users/user.py | 20 +++++------------- scripts/create_tables.sql | 5 +++-- templates/header.html | 6 +++++- 9 files changed, 89 insertions(+), 79 deletions(-) diff --git a/controllers/database/database.py b/controllers/database/database.py index 7a6425b..e3164ce 100644 --- a/controllers/database/database.py +++ b/controllers/database/database.py @@ -1,4 +1,5 @@ from abc import ABC, abstractmethod +from typing import Mapping, Any import sqlite3 class DatabaseController(ABC): @@ -14,6 +15,12 @@ class DatabaseController(ABC): self._conn.close() print(e) + def new_instance(self, of: type, with_fields: Mapping[str, Any]): + obj = of.__new__(of) + for attr, value in with_fields.items(): + setattr(obj, attr, value) + return obj + @abstractmethod def create(self): pass diff --git a/controllers/database/user.py b/controllers/database/user.py index ef6e49a..2a73b7d 100644 --- a/controllers/database/user.py +++ b/controllers/database/user.py @@ -1,30 +1,48 @@ from .database import DatabaseController from models.users.user import User +from models.users.customer import Customer class UserController(DatabaseController): + FIELDS = ['id', 'username', 'password', 'firstName', 'lastName', 'email', 'phone', 'role'] def __init__(self): super().__init__() def create(self, user: User): params = [ + user.username, + user.password, user.firstName, user.lastName, user.email, user.phone, - user.password, user.role ] self._conn.execute( - "INSERT INTO Users (first_name, last_name, email, phone, password, role) VALUES (?, ?, ?, ?, ?, ?)", + "INSERT INTO Users (username, password, first_name, last_name, email, phone, role) VALUES (?, ?, ?, ?, ?, ?, ?)", params ) self._conn.commit() - user.login() - def read(self): - print("Doing work") + def read(self, username: str) -> User | None: + params = [ + username + ] + + cursor = self._conn.execute( + "SELECT * FROM Users WHERE Username = ?", + params + ) + row = cursor.fetchone() + + if row != None: + params = dict(zip(self.FIELDS, row)) + obj = self.new_instance(Customer, params) + print(obj.__dict__) + return obj + + return None def update(self): print("Doing work") diff --git a/controllers/web/endpoints.py b/controllers/web/endpoints.py index 3661328..ebbef7b 100644 --- a/controllers/web/endpoints.py +++ b/controllers/web/endpoints.py @@ -1,5 +1,5 @@ from . import blueprint -from flask import render_template, redirect, request +from flask import render_template, redirect, request, session from controllers.database.user import UserController from models.users.customer import Customer from hashlib import sha512 @@ -8,7 +8,7 @@ from hashlib import sha512 # Function responsible for displaying the main landing page of the site @blueprint.route('/') def welcome_page(): - return render_template('index.html', content="content.html") + return render_template('index.html', content="content.html", user = session.get('user')) @@ -16,12 +16,23 @@ def welcome_page(): # Function responsible for delivering the Login page for the site @blueprint.route('/login') def display_login(): - return render_template('index.html', content="login.html") + return render_template('index.html', content="login.html", user = session.get('user')) # Function responsible for handling logins to the site @blueprint.post('/login') def login(): - print("Tryin to login as " + request.form['username']) + database = UserController() + user = database.read(request.form['username']) + + # No user found + if user == None: + return redirect("/login") + + # Incorrect Password + if sha512(request.form['password'].encode()).hexdigest() != user.password: + return redirect("/login") + + session['user'] = user.username return redirect("/") @@ -29,7 +40,7 @@ def login(): # Function responsible for delivering the Signup page for the site @blueprint.route('/signup') def display_signup(): - return render_template('index.html', content="signup.html") + return render_template('index.html', content="signup.html", user = session.get('user')) # Function responsible for handling signups to the site @blueprint.post('/signup') @@ -38,12 +49,20 @@ def signup(): database.create(Customer( 0, request.form['username'], - request.form['email'], + sha512(request.form['password'].encode()).hexdigest(), # Hashed as soon as it is recieved on the backend request.form['firstname'], request.form['lastname'], + request.form['email'], "123", - sha512(request.form['password'].encode()).hexdigest(), # Hashed as soon as it is recieved on the backend "Customer" )) - return redirect("/") + # Code 307 Preserves the original request (POST) + return redirect("/login", code=307) + + +# Function responsible for handling logouts from the site +@blueprint.route('/logout') +def logout(): + session.pop('user') + return redirect("/") \ No newline at end of file diff --git a/models/users/admin.py b/models/users/admin.py index 8a36525..917907f 100644 --- a/models/users/admin.py +++ b/models/users/admin.py @@ -2,24 +2,12 @@ from .user import User class Admin(User): ''' - Class constructor to instatiate an Admin object + Class constructor to instatiate an admin object + + No additional properties are assigned to the admin ''' - def __init__(self): - super().__init__() - self.store = "" - - def login(self): - print("Logging in as Admin") - - def signup(self): - print("Signing up as Admin") - - def createProduct(): - pass - - def deleteProduct(): - pass - - def updateProduct(): - pass - + def __init__(self, id: int, username: str, password: str, firstname: str, + lastname: str, email: str, phone: str, role: str): + super().__init__( + id, username, password, firstname, lastname, email, phone, role + ) diff --git a/models/users/customer.py b/models/users/customer.py index b7c874e..34a5e64 100644 --- a/models/users/customer.py +++ b/models/users/customer.py @@ -6,15 +6,9 @@ class Customer(User): No additional properties are assigned to the customer ''' - def __init__(self, id: int, username: str, email: str, firstname: str, - lastname: str, phone: str, password: str, role: str): + def __init__(self, id: int, username: str, password: str, firstname: str, + lastname: str, email: str, phone: str, role: str): super().__init__( - id, username, email, firstname, lastname, phone, password, role + id, username, password, firstname, lastname, email, phone, role ) - def login(self): - print("Logging in as Customer") - - def signup(self): - print("Signing up as Customer") - diff --git a/models/users/seller.py b/models/users/seller.py index e16fc62..57473ac 100644 --- a/models/users/seller.py +++ b/models/users/seller.py @@ -2,24 +2,13 @@ from .user import User class Seller(User): ''' - Class constructor to instatiate a Seller object + Class constructor to instatiate a customer object + + No additional properties are assigned to the customer ''' - def __init__(self): - super().__init__() + def __init__(self, id: int, username: str, password: str, firstname: str, + lastname: str, email: str, phone: str, role: str): + super().__init__( + id, username, password, firstname, lastname, email, phone, role + ) self.store = "" - - def login(self): - print("Logging in as Seller") - - def signup(self): - print("Signing up as Seller") - - def createProduct(): - pass - - def deleteProduct(): - pass - - def updateProduct(): - pass - diff --git a/models/users/user.py b/models/users/user.py index e4d26f4..e282500 100644 --- a/models/users/user.py +++ b/models/users/user.py @@ -1,25 +1,15 @@ -from abc import ABC, abstractmethod +from abc import ABC class User(ABC): """ Functional Class constructor to initialise all properties in the base object with a value """ - def __init__(self, id: int, username: str, email: str, firstname: str, - lastname: str, phone: str, password: str, role: str): + def __init__(self, id: int, username: str, password: str, firstname: str, + lastname: str, email: str, phone: str, role: str): self.id = id self.username = username - self.email = email + self.password = password self.firstName = firstname self.lastName = lastname + self.email = email self.phone = phone - self.password = password self.role= role - - - @abstractmethod - def login(self): - pass - - @abstractmethod - def signup(self): - pass - diff --git a/scripts/create_tables.sql b/scripts/create_tables.sql index 893c556..efe7afc 100644 --- a/scripts/create_tables.sql +++ b/scripts/create_tables.sql @@ -1,10 +1,11 @@ CREATE TABLE IF NOT EXISTS Users ( id INTEGER PRIMARY KEY, + username TEXT NOT NULL UNIQUE, + password TEXT NOT NULL, first_name TEXT NOT NULL, last_name TEXT NOT NULL, email TEXT NOT NULL UNIQUE, - phone TEXT NOT NULL UNIQUE, - password TEXT NOT NULL, + phone TEXT NOT NULL, role TEXT NOT NULL ); diff --git a/templates/header.html b/templates/header.html index 70abf42..0558afe 100644 --- a/templates/header.html +++ b/templates/header.html @@ -4,7 +4,11 @@ - Login/Signup + {% if user != None: %} + Welcome, {{ user }} + {% else %} + Login/Signup + {% endif %}