#!/usr/bin/env nix-shell
#!nix-shell --pure -i python3 -p "python3.withPackages (ps: with ps; [ flask ])"
from typing import Any
from flask import Flask, request
from flask import render_template, render_template_string
import argparse
import logging
import json
import sys
import os
logging.basicConfig()
logger = logging.getLogger(__name__)
app = Flask(__name__)
services_data: dict[str, Any] = {}
tmpl_index = """
Members Area
Welcome to the members area {% if user.name %} {{ user.name }} {% else %} {{ user.username }} {% endif %}!
Services
{% for name, info in services.items() %}
{{ info.name }}
{{ info.description }}
{% if info.url %}
Link: {{ info.url }}
{% endif %}
Package name: {{ info.package.name }}
Package version: {{ info.package.version }}
Package homepage: {{ info.package.meta.homepage }}
License: {{ info.package.meta.license.spdxId }} ({{ info.package.meta.license.shortName }})
Unfree: {{ info.package.meta.unfree }}
{% endfor %}
{% if show_debug %}
Debug information:
- Username: {{ user.username }}
- Name: {{ user.name }}
- Email: {{ user.email }}
- Groups: {{ user.groups }}
{% endif %}
"""
def extract_secrets() -> dict[str, str]:
new_args = {}
# read all secrets
for service in services_data.values():
for k, v in service.get("secrets", {}).items():
try:
fcontent = open(v, "r").read()
except Exception as e:
logger.exception("unable to open secret file", e)
continue
isEnv: bool = False
if v.endswith("env"):
isEnv = True
if not isEnv:
new_args[k.upper()] = fcontent
continue
# parse env file
for line in fcontent.splitlines():
line = line.strip()
if not line:
continue
envkey, envvalue = line.split("=", maxsplit=1)
if envvalue[0] == '"' or envvalue[1] == "'":
envvalue = envvalue[1:-1]
new_args[envkey.upper()] = envvalue
return new_args
@app.route("/")
@app.route("/members")
def index():
# extract user information
user_info = {
"username": request.headers.get(os.environ.get("AUTH_PROXY_USERNAME")),
"name": request.headers.get(os.environ.get("AUTH_PROXY_NAME")),
"groups": request.headers.get(os.environ.get("AUTH_PROXY_GROUPS")),
"email": request.headers.get(os.environ.get("AUTH_PROXY_EMAIL")),
}
tmpl_firstpass = render_template_string(
tmpl_index,
services=services_data,
user=user_info,
show_debug=bool(request.args.get("debug")),
)
return render_template_string(
tmpl_firstpass,
user=user_info,
secrets=extract_secrets(),
)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--debug",
type=bool,
action=argparse.BooleanOptionalAction,
default=False,
)
parser.add_argument("--listen", type=str, default="127.0.0.1")
parser.add_argument("--port", type=int, default=5000)
parser.add_argument("--meta-json", type=str, required=True)
args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
services_data = json.loads(open(args.meta_json, "r").read())
app.run(host=args.listen, port=args.port, debug=args.debug)