|
1 | 1 | from flask import Flask, request, jsonify, render_template, Response, stream_with_context |
2 | 2 | from flask_wtf.csrf import CSRFProtect |
3 | 3 | from rag_system import rag_system |
| 4 | +import hashlib |
4 | 5 | import subprocess |
5 | | -app = Flask(__name__, static_folder='templates/images') |
6 | | - |
7 | 6 | import os |
8 | 7 |
|
| 8 | +app = Flask(__name__, static_folder='templates/images') |
9 | 9 | app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') |
10 | 10 | app.config['SESSION_COOKIE_HTTPONLY'] = True |
11 | 11 | app.config['SESSION_COOKIE_SECURE'] = bool(os.getenv('SESSION_COOKIE_SECURE')) |
12 | 12 |
|
13 | 13 | csrf = CSRFProtect(app) |
14 | 14 |
|
| 15 | + |
| 16 | +def validate_pow(nonce, data, difficulty): |
| 17 | + # Calculate the sha256 of the concatenated string of 32-bit X-Nonce header and raw body. |
| 18 | + # This calculation has to match the code on the client side, in index.html. |
| 19 | + nonce_bytes = int(nonce).to_bytes(4, byteorder='little') # 32-bit = 4 bytes |
| 20 | + calculated_hash = hashlib.sha256(nonce_bytes + data).digest() |
| 21 | + first_uint32 = int.from_bytes(calculated_hash[:4], byteorder='big') |
| 22 | + return first_uint32 <= difficulty |
| 23 | + |
| 24 | + |
15 | 25 | @app.route('/', methods=['GET', 'POST']) |
16 | 26 | def index(): |
17 | 27 | return render_template('index.html') |
18 | 28 |
|
19 | 29 | @app.route('/ask', methods=['POST']) |
20 | 30 | def ask(): |
| 31 | + if not validate_pow(request.headers.get('X-Nonce'), request.get_data(), 0x50000): |
| 32 | + return jsonify({"error": "Invalid proof of work"}), 400 |
| 33 | + |
21 | 34 | data = request.get_json() |
22 | 35 | query = data.get('query') |
23 | 36 | if not query: |
24 | 37 | return jsonify({"error": "No query provided"}), 400 |
25 | | - |
| 38 | + |
26 | 39 | def generate(): |
27 | 40 | try: |
28 | 41 | for token in rag_system.answer_query_stream(query): |
|
0 commit comments