net-kingdom/identity-provisioner/server.py
tegwick ba07dd2acb
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Add scoped LLDAP identity provisioner
2026-07-28 00:57:16 +02:00

56 lines
1.9 KiB
Python

from dataclasses import asdict
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
import os
import secrets
from provisioner import LLDAPProvisioner, dispatch
class Handler(BaseHTTPRequestHandler):
provisioner: LLDAPProvisioner
service_token: str
def do_GET(self):
if self.path == "/healthz":
return self._send(200, {"status": "ok"})
self._send(404, {"error": "not_found"})
def do_POST(self):
supplied = self.headers.get("Authorization", "").removeprefix("Bearer ")
if not secrets.compare_digest(supplied, self.service_token):
return self._send(403, {"error": "access_denied"})
try:
length = min(int(self.headers.get("Content-Length", "0")), 65536)
payload = json.loads(self.rfile.read(length))
result = dispatch(self.provisioner, self.path, payload)
except KeyError:
return self._send(404, {"error": "not_found"})
except (ValueError, json.JSONDecodeError) as exc:
return self._send(400, {"error": "invalid_request", "message": str(exc)})
self._send(200, asdict(result))
def _send(self, status: int, payload: dict):
body = json.dumps(payload, separators=(",", ":")).encode()
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Cache-Control", "no-store")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
return
def main():
Handler.provisioner = LLDAPProvisioner(
base_url=os.environ["LLDAP_URL"],
admin_password=os.environ["LLDAP_ADMIN_PASSWORD"],
)
Handler.service_token = os.environ["PROVISIONER_SERVICE_TOKEN"]
ThreadingHTTPServer(("0.0.0.0", 8080), Handler).serve_forever()
if __name__ == "__main__":
main()