mirror of
https://github.com/NohamR/BrunoServer.git
synced 2026-01-10 08:18:20 +00:00
Add docstrings and improve formatting in server.py
This commit is contained in:
155
server.py
155
server.py
@@ -1,3 +1,4 @@
|
|||||||
|
"""Flask server for license activation and verification."""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
@@ -12,105 +13,117 @@ app = Flask(__name__)
|
|||||||
PENDING_ACTIVATIONS = {}
|
PENDING_ACTIVATIONS = {}
|
||||||
|
|
||||||
def _b64url_encode(data: bytes) -> str:
|
def _b64url_encode(data: bytes) -> str:
|
||||||
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
|
"""Base64 URL-safe encode data."""
|
||||||
|
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
|
||||||
|
|
||||||
|
|
||||||
def _make_jwt_like(payload: dict) -> str:
|
def _make_jwt_like(payload: dict) -> str:
|
||||||
header = {"alg": "HS256", "typ": "JWT"}
|
"""Create a JWT-like token."""
|
||||||
header_b64 = _b64url_encode(json.dumps(header, separators=(",", ":"), ensure_ascii=False).encode("utf-8"))
|
header = {"alg": "HS256", "typ": "JWT"}
|
||||||
payload_b64 = _b64url_encode(json.dumps(payload, separators=(",", ":"), ensure_ascii=False).encode("utf-8"))
|
header_json = json.dumps(header, separators=(",", ":"),
|
||||||
signature_b64 = _b64url_encode(b"signature")
|
ensure_ascii=False).encode("utf-8")
|
||||||
return f"{header_b64}.{payload_b64}.{signature_b64}"
|
header_b64 = _b64url_encode(header_json)
|
||||||
|
payload_json = json.dumps(payload, separators=(",", ":"),
|
||||||
|
ensure_ascii=False).encode("utf-8")
|
||||||
|
payload_b64 = _b64url_encode(payload_json)
|
||||||
|
signature_b64 = _b64url_encode(b"signature")
|
||||||
|
return f"{header_b64}.{payload_b64}.{signature_b64}"
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/v1/license/activate", methods=["POST"])
|
@app.route("/api/v1/license/activate", methods=["POST"])
|
||||||
def activate_license():
|
def activate_license():
|
||||||
payload = request.get_json(silent=True) or {}
|
"""Handle license activation request."""
|
||||||
print("Received activation request:", payload)
|
payload = request.get_json(silent=True) or {}
|
||||||
|
print("Received activation request:", payload)
|
||||||
|
|
||||||
license_key = payload.get("licenseKey", "")
|
license_key = payload.get("licenseKey", "")
|
||||||
device_id = payload.get("deviceId", str(uuid.uuid4()))
|
device_id = payload.get("deviceId", str(uuid.uuid4()))
|
||||||
device_name = payload.get("deviceName", "Unnamed Device")
|
device_name = payload.get("deviceName", "Unnamed Device")
|
||||||
email = payload.get("email")
|
email = payload.get("email")
|
||||||
license_server_url = payload.get("licenseServerUrl")
|
license_server_url = payload.get("licenseServerUrl")
|
||||||
|
|
||||||
activation_id = str(uuid.uuid4())
|
activation_id = str(uuid.uuid4())
|
||||||
activated_at = datetime.utcnow().isoformat() + "Z"
|
activated_at = datetime.utcnow().isoformat() + "Z"
|
||||||
|
|
||||||
PENDING_ACTIVATIONS[activation_id] = {
|
PENDING_ACTIVATIONS[activation_id] = {
|
||||||
"licenseKey": license_key,
|
"licenseKey": license_key,
|
||||||
"deviceId": device_id,
|
"deviceId": device_id,
|
||||||
"deviceName": device_name,
|
"deviceName": device_name,
|
||||||
"email": email,
|
"email": email,
|
||||||
"licenseServerUrl": license_server_url,
|
"licenseServerUrl": license_server_url,
|
||||||
"activatedAt": activated_at,
|
"activatedAt": activated_at,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = {
|
resp = {
|
||||||
"status": "activated",
|
"status": "activated",
|
||||||
"licenseKey": license_key,
|
"licenseKey": license_key,
|
||||||
"deviceId": device_id,
|
"deviceId": device_id,
|
||||||
"deviceName": device_name,
|
"deviceName": device_name,
|
||||||
"email": email,
|
"email": email,
|
||||||
"activationId": activation_id,
|
"activationId": activation_id,
|
||||||
"activatedAt": activated_at,
|
"activatedAt": activated_at,
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonify(resp), 200
|
return jsonify(resp), 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/v1/license/activate/<activation_id>", methods=["POST"])
|
@app.route("/api/v1/license/activate/<activation_id>", methods=["POST"])
|
||||||
def verify_activation_otp(activation_id: str):
|
def verify_activation_otp(activation_id: str):
|
||||||
payload = request.get_json(silent=True) or {}
|
"""Verify activation OTP and return license token."""
|
||||||
print("Received OTP verification:", {"activationId": activation_id, **payload})
|
payload = request.get_json(silent=True) or {}
|
||||||
|
print("Received OTP verification:",
|
||||||
|
{"activationId": activation_id, **payload})
|
||||||
|
|
||||||
pending = PENDING_ACTIVATIONS.get(activation_id)
|
pending = PENDING_ACTIVATIONS.get(activation_id)
|
||||||
if not pending:
|
if not pending:
|
||||||
return jsonify({"error": "Invalid activationId"}), 404
|
return jsonify({"error": "Invalid activationId"}), 404
|
||||||
|
|
||||||
now_iso = datetime.utcnow().isoformat() + "Z"
|
now_iso = datetime.utcnow().isoformat() + "Z"
|
||||||
license_payload = {
|
license_payload = {
|
||||||
"licenseKey": pending.get("licenseKey"),
|
"licenseKey": pending.get("licenseKey"),
|
||||||
"email": pending.get("email"),
|
"email": pending.get("email"),
|
||||||
"deviceId": pending.get("deviceId"),
|
"deviceId": pending.get("deviceId"),
|
||||||
"deviceName": pending.get("deviceName"),
|
"deviceName": pending.get("deviceName"),
|
||||||
"licenseServerUrl": pending.get("licenseServerUrl"),
|
"licenseServerUrl": pending.get("licenseServerUrl"),
|
||||||
"plan": "ULTIMATE_EDITION", # ["PRO_EDITION","GOLDEN_EDITION","ULTIMATE_EDITION"]
|
# ["PRO_EDITION","GOLDEN_EDITION","ULTIMATE_EDITION"]
|
||||||
"type": "personal",
|
"plan": "ULTIMATE_EDITION",
|
||||||
"createdAt": pending.get("activatedAt"),
|
"type": "personal",
|
||||||
"updatedAt": now_iso,
|
"createdAt": pending.get("activatedAt"),
|
||||||
"trialActive": False,
|
"updatedAt": now_iso,
|
||||||
}
|
"trialActive": False,
|
||||||
|
}
|
||||||
|
|
||||||
token = _make_jwt_like(license_payload)
|
token = _make_jwt_like(license_payload)
|
||||||
PENDING_ACTIVATIONS.pop(activation_id, None)
|
PENDING_ACTIVATIONS.pop(activation_id, None)
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"licenseToken": token,
|
"licenseToken": token,
|
||||||
}), 200
|
}), 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/v1/license/verify", methods=["POST"])
|
@app.route("/api/v1/license/verify", methods=["POST"])
|
||||||
def verify_license():
|
def verify_license():
|
||||||
payload = request.get_json(silent=True) or {}
|
"""Verify license token."""
|
||||||
print("Received license verification:", payload)
|
payload = request.get_json(silent=True) or {}
|
||||||
|
print("Received license verification:", payload)
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
"verified": True,
|
"verified": True,
|
||||||
"subscription": {
|
"subscription": {
|
||||||
"plan": "GOLDEN_EDITION"
|
"plan": "GOLDEN_EDITION"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonify(response), 200
|
return jsonify(response), 200
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
return app
|
"""Create and return Flask app."""
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
host = os.getenv("FLASK_HOST", "127.0.0.1")
|
host = os.getenv("FLASK_HOST", "127.0.0.1")
|
||||||
port = int(os.getenv("FLASK_PORT", "5000"))
|
port = int(os.getenv("FLASK_PORT", "5000"))
|
||||||
debug = os.getenv("FLASK_DEBUG", "false").lower() in {"1", "true", "yes"}
|
debug = os.getenv("FLASK_DEBUG", "false").lower() in {"1", "true", "yes"}
|
||||||
app.run(host=host, port=port, debug=debug)
|
app.run(host=host, port=port, debug=debug)
|
||||||
|
|||||||
Reference in New Issue
Block a user