larxius commited on
Commit
1863d83
·
verified ·
1 Parent(s): 7bdbd3c

Update backend/__init__.py

Browse files
Files changed (1) hide show
  1. 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