aboutsummaryrefslogtreecommitdiff
path: root/outbound.py
blob: 34f114e9d24e41bf9c4eb97752c64ffbc57a7d6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python3
# File: outbound.py
# Location: https://bgstack15.ddns.net/cgit/outbound/
# Author: bgstack15
# Startdate: 2022-11-28-2 16:34
# SPDX-License-Identifier: GPL-3.0
# Title: Outbound flask web app
# Project: outbound
# Purpose: allow web server to log outbound links, by using a link underneath this webapp entry point
# History:
# Usage: See README
# References:
#    fuss.py, coupons.py
#    https://werkzeug.palletsprojects.com/en/2.2.x/serving/#werkzeug.serving.run_simple
# Improve:
#    ensure it works under an arbitrary top-level path like "/outbound/"
#    add domain and port globbing in WHITELIST
# Dependencies:
#    python3-flask
# Documentation: See README

from flask import Flask, request, redirect, abort
from urllib.parse import urlparse
import sys, os, re
# Load app from same directory as this file.py
#sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from urllib import parse

app = Flask(__name__)
try:
   app.config.from_pyfile(os.environ["OUTBOUND_CONF"], silent=False)
except:
   try:
      app.config.from_pyfile("/etc/outbound.conf")
   except:
      try:
         # from working directory
         app.config.from_pyfile("outbound.conf")
      except:
         try:
            # from same directory
            app.config.from_pyfile(os.path.join(os.path.dirname(os.path.realpath(__file__)),"outbound.conf"))
         except:
            # defaults
            print(f"WARNING: Using default configs because could not find OUTBOUND_CONF, or /etc/outbound.conf, or ./outbound.conf!")
            app.config.update(
               WHITELIST = ["localhost"],
               DEBUG = False,
               ALLOW_DEBUG = False
            )
if "WSGI_LOGGING" in app.config:
   dictConfig(app.config["WSGI_LOGGING"])

# satisfies mod_wsgi:
application = app

@app.route("/<path:url>", methods=["GET"])
def root(url = ""):
   referer = None
   allow_debug = app.config["ALLOW_DEBUG"]
   _debug = app.config["DEBUG"]
   try:
      #print(dict(request.headers))
      for item in dict(request.headers):
         #print(f"Item: {item}, {request.headers.get('item')}")
         #print(f"Evaluating item {item}")
         if item.lower() in ["debug"]:
            #print(f"DEBUG header: {request.headers.get(item).lower()}")
            if request.headers.get(item).lower() in ["true","yes","on","1"]:
               #print(f"{item}: {request.headers.get(item)}")
               if allow_debug:
                  _debug = True
   except:
      pass
   bad_referer = False
   try:
      referer = request.referrer
      domain = urlparse(referer).netloc
      if _debug:
         print(f"Referer: {referer}, domain {domain}")
      # TODO: allow wildcard/globbing
      if domain in app.config["WHITELIST"]:
         # Main logic to redirect to/print url.
         # need to fix the webserver->flask collapse of the parameter string http:// down to http:/
         new_url = re.sub("(((ht|f)tps?|gemini):)\/+","\\1//",url)
         if _debug and allow_debug:
            return f"redirect to {new_url}\n",307
         else:
            return redirect(new_url, 307)
      else:
         #print("Bad referer 1")
         bad_referer = True
   except:
      #print("Bad referer 2")
      bad_referer = True
   if bad_referer:
      if _debug and allow_debug:
         return f"<html>Invalid referer: {referer}</html>\n",404
      else:
         abort(404)
   return "OK", 200

if __name__ == "__main__":
   app.run()
bgstack15