chimera-api 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. app/__init__.py +302 -0
  2. app/blueprints/admin/__init__.py +9 -0
  3. app/blueprints/admin/routes.py +708 -0
  4. app/blueprints/attack_sim/__init__.py +9 -0
  5. app/blueprints/attack_sim/routes.py +577 -0
  6. app/blueprints/auth/__init__.py +9 -0
  7. app/blueprints/auth/routes.py +1158 -0
  8. app/blueprints/banking/__init__.py +9 -0
  9. app/blueprints/banking/routes.py +880 -0
  10. app/blueprints/checkout/__init__.py +9 -0
  11. app/blueprints/checkout/routes.py +124 -0
  12. app/blueprints/compliance/__init__.py +9 -0
  13. app/blueprints/compliance/routes.py +218 -0
  14. app/blueprints/database_vulnerable/__init__.py +15 -0
  15. app/blueprints/database_vulnerable/routes.py +340 -0
  16. app/blueprints/diagnostics/__init__.py +9 -0
  17. app/blueprints/diagnostics/routes.py +70 -0
  18. app/blueprints/ecommerce/__init__.py +9 -0
  19. app/blueprints/ecommerce/routes.py +588 -0
  20. app/blueprints/energy_utilities/__init__.py +9 -0
  21. app/blueprints/energy_utilities/routes.py +414 -0
  22. app/blueprints/genai/__init__.py +9 -0
  23. app/blueprints/genai/routes.py +261 -0
  24. app/blueprints/government/__init__.py +9 -0
  25. app/blueprints/government/routes.py +684 -0
  26. app/blueprints/healthcare/__init__.py +9 -0
  27. app/blueprints/healthcare/routes.py +956 -0
  28. app/blueprints/ics_ot/__init__.py +9 -0
  29. app/blueprints/ics_ot/routes.py +266 -0
  30. app/blueprints/infrastructure/__init__.py +9 -0
  31. app/blueprints/infrastructure/routes.py +269 -0
  32. app/blueprints/insurance/__init__.py +9 -0
  33. app/blueprints/insurance/routes.py +838 -0
  34. app/blueprints/integrations/__init__.py +9 -0
  35. app/blueprints/integrations/routes.py +133 -0
  36. app/blueprints/loyalty/__init__.py +9 -0
  37. app/blueprints/loyalty/routes.py +195 -0
  38. app/blueprints/main/__init__.py +9 -0
  39. app/blueprints/main/routes.py +41 -0
  40. app/blueprints/mobile/__init__.py +9 -0
  41. app/blueprints/mobile/routes.py +146 -0
  42. app/blueprints/payments/__init__.py +9 -0
  43. app/blueprints/payments/routes.py +683 -0
  44. app/blueprints/recorder/__init__.py +9 -0
  45. app/blueprints/recorder/routes.py +39 -0
  46. app/blueprints/saas/__init__.py +9 -0
  47. app/blueprints/saas/routes.py +567 -0
  48. app/blueprints/security_ops/__init__.py +9 -0
  49. app/blueprints/security_ops/routes.py +163 -0
  50. app/blueprints/telecom/__init__.py +9 -0
  51. app/blueprints/telecom/routes.py +448 -0
  52. app/blueprints/testing/__init__.py +13 -0
  53. app/blueprints/testing/routes.py +364 -0
  54. app/blueprints/throughput/__init__.py +9 -0
  55. app/blueprints/throughput/routes.py +75 -0
  56. app/cli.py +40 -0
  57. app/database.py +313 -0
  58. app/error_handlers.py +307 -0
  59. app/middleware/traffic_recorder.py +67 -0
  60. app/models/__init__.py +200 -0
  61. app/models/dal.py +391 -0
  62. app/models/data_stores.py +363 -0
  63. app/models.py +216 -0
  64. app/throughput.py +62 -0
  65. app/utils/__init__.py +155 -0
  66. app/utils/auth_helpers.py +528 -0
  67. app/utils/demo_data.py +1045 -0
  68. app/utils/monitoring.py +510 -0
  69. app/utils/responses.py +507 -0
  70. app/utils/templates.py +124 -0
  71. app/utils/validators.py +544 -0
  72. app/web_dist/assets/index-Ce9aAr74.js +613 -0
  73. app/web_dist/assets/index-DoKhh6ts.css +1 -0
  74. app/web_dist/index.html +13 -0
  75. chimera_api-0.1.1.dist-info/METADATA +17 -0
  76. chimera_api-0.1.1.dist-info/RECORD +78 -0
  77. chimera_api-0.1.1.dist-info/WHEEL +4 -0
  78. chimera_api-0.1.1.dist-info/entry_points.txt +2 -0
