diff --git a/machines/gerd/services/authelia/authelia-nginx.nix b/machines/gerd/services/authelia/authelia-nginx.nix index b58399a..12ad8fa 100644 --- a/machines/gerd/services/authelia/authelia-nginx.nix +++ b/machines/gerd/services/authelia/authelia-nginx.nix @@ -51,10 +51,10 @@ let auth_request_set $email $upstream_http_remote_email; ## Inject the metadata response headers from the variables into the request made to the backend. - proxy_set_header Remote-User $user; - proxy_set_header Remote-Groups $groups; - proxy_set_header Remote-Email $email; - proxy_set_header Remote-Name $name; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.username} $user; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.groups} $groups; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.email} $email; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.name} $name; ## Configure the redirection when the authz failure occurs. Lines starting with 'Modern Method' and 'Legacy Method' ## should be commented / uncommented as pairs. The modern method uses the session cookies configuration's authelia_url @@ -75,12 +75,27 @@ let ## URL parameter set to $target_url. This requires users update 'auth.example.com/' with their external authelia URL. error_page 401 =302 https://${config.mine.shared.settings.authelia.domain}/?rd=$target_url; ''; + + nginxUnsetAuthHeaders = '' + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.username} ""; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.groups} ""; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.email} ""; + proxy_set_header ${config.mine.shared.lib.authelia.protectedHeaders.name} ""; + ''; in { mine.shared.lib.authelia.mkProtectedWebsite = websiteConfig: lib.recursiveUpdate websiteConfig { - extraConfig = (lib.attrByPath [ "extraConfig" ] "" websiteConfig) + "\n" + "include ${autheliaLocation};"; + extraConfig = (websiteConfig.extraConfig or "") + "\n" + "include ${autheliaLocation};"; + locations = lib.mapAttrs (n: v: v // { extraConfig = nginxUnsetAuthHeaders + (v.extraConfig or ""); }) (websiteConfig.locations or {}); }; mine.shared.lib.authelia.mkProtectedLocation = vhostLocationConfig: lib.recursiveUpdate vhostLocationConfig { extraConfig = (lib.attrByPath [ "extraConfig" ] "" vhostLocationConfig) + "\n" + "include ${autheliaRequest};"; }; + + mine.shared.lib.authelia.protectedHeaders = { + username = "Remote-User"; + groups = "Remote-Groups"; # comma separated string of groups + email = "Remote-Email"; + name = "Remote-Name"; + }; } diff --git a/machines/gerd/services/member-website/app.py b/machines/gerd/services/member-website/app.py index 70f02e7..c722420 100755 --- a/machines/gerd/services/member-website/app.py +++ b/machines/gerd/services/member-website/app.py @@ -8,6 +8,7 @@ import argparse import logging import json import sys +import os logging.basicConfig() logger = logging.getLogger(__name__) @@ -94,10 +95,10 @@ def extract_secrets() -> dict[str, str]: 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"), + "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, diff --git a/machines/gerd/services/member-website/default.nix b/machines/gerd/services/member-website/default.nix index 738da25..53c5805 100644 --- a/machines/gerd/services/member-website/default.nix +++ b/machines/gerd/services/member-website/default.nix @@ -9,6 +9,14 @@ in { description = "members area website"; wantedBy = [ "multi-user.target" ]; after = [ "networking.target" ]; + + environment = { + AUTH_PROXY_USERNAME = config.mine.shared.lib.authelia.protectedHeaders.username; + AUTH_PROXY_GROUPS = config.mine.shared.lib.authelia.protectedHeaders.groups; + AUTH_PROXY_EMAIL = config.mine.shared.lib.authelia.protectedHeaders.email; + AUTH_PROXY_NAME = config.mine.shared.lib.authelia.protectedHeaders.name; + }; + serviceConfig = { ExecStart = let pythonEnv = pkgs.python3.withPackages(ps: with ps; [ flask ]); diff --git a/machines/gerd/services/miniflux.nix b/machines/gerd/services/miniflux.nix index 1303a21..5c6ceaa 100644 --- a/machines/gerd/services/miniflux.nix +++ b/machines/gerd/services/miniflux.nix @@ -20,7 +20,7 @@ in { # use auth proxy # TODO: This should be configureable - AUTH_PROXY_HEADER = "Remote-User"; + AUTH_PROXY_HEADER = config.mine.shared.lib.authelia.protectedHeaders.username; AUTH_PROXY_USER_CREATION = "true"; }; }; diff --git a/machines/gerd/services/wger/default.nix b/machines/gerd/services/wger/default.nix index 26c0394..fa5b9cb 100644 --- a/machines/gerd/services/wger/default.nix +++ b/machines/gerd/services/wger/default.nix @@ -19,6 +19,11 @@ in { # wger specific settings wgerSettings = { EMAIL_FROM = "wger Workout Manager "; + + # use authelia for authentication (disable guest users + regisration) + AUTH_PROXY_HEADER = config.mine.shared.lib.authelia.protectedHeaders.username; + ALLOW_GUEST_USERS = false; + ALLOW_REGISTRATION = false; }; # django specific settings diff --git a/machines/gerd/services/wger/wgerpkg/default.nix b/machines/gerd/services/wger/wgerpkg/default.nix index d774d1e..2fa921f 100644 --- a/machines/gerd/services/wger/wgerpkg/default.nix +++ b/machines/gerd/services/wger/wgerpkg/default.nix @@ -4,20 +4,21 @@ fetchFromGitHub, callPackage, writeText, + fetchpatch, }: let frontend = callPackage ./frontend.nix {}; in python3.pkgs.buildPythonPackage rec { pname = "wger"; - version = "unstable-2024-12-01"; + version = "unstable-2024-12-30"; pyproject = true; src = fetchFromGitHub { owner = "wger-project"; repo = "wger"; - rev = "bfca74e88f6c9ff6e917e0ba0e8e9c782ae0047b"; - hash = "sha256-VuVKgkNp6Omiag72lOn6p51kC/jvApX/kRAPpK95U7w="; + rev = "30871d621fa6e732f07bd33d4112b99539974e5f"; + hash = "sha256-WcycWbzKug8vUfNnUDhvgmj1kUCpT1P1YJBfdIC1H9g="; }; build-system = [ @@ -26,9 +27,14 @@ in python3.pkgs.buildPythonPackage rec { patches = [ ./patches/pyproject.patch - ./patches/tasks.patch ./patches/manage.patch ./patches/exercises-no-gifs.patch + + # adds support for proxy auth header + (fetchpatch { + url = "https://github.com/wger-project/wger/pull/1859/commits/d46d469fa802890d7162b07c098802810fc8417c.patch"; + sha256 = "sha256-D+3FmiSokJe9iSJz7ZbRzS+kuP3yV64XhKnQ4Oh5x8c="; + }) ]; # dependencies = with python3.pkgs; [ @@ -86,6 +92,8 @@ in python3.pkgs.buildPythonPackage rec { # fixup compressed files postBuild = let staticSettings = writeText "static_settings.py" '' + import os + DEBUG = False STATIC_ROOT = os.environ["static"] COMPRESS_OFFLINE = True @@ -97,7 +105,7 @@ in python3.pkgs.buildPythonPackage rec { # cp -a ${frontend}/static/yarn $out/${python3.sitePackages}/wger/core/static cp -a ${frontend}/static/yarn wger/core/static - python3 -m wger.tasks create-settings -s $PWD/tmp_settings.py + python3 -m wger create-settings -s $PWD/tmp_settings.py cat ${staticSettings} >> $PWD/tmp_settings.py mkdir tmpstatic pushd tmpstatic diff --git a/machines/gerd/services/wger/wgerpkg/module.nix b/machines/gerd/services/wger/wgerpkg/module.nix index 9b72ed9..4f69f3c 100644 --- a/machines/gerd/services/wger/wgerpkg/module.nix +++ b/machines/gerd/services/wger/wgerpkg/module.nix @@ -138,15 +138,15 @@ in config = mkIf cfg.enable { services.wger.wgerSettings = { EMAIL_FROM = mkDefault "wger Workout Manager "; - ALLOW_REGISTRATION = true; - ALLOW_GUEST_USERS = true; - ALLOW_UPLOAD_VIDEOS = false; - MIN_ACCOUNT_AGE_TO_TRUST = 1; - EXERCISE_CACHE_TTL = 3600; # 1 hour + ALLOW_REGISTRATION = mkDefault true; + ALLOW_GUEST_USERS = mkDefault true; + ALLOW_UPLOAD_VIDEOS = mkDefault false; + MIN_ACCOUNT_AGE_TO_TRUST = mkDefault 1; + EXERCISE_CACHE_TTL = mkDefault 3600; # 1 hour }; services.wger.djangoSettings = rec { - DEBUG = false; + DEBUG = mkDefault false; # configure database as postgresql or sqlite DATABASES.default = if cfg.configurePostgres then { diff --git a/machines/gerd/services/wger/wgerpkg/patches/tasks.patch b/machines/gerd/services/wger/wgerpkg/patches/tasks.patch deleted file mode 100644 index 2f8d150..0000000 --- a/machines/gerd/services/wger/wgerpkg/patches/tasks.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/wger/tasks.py b/wger/tasks.py -index b1b4b7c65..50bf95b7c 100644 ---- a/wger/tasks.py -+++ b/wger/tasks.py -@@ -31,7 +31,7 @@ from django.utils.crypto import get_random_string - - # Third Party - import requests --from invoke import task -+from invoke import task, Program, Collection - from tqdm import tqdm - - -@@ -358,3 +358,20 @@ def database_exists(): - sys.exit(0) - else: - return True -+ -+def main(): -+ ns = Collection( -+ start, -+ bootstrap, -+ create_settings, -+ create_or_reset_admin, -+ migrate_db, -+ load_fixtures, -+ load_online_fixtures, -+ ) -+ program = Program(namespace=ns) -+ program.run() -+ -+ -+if __name__ == "__main__": -+ main() -