Add docstrings and improve formatting in server.py

This commit is contained in:
√(noham)²
2025-12-13 15:07:12 +01:00
parent 523f5f1576
commit 915a758b17

155
server.py
View File

@@ -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)