#!/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("/", 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"Invalid referer: {referer}\n",404 else: abort(404) return "OK", 200 if __name__ == "__main__": app.run()