mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
feat: enhanced bootnode app with updated dependencies
- Update app.py with improvements - Update requirements.txt dependencies - Add .env.example template
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# Legacy Bootnode - Secured Configuration
|
||||
# For the legacy Quart application
|
||||
|
||||
# Authentication (Set secure values!)
|
||||
LEGACY_API_TOKEN=bn_legacy_secure_token_replace_with_random_32_chars
|
||||
LEGACY_ADMIN_EMAIL=[email protected]
|
||||
LEGACY_ADMIN_PASSWORD=your-strong-admin-password-here
|
||||
|
||||
# MongoDB
|
||||
MONGO_URL=mongodb://localhost:27017/bootnode
|
||||
|
||||
# WARNING: This is the legacy app - migrate to /api/bootnode for modern features
|
||||
@@ -1,3 +1,26 @@
|
||||
"""
|
||||
LEGACY BOOTNODE APPLICATION
|
||||
===========================
|
||||
|
||||
⚠️ SECURITY NOTICE: This is the legacy Bootnode application.
|
||||
|
||||
✅ FIXED: Hardcoded credentials have been removed and replaced with environment variables.
|
||||
|
||||
🔄 MIGRATION RECOMMENDED: Consider migrating to the modern FastAPI version in /api/bootnode/
|
||||
- Better security with JWT authentication
|
||||
- Modern async/await patterns
|
||||
- Comprehensive API documentation
|
||||
- Support for 11+ blockchains
|
||||
- Rate limiting and monitoring
|
||||
|
||||
To run this legacy app safely:
|
||||
1. Copy .env.example to .env
|
||||
2. Set secure values for all environment variables
|
||||
3. Use strong passwords and random tokens
|
||||
|
||||
For new development, use the modern API in /api/ instead.
|
||||
"""
|
||||
|
||||
from threading import Thread
|
||||
from functools import wraps
|
||||
from quart import Quart, request
|
||||
@@ -7,8 +30,13 @@ from util import to_nodes, jsonify
|
||||
from pymongo import MongoClient
|
||||
import datetime
|
||||
import asyncio
|
||||
import requests_async as requests
|
||||
import httpx
|
||||
import datetime
|
||||
import os
|
||||
|
||||
# Load environment variables
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.get_child_watcher().attach_loop(loop)
|
||||
@@ -59,18 +87,16 @@ async def update_nodes_lambda(date, zone, provider):
|
||||
|
||||
start = datetime.datetime.now()
|
||||
|
||||
reqs = [
|
||||
requests.put('https://{0}:{1}/show/blocks'.format(ip, port),
|
||||
json={'depth': 1},
|
||||
verify=False),
|
||||
requests.put('https://{0}:{1}/show/dag'.format(ip,
|
||||
port),
|
||||
json={'depth': 10,
|
||||
'showJustifications':
|
||||
True}, verify=False)
|
||||
]
|
||||
async with httpx.AsyncClient(verify=False) as client:
|
||||
reqs = [
|
||||
client.put(f'https://{ip}:{port}/show/blocks',
|
||||
json={'depth': 1}),
|
||||
client.put(f'https://{ip}:{port}/show/dag',
|
||||
json={'depth': 10,
|
||||
'showJustifications': True})
|
||||
]
|
||||
|
||||
ress = await asyncio.gather(*reqs)
|
||||
ress = await asyncio.gather(*reqs)
|
||||
|
||||
blockdata = ress[0]
|
||||
dag = ress[1]
|
||||
@@ -135,8 +161,17 @@ Thread(target=update_nodes_thread).start()
|
||||
def auth_required(fn):
|
||||
@wraps(fn)
|
||||
async def wrapped_fn(*args, **kwargs):
|
||||
# print(request.headers.get('Authorization'))
|
||||
if request.headers.get('Authorization') != 'Bearer fLcLu7OLD81aR9jf':
|
||||
# SECURITY: Check for environment variable instead of hardcoded token
|
||||
import os
|
||||
expected_token = os.environ.get('LEGACY_API_TOKEN')
|
||||
if not expected_token:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'API token not configured',
|
||||
})
|
||||
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if not auth_header or auth_header != f'Bearer {expected_token}':
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'authorization required',
|
||||
@@ -148,11 +183,23 @@ def auth_required(fn):
|
||||
async def login():
|
||||
try:
|
||||
json = await request.get_json()
|
||||
|
||||
# SECURITY: Use environment variables for credentials
|
||||
import os
|
||||
admin_email = os.environ.get('LEGACY_ADMIN_EMAIL')
|
||||
admin_password = os.environ.get('LEGACY_ADMIN_PASSWORD')
|
||||
api_token = os.environ.get('LEGACY_API_TOKEN')
|
||||
|
||||
if not all([admin_email, admin_password, api_token]):
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'Authentication not properly configured'
|
||||
})
|
||||
|
||||
print('login', json)
|
||||
print('login attempt for:', json.get('email', 'unknown'))
|
||||
|
||||
if json['email'] == '[email protected]' and json['password'] == 'testtest':
|
||||
return jsonify({'token': 'fLcLu7OLD81aR9jf'})
|
||||
if json.get('email') == admin_email and json.get('password') == admin_password:
|
||||
return jsonify({'token': api_token})
|
||||
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
|
||||
+32
-14
@@ -1,14 +1,32 @@
|
||||
kubernetes
|
||||
kubernetes_asyncio
|
||||
google-api-python-client
|
||||
google-auth-httplib2
|
||||
tabulate
|
||||
protobuf3-to-dict
|
||||
google-cloud-container
|
||||
oauth2client
|
||||
quart
|
||||
quart-cors
|
||||
asyncio
|
||||
pymongo
|
||||
hypercorn
|
||||
requests_async
|
||||
# Legacy Bootnode Dependencies
|
||||
# NOTE: Consider migrating to the modern FastAPI version in /api/ instead
|
||||
|
||||
# Core web framework
|
||||
quart>=0.19.0
|
||||
quart-cors>=0.7.0
|
||||
hypercorn>=0.16.0
|
||||
|
||||
# Environment variables
|
||||
python-dotenv>=1.0.0
|
||||
|
||||
# Database
|
||||
pymongo>=4.6.0
|
||||
|
||||
# HTTP client
|
||||
httpx>=0.26.0 # Modern replacement for requests_async
|
||||
|
||||
# Kubernetes
|
||||
kubernetes>=29.0.0
|
||||
kubernetes_asyncio>=29.0.0
|
||||
|
||||
# Google Cloud
|
||||
google-api-python-client>=2.0.0
|
||||
google-auth-httplib2>=0.2.0
|
||||
google-cloud-container>=2.30.0
|
||||
|
||||
# Utilities
|
||||
tabulate>=0.9.0
|
||||
protobuf>=4.25.0
|
||||
|
||||
# Security notice: This is the legacy app
|
||||
# Consider migrating to the modern FastAPI version in /api/
|
||||
|
||||
Reference in New Issue
Block a user