# services/guildhall-join.nix — invite links that create Guildhall accounts. # # guildhall-invite [note] print a one-time link, valid for a week # guildhall-invite list open, used and expired invites # guildhall-invite revoke ID cancel one # # The link opens guildhall.nordhammer.it/join/, the one path nginx # serves without Authelia. The page appends the new user, in the `guildhall` # group only, to Authelia's users file (see services/authelia.nix), which # Authelia reloads on change. The service shares a dedicated authelia-users # group with Authelia rather than authelia-main, which would also open # Authelia's secrets. { config, lib, pkgs, ... }: let port = 8099; stateDir = "/var/lib/guildhall-join"; pythonEnv = pkgs.python3.withPackages (ps: [ ps.pyyaml ps.argon2-cffi ]); script = ../scripts/guildhall-join.py; environment = { GUILDHALL_JOIN_STATE = stateDir; GUILDHALL_JOIN_USERS = "/var/lib/authelia-users/users_database.yml"; GUILDHALL_JOIN_SITE = "https://guildhall.nordhammer.it"; GUILDHALL_JOIN_PORT = toString port; }; invite = pkgs.writeShellScriptBin "guildhall-invite" '' case "''${1:-}" in list|revoke) ;; *) set -- invite "$@" ;; esac exec /run/wrappers/bin/sudo -u guildhall-join ${pkgs.coreutils}/bin/env \ ${lib.concatStringsSep " " (lib.mapAttrsToList (k: v: "${k}=${lib.escapeShellArg v}") environment)} \ ${pythonEnv}/bin/python3 ${script} "$@" ''; in { config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") { users.groups.authelia-users = { }; users.groups.guildhall-join = { }; users.users.guildhall-join = { isSystemUser = true; group = "guildhall-join"; extraGroups = [ "authelia-users" ]; description = "Guildhall invite page"; }; users.users.authelia-main.extraGroups = [ "authelia-users" ]; systemd.tmpfiles.rules = [ "d ${stateDir} 0700 guildhall-join guildhall-join -" ]; systemd.services.guildhall-join = { description = "Guildhall invite page"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "authelia-main.service" ]; inherit environment; serviceConfig = { ExecStart = "${pythonEnv}/bin/python3 ${script} serve"; User = "guildhall-join"; Group = "guildhall-join"; Restart = "on-failure"; RestartSec = 3; UMask = "0077"; NoNewPrivileges = true; PrivateTmp = true; PrivateDevices = true; ProtectSystem = "strict"; ProtectHome = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; ReadWritePaths = [ stateDir "/var/lib/authelia-users" ]; }; }; environment.systemPackages = [ invite ]; }; }