net-kingdom/sso-mfa/k8s/privacyidea/pi_api.py

57 lines
1.6 KiB
Python
Raw Normal View History

"""Shared JSON request transport. Credentials stay in memory or stdin, never argv."""
import json
import sys
import urllib.error
import urllib.request
def request(url, payload=None, token=None, *, method=None):
headers = {}
data = None
if payload is not None:
headers["Content-Type"] = "application/json"
data = json.dumps(payload).encode("utf-8")
if token:
headers["Authorization"] = token
# Bodyless GET must not advertise JSON: Werkzeug can reject it before routing.
req = urllib.request.Request(
url,
data=data,
headers=headers,
method=method or ("POST" if payload is not None else "GET"),
)
try:
with urllib.request.urlopen(req, timeout=20) as response:
status, body = response.status, response.read()
try:
return status, json.loads(body) if body else None
except (ValueError, UnicodeError):
return status, None
except urllib.error.HTTPError as exc:
exc.close()
return exc.code, None
except (urllib.error.URLError, TimeoutError, OSError):
return 0, None
def main():
# Shell adapter: token on the first line, optional JSON body on the rest.
token = sys.stdin.readline().rstrip("\n")
body = sys.stdin.read()
status, result = request(
sys.argv[2],
json.loads(body) if body else None,
token or None,
method=sys.argv[1],
)
if not 200 <= status < 300 or not isinstance(result, dict):
print("CURL_FAILED")
return 1
print(json.dumps(result))
return 0
if __name__ == "__main__":
raise SystemExit(main())