Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update backend/__init__.py
Browse files- backend/__init__.py +82 -0
backend/__init__.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# pyright: reportGeneralTypeIssues=false, reportAttributeAccessIssue=false
|
| 2 |
+
from flask import Flask
|
| 3 |
+
from .config import Config, _is_redis_running
|
| 4 |
+
from .extensions import db, celery, socketio, limiter, cache
|
| 5 |
+
from flask_cors import CORS
|
| 6 |
+
|
| 7 |
+
def create_app():
|
| 8 |
+
app = Flask(__name__)
|
| 9 |
+
app.config.from_object(Config)
|
| 10 |
+
|
| 11 |
+
# Initialize extensions
|
| 12 |
+
db.init_app(app)
|
| 13 |
+
from .extensions import migrate
|
| 14 |
+
migrate.init_app(app, db) # type: ignore
|
| 15 |
+
socketio.init_app(app, cors_allowed_origins="*") # type: ignore
|
| 16 |
+
app.socketio = socketio # type: ignore
|
| 17 |
+
|
| 18 |
+
# Configure Caching dynamically based on Redis availability
|
| 19 |
+
redis_url = app.config.get('CELERY_BROKER_URL', 'redis://localhost:6379/0')
|
| 20 |
+
if _is_redis_running(redis_url):
|
| 21 |
+
app.config['CACHE_TYPE'] = 'RedisCache'
|
| 22 |
+
app.config['CACHE_REDIS_URL'] = redis_url
|
| 23 |
+
else:
|
| 24 |
+
app.config['CACHE_TYPE'] = 'SimpleCache'
|
| 25 |
+
|
| 26 |
+
cache.init_app(app)
|
| 27 |
+
|
| 28 |
+
# Initialize Firebase Cloud Storage (for logos, PDFs, and file uploads)
|
| 29 |
+
try:
|
| 30 |
+
from backend.utils.firebase_storage import init_firebase
|
| 31 |
+
except ImportError:
|
| 32 |
+
from utils.firebase_storage import init_firebase
|
| 33 |
+
init_firebase()
|
| 34 |
+
|
| 35 |
+
# Optional Celery config update
|
| 36 |
+
celery.conf.update(
|
| 37 |
+
broker_url=redis_url,
|
| 38 |
+
result_backend=app.config.get('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0')
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
CORS(app, resources={r"/api/*": {"origins": "*"}}) # type: ignore
|
| 42 |
+
|
| 43 |
+
with app.app_context():
|
| 44 |
+
# Import routes to register blueprints
|
| 45 |
+
from .routes import api_bp, auth_bp, scans_bp, vuln_bp, reports_bp
|
| 46 |
+
app.register_blueprint(api_bp)
|
| 47 |
+
app.register_blueprint(auth_bp, url_prefix='/api/auth')
|
| 48 |
+
app.register_blueprint(scans_bp, url_prefix='/api/scans')
|
| 49 |
+
app.register_blueprint(vuln_bp, url_prefix='/api/vulnerabilities')
|
| 50 |
+
app.register_blueprint(reports_bp, url_prefix='/api/reports')
|
| 51 |
+
|
| 52 |
+
# Create tables
|
| 53 |
+
db.create_all()
|
| 54 |
+
|
| 55 |
+
# Seed superadmin user (created once, never overwritten)
|
| 56 |
+
from .models import User
|
| 57 |
+
import os
|
| 58 |
+
if not User.query.filter_by(email='superadmin@gmail.com').first():
|
| 59 |
+
sa = User(email='superadmin@gmail.com', role='super_admin', org_id=None)
|
| 60 |
+
sa.set_password(os.getenv('SUPERADMIN_PASSWORD', 'larshield2025'))
|
| 61 |
+
db.session.add(sa)
|
| 62 |
+
db.session.commit()
|
| 63 |
+
print("[System] Superadmin user seeded (superadmin@gmail.com)")
|
| 64 |
+
|
| 65 |
+
# Cleanup stale scans that were truly abandoned/interrupted (> 10 mins old)
|
| 66 |
+
from .models import Scan
|
| 67 |
+
from datetime import datetime, timezone, timedelta
|
| 68 |
+
try:
|
| 69 |
+
ten_mins_ago = datetime.now(timezone.utc) - timedelta(minutes=10)
|
| 70 |
+
stale_scans = Scan.query.filter(
|
| 71 |
+
Scan.status.in_(['queued', 'scanning']),
|
| 72 |
+
(Scan.started_at < ten_mins_ago) | (Scan.started_at == None)
|
| 73 |
+
).all()
|
| 74 |
+
for scan in stale_scans:
|
| 75 |
+
scan.status = 'failed'
|
| 76 |
+
if stale_scans:
|
| 77 |
+
db.session.commit()
|
| 78 |
+
print(f"[System] Marked {len(stale_scans)} stale/interrupted scans as failed on startup.")
|
| 79 |
+
except Exception as e:
|
| 80 |
+
print(f"[System] Failed to clean up stale scans: {e}")
|
| 81 |
+
|
| 82 |
+
return app
|