gerd.members-area: adds member website on <domain>/members
This commit is contained in:
parent
0ca49ba790
commit
23faf44b39
4 changed files with 153 additions and 6 deletions
|
@ -14,6 +14,8 @@
|
|||
./gerd/services/murmur.nix
|
||||
./gerd/services/hedgedoc.nix
|
||||
|
||||
./gerd/services/member-website
|
||||
|
||||
# ./gerd/services/owncast.nix
|
||||
];
|
||||
|
||||
|
|
|
@ -76,20 +76,22 @@ let
|
|||
error_page 401 =302 https://auth.fricloud.dk/?rd=$target_url;
|
||||
'';
|
||||
in {
|
||||
mine.shared.lib.authelia.mkProtectedWebsite = virtualHostConfig: lib.recursiveUpdate {
|
||||
mine.shared.lib.authelia.mkProtectedWebsite = { vhostConfig, endpoint ? "/" }: lib.recursiveUpdate {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
extraConfig = "include ${autheliaLocation};";
|
||||
|
||||
locations."/" = {
|
||||
locations."${endpoint}" = {
|
||||
extraConfig = "include ${autheliaRequest};";
|
||||
};
|
||||
} virtualHostConfig;
|
||||
} vhostConfig;
|
||||
|
||||
services.nginx.virtualHosts."test.fricloud.dk" = config.mine.shared.lib.authelia.mkProtectedWebsite {
|
||||
locations."/".root = pkgs.writeTextDir "index.html" ''
|
||||
ACCESS GRANTED!
|
||||
'';
|
||||
vhostConfig = {
|
||||
locations."/".root = pkgs.writeTextDir "index.html" ''
|
||||
ACCESS GRANTED!
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
116
machines/gerd/services/member-website/app.py
Executable file
116
machines/gerd/services/member-website/app.py
Executable file
|
@ -0,0 +1,116 @@
|
|||
#!/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
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
services_data: dict[str, Any] = {}
|
||||
|
||||
tmpl_index = """
|
||||
<!doctype html>
|
||||
<title>Members Area</title>
|
||||
<b>Welcome to the members area {% if user.name %} {{ user.name }} {% else %} {{ user.username }} {% endif %}!</b>
|
||||
|
||||
<h1>Services</h1>
|
||||
{% for name, info in services.items() %}
|
||||
<h3>{{ info.name }}</h3>
|
||||
{{ info.description }}
|
||||
<br>
|
||||
<a href="{{ info.url }}">{{ info.url }}</a>
|
||||
<pre>
|
||||
Package name: {{ info.package.name }}
|
||||
Package version: {{ info.package.version }}
|
||||
Package homepage: {{ info.package.meta.homepage }}
|
||||
License: <a href="{{ info.package.meta.license.url }}">{{ info.package.meta.license.spdxId }} ({{ info.package.meta.license.shortName }})</a>
|
||||
Unfree: {{ info.package.meta.unfree }}
|
||||
|
||||
<pre>
|
||||
<hr>
|
||||
{% endfor %}
|
||||
"""
|
||||
|
||||
|
||||
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("/")
|
||||
def index():
|
||||
# extract user information
|
||||
user_info = {
|
||||
"username": request.headers.get("Remote-User"),
|
||||
"name": request.headers.get("Remote-Name"),
|
||||
"groups": request.headers.get("Remote-Groups"),
|
||||
"email": request.headers.get("Remote-Email"),
|
||||
}
|
||||
tmpl_firstpass = render_template_string(
|
||||
tmpl_index,
|
||||
services=services_data,
|
||||
user=user_info,
|
||||
)
|
||||
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)
|
27
machines/gerd/services/member-website/default.nix
Normal file
27
machines/gerd/services/member-website/default.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
urlpath = "/members";
|
||||
metaJSONFile = (pkgs.formats.json {}).generate "meta-service-info.json" config.mine.shared.meta;
|
||||
port = 5050;
|
||||
in {
|
||||
systemd.services.website-member = {
|
||||
description = "members area website";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = let
|
||||
pythonEnv = pkgs.python3.withPackages(ps: with ps; [ flask ]);
|
||||
in "${pythonEnv}/bin/python ${./app.py} --port ${builtins.toString port} --meta-json ${metaJSONFile}";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${config.mine.shared.settings.domain}" = config.mine.shared.lib.authelia.mkProtectedWebsite {
|
||||
endpoint = urlpath;
|
||||
vhostConfig.locations."${urlpath}" = {
|
||||
extraConfig = "rewrite ^${urlpath}(.*)$ /$1 break;";
|
||||
proxyPass = "http://localhost:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue