from flask import Blueprint, render_template, request, redirect, url_for, flash from flask_login import login_user, logout_user, login_required, current_user from werkzeug.security import check_password_hash from app.models import User, db from app.forms import LoginForm, RegisterForm, ForgotPasswordForm import re auth = Blueprint('auth', __name__) @auth.route('/login', methods=['GET', 'POST']) def login(): """User login page""" if current_user.is_authenticated: return redirect(url_for('main.index')) form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user and user.check_password(form.password.data): login_user(user, remember=form.remember_me.data) next_page = request.args.get('next') if not next_page or not next_page.startswith('/'): next_page = url_for('community.index') flash(f'Welcome back, {user.nickname}!', 'success') return redirect(next_page) else: flash('Invalid email or password.', 'error') return render_template('auth/login.html', form=form) @auth.route('/register', methods=['GET', 'POST']) def register(): """User registration page""" if current_user.is_authenticated: return redirect(url_for('main.index')) form = RegisterForm() if form.validate_on_submit(): # Check if user already exists if User.query.filter_by(email=form.email.data).first(): flash('Email address already registered.', 'error') return render_template('auth/register.html', form=form) if User.query.filter_by(nickname=form.nickname.data).first(): flash('Nickname already taken.', 'error') return render_template('auth/register.html', form=form) # Validate password strength if not is_valid_password(form.password.data): flash('Password must be at least 8 characters long and contain at least one letter and one number.', 'error') return render_template('auth/register.html', form=form) # Create new user user = User( nickname=form.nickname.data, email=form.email.data ) user.set_password(form.password.data) try: db.session.add(user) db.session.commit() flash('Registration successful! You can now log in.', 'success') return redirect(url_for('auth.login')) except Exception as e: db.session.rollback() flash('An error occurred during registration. Please try again.', 'error') return render_template('auth/register.html', form=form) @auth.route('/logout') @login_required def logout(): """User logout""" logout_user() flash('You have been logged out.', 'info') return redirect(url_for('main.index')) @auth.route('/forgot-password', methods=['GET', 'POST']) def forgot_password(): """Forgot password page""" if current_user.is_authenticated: return redirect(url_for('main.index')) form = ForgotPasswordForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user: # TODO: Implement email sending for password reset flash('If an account with that email exists, we\'ve sent password reset instructions.', 'info') else: flash('If an account with that email exists, we\'ve sent password reset instructions.', 'info') return redirect(url_for('auth.login')) return render_template('auth/forgot_password.html', form=form) def is_valid_password(password): """Validate password strength""" if len(password) < 8: return False if not re.search(r'[A-Za-z]', password): return False if not re.search(r'\d', password): return False return True