|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +"""Proxies a request for GitHub gist content. |
| 4 | +
|
| 5 | +This script handles fetching public gist content server-side using |
| 6 | +a GitHub personal access token, so clients don't need authentication. |
| 7 | +
|
| 8 | +To use this script: |
| 9 | +1. Generate a GitHub personal access token with 'gist' scope |
| 10 | +2. Update GITHUB_TOKEN below with your token |
| 11 | +3. Set it up as a CGI script on your web server |
| 12 | +4. Add your domain to ORIGIN_LIST |
| 13 | +
|
| 14 | +Install python-requests: |
| 15 | + $ sudo apt-get install python3-pip |
| 16 | + $ sudo pip install requests |
| 17 | +""" |
| 18 | + |
| 19 | +import cgi |
| 20 | +import json |
| 21 | +import os |
| 22 | +import requests |
| 23 | +import sys |
| 24 | + |
| 25 | +# Replace with your GitHub personal access token |
| 26 | +#note: LOCATED in /usr/lib/cgi-bin on server with private key substituted, public address https://ded.increpare.com/cgi-bin/access_token.py (see auth.html) |
| 27 | +GITHUB_TOKEN = "INSERT github_pat_blah private key here" |
| 28 | + |
| 29 | +ORIGIN_LIST = [ |
| 30 | + "www.puzzlescript.net", |
| 31 | + "www.increpare.com", |
| 32 | + "ded.increpare.com", |
| 33 | + "increpare.github.io", |
| 34 | + "sfiera.github.io", |
| 35 | + "www.flickgame.org", |
| 36 | + "www.tinychoice.net", |
| 37 | + "tinychoice.net", |
| 38 | + "www.plingpling.org", |
| 39 | + "plingpling.org", |
| 40 | + "www.flickgame.org", |
| 41 | + "flickgame.org", |
| 42 | +] |
| 43 | + |
| 44 | +GITHUB_API_URL = "https://api.github.com/gists/" |
| 45 | +HEADERS = { |
| 46 | + "user-agent": "puzzlescript-gist-proxy", |
| 47 | + "accept": "application/vnd.github+json", |
| 48 | + "authorization": f"Bearer {GITHUB_TOKEN}", |
| 49 | + "x-github-api-version": "2022-11-28", |
| 50 | +} |
| 51 | + |
| 52 | +# Check origin |
| 53 | +origin = os.environ.get("HTTP_ORIGIN", "") |
| 54 | +if not origin.startswith("https://") or (origin[8:] not in ORIGIN_LIST): |
| 55 | + print("Content-type: application/json") |
| 56 | + print() |
| 57 | + json.dump({"error": "invalid origin"}, sys.stdout) |
| 58 | + sys.exit(0) |
| 59 | + |
| 60 | +# Get gist ID from query parameters |
| 61 | +form = cgi.FieldStorage() |
| 62 | +gist_id = form.getfirst("id", "") |
| 63 | + |
| 64 | +if not gist_id: |
| 65 | + print("Content-type: application/json") |
| 66 | + print("Access-Control-Allow-Origin: " + origin) |
| 67 | + print() |
| 68 | + json.dump({"error": "no gist id provided"}, sys.stdout) |
| 69 | + sys.exit(0) |
| 70 | + |
| 71 | +# Clean the gist ID (remove any path characters for security) |
| 72 | +gist_id = gist_id.replace("/", "").replace("\\", "") |
| 73 | + |
| 74 | +try: |
| 75 | + # Fetch gist data from GitHub API |
| 76 | + response = requests.get( |
| 77 | + GITHUB_API_URL + gist_id, |
| 78 | + headers=HEADERS, |
| 79 | + timeout=10 |
| 80 | + ) |
| 81 | + |
| 82 | + if response.status_code == 200: |
| 83 | + gist_data = response.json() |
| 84 | + |
| 85 | + # Extract script.txt content |
| 86 | + files = gist_data.get("files", {}) |
| 87 | + script_file = files.get("script.txt") |
| 88 | + |
| 89 | + if script_file and "content" in script_file: |
| 90 | + result = {"content": script_file["content"]} |
| 91 | + else: |
| 92 | + result = {"error": "script.txt not found in gist"} |
| 93 | + elif response.status_code == 404: |
| 94 | + result = {"error": "gist not found"} |
| 95 | + elif response.status_code == 403: |
| 96 | + result = {"error": "rate limit exceeded or access denied"} |
| 97 | + else: |
| 98 | + result = {"error": f"github api error: {response.status_code}"} |
| 99 | + |
| 100 | +except requests.exceptions.Timeout: |
| 101 | + result = {"error": "request timeout"} |
| 102 | +except requests.exceptions.RequestException as e: |
| 103 | + result = {"error": f"request failed: {str(e)}"} |
| 104 | +except Exception as e: |
| 105 | + result = {"error": f"unexpected error: {str(e)}"} |
| 106 | + |
| 107 | +print("Content-type: application/json") |
| 108 | +print("Access-Control-Allow-Origin: " + origin) |
| 109 | +print() |
| 110 | +json.dump(result, sys.stdout) |
0 commit comments