improve index endpoint with comprehensive API info
Some checks failed
CI / Lint & Format (push) Failing after 15s
CI / Tests (push) Has been skipped
CI / Security Scan (push) Failing after 20s

- Add all endpoints including PUT, register, PKI
- Show authentication tiers (anonymous/client_cert/trusted)
- Display current limits (size, rate) for each tier
- Show PoW status and difficulty
- Add CLI install/usage hints
- Conditionally show PKI endpoints when enabled
This commit is contained in:
Username
2025-12-21 13:16:49 +01:00
parent 098789ff89
commit 0c7bf6b587

View File

@@ -581,30 +581,75 @@ class IndexView(MethodView):
def get(self) -> Response:
"""Return API information and usage examples."""
prefix = url_prefix() or "/"
return json_response(
{
"name": "FlaskPaste",
"version": VERSION,
"prefix": prefix,
"endpoints": {
f"GET {prefixed_url('/')}": "API information",
f"GET {prefixed_url('/health')}": "Health check",
f"GET {prefixed_url('/client')}": "Download CLI client",
f"GET {prefixed_url('/challenge')}": "Get PoW challenge",
f"POST {prefixed_url('/')}": "Create paste",
f"GET {prefixed_url('/pastes')}": "List your pastes (auth required)",
f"GET {prefixed_url('/<id>')}": "Retrieve paste metadata",
f"GET {prefixed_url('/<id>/raw')}": "Retrieve raw paste content",
f"DELETE {prefixed_url('/<id>')}": "Delete paste",
url = base_url()
difficulty = get_dynamic_difficulty()
pki_enabled = current_app.config.get("PKI_ENABLED", False)
# Build endpoints dict
endpoints: dict[str, str] = {
f"GET {prefixed_url('/')}": "API information",
f"GET {prefixed_url('/health')}": "Health check",
f"GET {prefixed_url('/client')}": "Download CLI client (fpaste)",
f"GET {prefixed_url('/challenge')}": "Get proof-of-work challenge",
f"POST {prefixed_url('/')}": "Create paste (PoW required)",
f"GET {prefixed_url('/pastes')}": "List your pastes (cert required)",
f"GET {prefixed_url('/<id>')}": "Get paste metadata",
f"GET {prefixed_url('/<id>/raw')}": "Get raw paste content",
f"PUT {prefixed_url('/<id>')}": "Update paste (owner only)",
f"DELETE {prefixed_url('/<id>')}": "Delete paste (owner only)",
f"GET {prefixed_url('/register/challenge')}": "Get registration challenge",
f"POST {prefixed_url('/register')}": "Register for client certificate",
}
if pki_enabled:
endpoints.update(
{
f"GET {prefixed_url('/pki')}": "PKI status",
f"GET {prefixed_url('/pki/ca.crt')}": "Download CA certificate",
f"POST {prefixed_url('/pki/issue')}": "Issue client certificate",
f"GET {prefixed_url('/pki/certs')}": "List certificates",
f"POST {prefixed_url('/pki/revoke/<serial>')}": "Revoke certificate",
}
)
# Build response
response_data: dict[str, Any] = {
"name": "FlaskPaste",
"version": VERSION,
"prefix": prefix,
"endpoints": endpoints,
"authentication": {
"anonymous": "Create pastes only (strict limits)",
"client_cert": "Create + manage own pastes (strict limits)",
"trusted_cert": "All operations (relaxed limits)",
},
"limits": {
"anonymous": {
"max_size": current_app.config["MAX_PASTE_SIZE_ANON"],
"rate": f"{current_app.config['RATE_LIMIT_MAX']}/min",
},
"usage": {
"raw": f"curl --data-binary @file.txt {base_url()}/",
"pipe": f"cat file.txt | curl --data-binary @- {base_url()}/",
"json": f"curl -H \"Content-Type: application/json\" -d '...' {base_url()}/",
"trusted": {
"max_size": current_app.config["MAX_PASTE_SIZE_AUTH"],
"rate": f"{current_app.config['RATE_LIMIT_MAX'] * current_app.config.get('RATE_LIMIT_AUTH_MULTIPLIER', 5)}/min", # noqa: E501
},
"note": "Use --data-binary (not -d) to preserve newlines",
}
)
},
"pow": {
"enabled": difficulty > 0,
"difficulty": difficulty,
"hint": "GET /challenge, solve, submit with X-PoW-Token + X-PoW-Solution",
},
"cli": {
"install": f"curl -o fpaste {url}/client && chmod +x fpaste",
"usage": "fpaste file.txt # encrypts by default",
},
"usage": {
"create": f"curl -X POST --data-binary @file.txt {url}/ (with PoW headers)",
"get": f"curl {url}/<id>/raw",
"delete": f"curl -X DELETE {url}/<id> (with X-SSL-Client-SHA1)",
},
}
return json_response(response_data)
def post(self) -> Response:
"""Create a new paste."""