feat: implement initial admin setup (Story 1.1)
Add complete initial admin setup functionality including: - SetupForm with email, password, and password confirmation fields - Password validation (minimum 12 characters) and confirmation matching - Email format validation - Setup route with GET (display form) and POST (process setup) handlers - bcrypt password hashing before storing admin credentials - Auto-login after successful setup with session management - First-run detection middleware that redirects to /setup if no admin exists - Setup page returns 404 after admin account is created - Base HTML template with Pico CSS integration - Admin dashboard placeholder template - 404 error template All tests pass with 90.09% code coverage (exceeds 80% requirement). Code passes ruff linting and mypy type checking. Story: 1.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
5
src/routes/__init__.py
Normal file
5
src/routes/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
"""Route blueprints for Sneaky Klaus application."""
|
||||
|
||||
from src.routes.setup import setup_bp
|
||||
|
||||
__all__ = ["setup_bp"]
|
||||
15
src/routes/admin.py
Normal file
15
src/routes/admin.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""Admin routes for Sneaky Klaus application."""
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
admin_bp = Blueprint("admin", __name__, url_prefix="/admin")
|
||||
|
||||
|
||||
@admin_bp.route("/dashboard")
|
||||
def dashboard():
|
||||
"""Display admin dashboard.
|
||||
|
||||
Returns:
|
||||
Rendered admin dashboard template.
|
||||
"""
|
||||
return render_template("admin/dashboard.html")
|
||||
53
src/routes/setup.py
Normal file
53
src/routes/setup.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""Setup route for initial admin account creation."""
|
||||
|
||||
from flask import Blueprint, abort, redirect, render_template, session, url_for
|
||||
|
||||
from src.app import bcrypt, db
|
||||
from src.forms import SetupForm
|
||||
from src.models import Admin
|
||||
|
||||
setup_bp = Blueprint("setup", __name__)
|
||||
|
||||
|
||||
@setup_bp.route("/setup", methods=["GET", "POST"])
|
||||
def setup():
|
||||
"""Handle initial admin account setup.
|
||||
|
||||
GET: Display the setup form if no admin exists.
|
||||
POST: Process the setup form, create admin account, and log in.
|
||||
|
||||
Returns:
|
||||
On GET: Rendered setup form template.
|
||||
On POST success: Redirect to admin dashboard.
|
||||
On POST error: Re-render form with validation errors.
|
||||
404 if admin already exists.
|
||||
"""
|
||||
# Check if admin already exists
|
||||
admin_count = db.session.query(Admin).count()
|
||||
if admin_count > 0:
|
||||
abort(404)
|
||||
|
||||
form = SetupForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
# Create admin account
|
||||
password_hash = bcrypt.generate_password_hash(form.password.data).decode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
admin = Admin(
|
||||
email=form.email.data,
|
||||
password_hash=password_hash,
|
||||
)
|
||||
|
||||
db.session.add(admin)
|
||||
db.session.commit()
|
||||
|
||||
# Log in the admin by setting session
|
||||
session["admin_id"] = admin.id
|
||||
session["admin_email"] = admin.email
|
||||
|
||||
# Redirect to admin dashboard
|
||||
return redirect(url_for("admin.dashboard"))
|
||||
|
||||
return render_template("setup.html", form=form)
|
||||
Reference in New Issue
Block a user