import json, os, sys, urllib.parse, urllib.request, urllib.error def _cfg(): return json.loads(os.environ.get("INTEGRATION_SECRETS", "{}")) def _inputs(): return json.loads(os.environ.get("INTEGRATION_INPUTS", "{}")) def _token(cfg): auth_url = str(cfg.get("auth_url") or "https://auth.app.wiz.io/oauth/token") form = urllib.parse.urlencode({ "grant_type": "client_credentials", "client_id": str(cfg.get("client_id", "")), "client_secret": str(cfg.get("client_secret", "")), "audience": "wiz-api", }).encode("utf-8") req = urllib.request.Request(auth_url, data=form, headers={"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}, method="POST") with urllib.request.urlopen(req, timeout=60) as r: tok = json.loads(r.read()) if not tok.get("access_token"): raise Exception("Token request failed: " + json.dumps(tok)) return tok["access_token"] def graphql(cfg, token, query, variables): body = json.dumps({"query": query, "variables": variables}).encode("utf-8") req = urllib.request.Request(str(cfg.get("api_url", "")), data=body, headers={ "Authorization": "Bearer " + token, "Content-Type": "application/json", "Accept": "application/json", }, method="POST") with urllib.request.urlopen(req, timeout=90) as r: raw = r.read() resp = json.loads(raw) if raw else {} if resp.get("errors"): raise Exception("GraphQL error: " + json.dumps(resp["errors"])) return resp.get("data", resp) def _run(fn): try: cfg = _cfg() inputs = _inputs() token = _token(cfg) print(json.dumps(fn(cfg, token, inputs))) except urllib.error.HTTPError as e: print(json.dumps({"error": "HTTP " + str(e.code), "detail": e.read().decode("utf-8", "replace")})) sys.exit(1) except Exception as e: print(json.dumps({"error": str(e)})) sys.exit(1) QUERY = """ query Issues($first: Int, $filterBy: IssueFilters) { issues(first: $first, filterBy: $filterBy) { nodes { id status severity createdAt type entitySnapshot { name type } } pageInfo { hasNextPage endCursor } } } """ def main(cfg, token, inputs): status = inputs.get("status") severity = inputs.get("severity") first = inputs.get("first") filter_by = {} if status: filter_by["status"] = [status] if severity: filter_by["severity"] = [severity] variables = {"first": int(first or 20), "filterBy": filter_by} return graphql(cfg, token, QUERY, variables) _run(main)