Files
moto-adv-website/app/routes/auth.py
ske087 6a0548b880 Final cleanup: Complete Flask motorcycle adventure app
- Removed all Node.js/Next.js dependencies and files
- Cleaned up project structure to contain only Flask application
- Updated .gitignore to exclude Python cache files, virtual environments, and development artifacts
- Complete motorcycle adventure community website with:
  * Interactive Romania map with GPX route plotting
  * Advanced post creation with cover images, sections, highlights
  * User authentication and authorization system
  * Community features with likes and comments
  * Responsive design with blue-purple-teal gradient theme
  * Docker and production deployment configuration
  * SQLite database with proper models and relationships
  * Image and GPX file upload handling
  * Modern UI with improved form layouts and visual feedback

Technical stack:
- Flask 3.0.0 with SQLAlchemy, Flask-Login, Flask-Mail, Flask-WTF
- Jinja2 templates with Tailwind CSS styling
- Leaflet.js for interactive mapping
- PostgreSQL/SQLite database support
- Docker containerization with Nginx reverse proxy
- Gunicorn WSGI server for production

Project is now production-ready Flask application focused on motorcycle adventure sharing in Romania.
2025-07-23 17:20:52 +03:00

108 lines
3.9 KiB
Python

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()
login_user(user)
flash('Registration successful! Welcome to the community!', 'success')
return redirect(url_for('community.index'))
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