from flask import Flask, g, redirect, url_for, render_template, session import datetime import os import secrets from app.core.extensions import db, migrate, login_manager, bcrypt, limiter from app.core.csrf_utils import init_csrf from app.core.auth import User, load_user from app.core.context_processors import inject_breadcrumbs def create_app(config_name="development"): app = Flask(__name__, static_folder="static", template_folder="templates") # Load configuration if config_name == "production": app.config.from_object("config.ProductionConfig") elif config_name == "testing": app.config.from_object("config.TestingConfig") else: app.config.from_object("config.DevelopmentConfig") # Ensure SECRET_KEY is set if not app.config.get('SECRET_KEY'): app.config['SECRET_KEY'] = secrets.token_hex(32) # Initialize extensions db.init_app(app) migrate.init_app(app, db) login_manager.init_app(app) bcrypt.init_app(app) init_csrf(app) limiter.init_app(app) # Initialize login manager @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) login_manager.login_view = "auth.login" login_manager.login_message = "Please log in to access this page." login_manager.login_message_category = "info" # Register template filters from app.core.template_filters import bp as filters_bp from app.core.template_filters import markdown_filter app.register_blueprint(filters_bp) # Register the markdown filter directly app.jinja_env.filters['markdown'] = markdown_filter # Create database tables with app.app_context(): try: db.create_all() print("Database tables created successfully") except Exception as e: print(f"Error with database setup: {e}") # Register blueprints from app.routes import auth, dashboard, ipam app.register_blueprint(auth.bp) app.register_blueprint(dashboard.bp) app.register_blueprint(ipam.bp) # Register API routes from app.routes import api app.register_blueprint(api.bp) from app.routes.importexport import bp as importexport_bp app.register_blueprint(importexport_bp) # Add static assets blueprint from app.routes.static import bp as static_bp app.register_blueprint(static_bp) # Add session handling @app.before_request def make_session_permanent(): session.permanent = True # Add error handlers @app.errorhandler(404) def page_not_found(e): return render_template("errors/404.html", title="Page Not Found"), 404 @app.errorhandler(500) def internal_server_error(e): return render_template("errors/500.html", title="Server Error"), 500 @app.errorhandler(403) def forbidden(e): return render_template("errors/403.html", title="Forbidden"), 403 # Session configuration app.config['SESSION_TYPE'] = 'filesystem' app.config['SESSION_FILE_DIR'] = os.path.join(os.getcwd(), 'instance/sessions') app.config['SESSION_PERMANENT'] = True app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour in seconds # Ensure the sessions directory exists os.makedirs(app.config['SESSION_FILE_DIR'], exist_ok=True) # Debug CSRF issues @app.after_request def after_request(response): if app.debug: # Only in development print(f"Session contains CSRF token: {'csrf_token' in session}") print(f"CSRF header name: {app.config.get('WTF_CSRF_HEADERS')}") return response # Register context processors app.context_processor(inject_breadcrumbs) return app