from flask import Blueprint, render_template, redirect, url_for, flash from werkzeug.security import generate_password_hash, check_password_hash from flask_login import login_user, login_required, logout_user from forms.login import LoginForm from forms.signup import SignupForm from extensions import db auth = Blueprint('auth', __name__) class Person: """ Simple Person class compatible with Flask-Login. """ def __init__(self, person_id, name, email, password_hash): self.id = person_id self.name = name self.email = email self.password_hash = password_hash def get_id(self): """Required by Flask-Login to get a unique user identifier.""" return str(self.id) @property def is_authenticated(self): return True @property def is_active(self): return True @property def is_anonymous(self): return False # ------------------------- # Database helper functions # ------------------------- def get_person_by_id(person_id): """ Fetch a person record by person_id and return a Person object. """ sql = """ SELECT person_id, name, email, password_hash FROM person WHERE person_id = %s LIMIT 1 """ row = db.execute(sql, [person_id], one=True) if row: return Person(row['person_id'], row['name'], row['email'], row['password_hash']) return None def get_person_by_email(email): """ Fetch a person record by email and return a Person object. """ sql = """ SELECT person_id, name, email, password_hash FROM person WHERE email = %s LIMIT 1 """ row = db.execute(sql, [email], one=True) if row: return Person(row['person_id'], row['name'], row['email'], row['password_hash']) return None def create_person(name, email, password_hash): """ Insert a new person into the database; return the new person's ID. """ sql = """ INSERT INTO person (name, email, password_hash) VALUES (%s, %s, %s) RETURNING person_id AS person_id """ row = db.execute(sql, [name, email, password_hash], commit=True, one=True) return row['person_id'] # --------------------- # Blueprint endpoints # --------------------- @auth.route('/signup', methods=['GET', 'POST']) def signup(): form = SignupForm() if form.validate_on_submit(): hashed_password = generate_password_hash(form.password.data) create_person( name=form.name.data, email=form.email.data, password_hash=hashed_password ) flash("Account created successfully. Please log in.", "success") return redirect(url_for('auth.login')) return render_template('auth/signup.html', form=form) @auth.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): person = get_person_by_email(form.email.data) if person and check_password_hash(person.password_hash, form.password.data): login_user(person) flash("Logged in successfully.", "success") return redirect(url_for('get_calendar', person_id=person.id)) else: flash("Invalid email or password.", "danger") return render_template('auth/login.html', form=form) @auth.route('/logout') @login_required def logout(): logout_user() flash('You have been logged out.', 'success') return redirect(url_for('auth.login'))