app/__init__.py ADDED
@@ -0,0 +1,302 @@
1
+ """
2
+ Application factory for the WAF Demo Site.
3
+ """
4
+
5
+ import os
6
+ from flask import Flask, Response, jsonify, request, send_from_directory
7
+
8
+ from app.throughput import (
9
+ bool_env,
10
+ int_env,
11
+ throughput_payload_bytes,
12
+ build_payload_cache
13
+ )
14
+
15
+
16
+ def create_app(config=None):
17
+ """
18
+ Application factory pattern for creating Flask app instances.
19
+
20
+ Args:
21
+ config: Optional configuration dictionary
22
+
23
+ Returns:
24
+ Configured Flask application instance
25
+ """
26
+ app = Flask(__name__, static_folder='../static')
27
+
28
+ # Basic configuration
29
+ app.secret_key = config.get('SECRET_KEY', 'chimera-demo-key-not-for-production') if config else 'chimera-demo-key-not-for-production'
30
+
31
+ # Initialize Swagger (legacy flasgger setup retained for backward compatibility)
32
+ from flasgger import Swagger
33
+ swagger_template = {
34
+ "swagger": "2.0",
35
+ "info": {
36
+ "title": " Demo API",
37
+ "description": "API Documentation for WAF TestBed. <br><br><b>Note:</b> This API contains intentional vulnerabilities for educational and testing purposes.",
38
+ "version": "1.0.0"
39
+ },
40
+ "schemes": [
41
+ "http",
42
+ "https"
43
+ ],
44
+ "securityDefinitions": {
45
+ "Bearer": {
46
+ "type": "apiKey",
47
+ "name": "Authorization",
48
+ "in": "header",
49
+ "description": "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\""
50
+ }
51
+ }
52
+ }
53
+ Swagger(app, template=swagger_template)
54
+
55
+ # Enable debug mode for demo environment to ensure verbose error responses
56
+ demo_mode = os.environ.get('DEMO_MODE', 'true').lower() == 'true'
57
+ if demo_mode:
58
+ app.config['DEBUG'] = True
59
+ app.config['ENV'] = 'development'
60
+ app.config['DEMO_MODE'] = True
61
+
62
+ # Initialize database if USE_DATABASE=true
63
+ use_database = os.environ.get('USE_DATABASE', 'false').lower() == 'true'
64
+ if use_database:
65
+ from app.database import init_database
66
+ db_initialized = init_database(app)
67
+ if db_initialized:
68
+ print("✓ Database mode enabled (SQLite)")
69
+ else:
70
+ print("✗ Database initialization failed")
71
+ else:
72
+ print("✓ In-memory mode (no database)")
73
+
74
+ throughput_mode = bool_env('DEMO_THROUGHPUT_MODE')
75
+ if throughput_mode:
76
+ payload_bytes = throughput_payload_bytes()
77
+ payload_cache = build_payload_cache(payload_bytes)
78
+ payload = payload_cache[payload_bytes]
79
+ payload_size = len(payload)
80
+ max_payload_bytes = int_env('DEMO_THROUGHPUT_MAX_BYTES') or (1024 * 1024)
81
+ throughput_only_fast = bool_env('DEMO_THROUGHPUT_ONLY_FAST')
82
+ match_paths = [p.strip() for p in os.environ.get('DEMO_THROUGHPUT_PATHS', '').split(',') if p.strip()]
83
+ exclude_paths = [p.strip() for p in os.environ.get('DEMO_THROUGHPUT_EXCLUDE_PATHS', '').split(',') if p.strip()]
84
+
85
+ app.config['DEMO_THROUGHPUT_MODE'] = True
86
+ app.config['DEMO_THROUGHPUT_PAYLOAD'] = payload
87
+ app.config['DEMO_THROUGHPUT_PAYLOAD_BYTES'] = payload_size
88
+ app.config['DEMO_THROUGHPUT_PAYLOAD_CACHE'] = payload_cache
89
+ app.config['DEMO_THROUGHPUT_MAX_BYTES'] = max_payload_bytes
90
+ app.config['DEMO_THROUGHPUT_ONLY_FAST'] = throughput_only_fast
91
+ app.config['DEMO_THROUGHPUT_PATHS'] = match_paths
92
+ app.config['DEMO_THROUGHPUT_EXCLUDE_PATHS'] = exclude_paths
93
+
94
+ @app.before_request
95
+ def short_circuit_exports():
96
+ if throughput_only_fast:
97
+ return None
98
+ if request.method not in {'GET', 'POST'}:
99
+ return None
100
+ path = request.path or ''
101
+ if exclude_paths and any(token in path for token in exclude_paths):
102
+ return None
103
+ if match_paths:
104
+ if not any(token in path for token in match_paths):
105
+ return None
106
+ elif 'export' not in path:
107
+ return None
108
+
109
+ response = Response(payload, mimetype='application/json')
110
+ response.headers['X-Demo-Throughput'] = 'true'
111
+ response.headers['X-Demo-Throughput-Bytes'] = str(payload_size)
112
+ return response
113
+
114
+ # Register Security Headers (CSP + CORS)
115
+ @app.after_request
116
+ def add_security_headers(response):
117
+ """Set Content-Security-Policy and CORS headers for all responses"""
118
+ # CORS Headers - Intentionally permissive for demo
119
+ response.headers['Access-Control-Allow-Origin'] = '*'
120
+ response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
121
+ response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With'
122
+
123
+ if request.path in {'/swagger', '/openapi.yaml'}:
124
+ response.headers['Content-Security-Policy'] = (
125
+ "default-src 'self' https://unpkg.com; "
126
+ "style-src 'self' https://unpkg.com 'unsafe-inline'; "
127
+ "script-src 'self' https://unpkg.com 'unsafe-inline'; "
128
+ "img-src 'self' data: https://unpkg.com; "
129
+ "font-src 'self' https://unpkg.com; "
130
+ "connect-src 'self'"
131
+ )
132
+ return response
133
+
134
+ # SPA routes need relaxed CSP for Tailwind/Vite inline styles
135
+ if not request.path.startswith(('/api/', '/apidocs', '/flasgger_static', '/apispec')):
136
+ response.headers['Content-Security-Policy'] = (
137
+ "default-src 'self'; "
138
+ "style-src 'self' 'unsafe-inline'; "
139
+ "script-src 'self'; "
140
+ "img-src 'self' data:; "
141
+ "font-src 'self'; "
142
+ "connect-src 'self'"
143
+ )
144
+ else:
145
+ response.headers['Content-Security-Policy'] = (
146
+ "default-src 'self'; "
147
+ "style-src 'self'; "
148
+ "script-src 'self'; "
149
+ "img-src 'self' data:; "
150
+ "font-src 'self'; "
151
+ "connect-src 'self'"
152
+ )
153
+ return response
154
+
155
+ # Register error handlers BEFORE blueprints to ensure they catch all errors
156
+ from app.error_handlers import register_error_handlers
157
+ register_error_handlers(app)
158
+
159
+ # Import and register blueprints
160
+ from app.blueprints.main import main_bp
161
+ from app.blueprints.auth import auth_bp
162
+ from app.blueprints.banking import banking_bp
163
+ from app.blueprints.mobile import mobile_bp
164
+ from app.blueprints.healthcare import healthcare_bp
165
+ from app.blueprints.compliance import compliance_bp
166
+ from app.blueprints.ecommerce import ecommerce_bp
167
+ from app.blueprints.checkout import checkout_bp
168
+ from app.blueprints.payments import payments_bp
169
+ from app.blueprints.loyalty import loyalty_bp
170
+ from app.blueprints.insurance import insurance_bp
171
+ from app.blueprints.infrastructure import infrastructure_bp
172
+ from app.blueprints.attack_sim import attack_sim_bp
173
+ from app.blueprints.ics_ot import ics_ot_bp
174
+ from app.blueprints.security_ops import security_ops_bp
175
+ from app.blueprints.integrations import integrations_bp
176
+ from app.blueprints.government import government_bp
177
+ from app.blueprints.saas import saas_bp
178
+ from app.blueprints.telecom import telecom_bp
179
+ from app.blueprints.energy_utilities import energy_utilities_bp
180
+ from app.blueprints.admin import admin_bp
181
+ from app.blueprints.testing import testing_bp
182
+ from app.blueprints.throughput import throughput_bp
183
+ from app.blueprints.genai import genai_bp
184
+ from app.blueprints.diagnostics import diagnostics_bp
185
+ from app.blueprints.recorder import recorder_bp
186
+ from app.middleware.traffic_recorder import TrafficRecorder
187
+
188
+ # Initialize Traffic Recorder
189
+ TrafficRecorder(app)
190
+
191
+ # Register all blueprints
192
+ app.register_blueprint(main_bp)
193
+ app.register_blueprint(auth_bp)
194
+ app.register_blueprint(banking_bp)
195
+ app.register_blueprint(mobile_bp)
196
+ app.register_blueprint(healthcare_bp)
197
+ app.register_blueprint(compliance_bp)
198
+ app.register_blueprint(ecommerce_bp)
199
+ app.register_blueprint(checkout_bp)
200
+ app.register_blueprint(payments_bp)
201
+ app.register_blueprint(loyalty_bp)
202
+ app.register_blueprint(insurance_bp)
203
+ app.register_blueprint(infrastructure_bp)
204
+ app.register_blueprint(attack_sim_bp)
205
+ app.register_blueprint(ics_ot_bp)
206
+ app.register_blueprint(security_ops_bp)
207
+ app.register_blueprint(integrations_bp)
208
+ app.register_blueprint(government_bp)
209
+ app.register_blueprint(saas_bp)
210
+ app.register_blueprint(telecom_bp)
211
+ app.register_blueprint(energy_utilities_bp)
212
+ app.register_blueprint(admin_bp)
213
+ app.register_blueprint(testing_bp)
214
+ app.register_blueprint(throughput_bp)
215
+ app.register_blueprint(genai_bp)
216
+ app.register_blueprint(diagnostics_bp)
217
+ app.register_blueprint(recorder_bp)
218
+
219
+ # Register database vulnerable endpoints (if database mode enabled)
220
+ if use_database:
221
+ from app.blueprints.database_vulnerable import db_vuln_bp
222
+ app.register_blueprint(db_vuln_bp)
223
+ print("✓ SQL injection test endpoints enabled")
224
+
225
+ # Static OpenAPI spec + Swagger UI
226
+ docs_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'docs'))
227
+
228
+ @app.get('/openapi.yaml')
229
+ def openapi_spec():
230
+ return send_from_directory(docs_dir, 'openapi.yaml')
231
+
232
+ @app.get('/swagger')
233
+ def swagger_ui():
234
+ html = """
235
+ <!doctype html>
236
+ <html lang="en">
237
+ <head>
238
+ <meta charset="utf-8" />
239
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
240
+ <title> TestBed Swagger UI</title>
241
+ <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
242
+ <style>
243
+ body { margin: 0; background: #0f172a; }
244
+ #swagger-ui { padding: 12px 24px; }
245
+ </style>
246
+ </head>
247
+ <body>
248
+ <div id="swagger-ui"></div>
249
+ <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
250
+ <script>
251
+ window.onload = function () {
252
+ SwaggerUIBundle({
253
+ url: '/openapi.yaml',
254
+ dom_id: '#swagger-ui',
255
+ deepLinking: true,
256
+ presets: [SwaggerUIBundle.presets.apis],
257
+ layout: 'BaseLayout'
258
+ });
259
+ };
260
+ </script>
261
+ </body>
262
+ </html>
263
+ """
264
+ return Response(html, mimetype='text/html')
265
+
266
+ # Initialize demo data
267
+ with app.app_context():
268
+ from app.utils import init_demo_data
269
+ init_demo_data()
270
+
271
+ # --- SPA serving: bundle the React frontend into Flask ---
272
+ web_dist_dir = os.path.join(os.path.dirname(__file__), 'web_dist')
273
+ spa_index = os.path.join(web_dist_dir, 'index.html')
274
+ _API_PREFIXES = ('api/', 'apidocs', 'flasgger_static', 'apispec')
275
+
276
+ if os.path.isfile(spa_index):
277
+ print("✓ SPA mode — serving web portal from app/web_dist/")
278
+
279
+ # Replace the main blueprint's / handler instead of adding a
280
+ # duplicate URL rule (blueprint routes match before app routes).
281
+ def _serve_spa_index():
282
+ return send_from_directory(web_dist_dir, 'index.html')
283
+
284
+ app.view_functions['main.home'] = _serve_spa_index
285
+
286
+ @app.route('/<path:path>')
287
+ def spa_catch_all(path):
288
+ # Let API and Swagger routes return 404 so error handlers work
289
+ if path.startswith(_API_PREFIXES):
290
+ return jsonify({"error": "Not found"}), 404
291
+
292
+ # Serve actual static files (JS, CSS, images, etc.)
293
+ static_path = os.path.join(web_dist_dir, path)
294
+ if os.path.isfile(static_path):
295
+ return send_from_directory(web_dist_dir, path)
296
+
297
+ # Everything else → index.html (React Router handles it)
298
+ return send_from_directory(web_dist_dir, 'index.html')
299
+ else:
300
+ print("✓ API-only mode — no web_dist/index.html found")
301
+
302
+ return app
@@ -0,0 +1,9 @@
1
+ """
2
+ Admin blueprint.
3
+ """
4
+
5
+ from flask import Blueprint
6
+
7
+ admin_bp = Blueprint('admin', __name__)
8
+
9
+ from . import routes