From dbfc2207dfd6e5ed7aa5db03c254efbe5b6b49f6 Mon Sep 17 00:00:00 2001 From: WilliButz Date: Sun, 2 Feb 2025 14:16:38 +0100 Subject: [PATCH] treewide: nixfmt --- components/docs.nix | 14 +- components/frontend.nix | 11 +- components/gopkgs.nix | 19 +- components/manage.nix | 29 ++- components/migrate.nix | 41 +-- components/pythonEnv.nix | 25 +- components/staticWorkdirDeps.nix | 44 +++- default.nix | 19 +- flake.nix | 221 +++++++++------- module.nix | 430 +++++++++++++++++-------------- poetry2nix-python-overrides.nix | 319 ++++++++++++----------- shell.nix | 19 +- tests/minimal-vmtest.nix | 9 +- tests/override-scope.nix | 52 ++-- 14 files changed, 688 insertions(+), 564 deletions(-) diff --git a/components/docs.nix b/components/docs.nix index d7428e8..b476407 100644 --- a/components/docs.nix +++ b/components/docs.nix @@ -1,7 +1,8 @@ -{ authentik-src -, authentik-version -, buildNapalmPackage -, nodejs_22 +{ + authentik-src, + authentik-version, + buildNapalmPackage, + nodejs_22, }: buildNapalmPackage "${authentik-src}/website" { @@ -52,8 +53,7 @@ buildNapalmPackage "${authentik-src}/website" { let files = builtins.readDir ./docs-extra-package-locks; in - builtins.concatMap (f: - if files.${f} == "regular" - then [ (./docs-extra-package-locks + "/${f}") ] else [] + builtins.concatMap ( + f: if files.${f} == "regular" then [ (./docs-extra-package-locks + "/${f}") ] else [ ] ) (builtins.attrNames files); } diff --git a/components/frontend.nix b/components/frontend.nix index ccbfa20..91b40d6 100644 --- a/components/frontend.nix +++ b/components/frontend.nix @@ -1,8 +1,9 @@ -{ authentik-src -, authentik-version -, authentikComponents -, buildNapalmPackage -, nodejs_22 +{ + authentik-src, + authentik-version, + authentikComponents, + buildNapalmPackage, + nodejs_22, }: buildNapalmPackage "${authentik-src}/web" rec { version = authentik-version; # 0.0.0 specified upstream in package.json diff --git a/components/gopkgs.nix b/components/gopkgs.nix index ec8e775..d3771fc 100644 --- a/components/gopkgs.nix +++ b/components/gopkgs.nix @@ -1,9 +1,10 @@ -{ authentik-src -, authentik-version -, authentikComponents -, buildGo123Module -, lib -, makeWrapper +{ + authentik-src, + authentik-version, + authentikComponents, + buildGo123Module, + lib, + makeWrapper, }: buildGo123Module { @@ -16,15 +17,15 @@ buildGo123Module { ''; src = lib.cleanSourceWith { src = authentik-src; - filter = (path: _: + filter = ( + path: _: (builtins.any (x: x) ( (map (infix: lib.hasInfix infix path) [ "/authentik" "/cmd" "/internal" ]) - ++ - (map (suffix: lib.hasSuffix suffix path) [ + ++ (map (suffix: lib.hasSuffix suffix path) [ "/web" "/web/static.go" "/web/robots.txt" diff --git a/components/manage.nix b/components/manage.nix index ccf9b8c..a075c5b 100644 --- a/components/manage.nix +++ b/components/manage.nix @@ -1,16 +1,19 @@ -{ authentik-src -, authentikComponents -, makeWrapper -, runCommandLocal +{ + authentik-src, + authentikComponents, + makeWrapper, + runCommandLocal, }: -runCommandLocal "authentik-manage" { - nativeBuildInputs = [ makeWrapper ]; -} '' - mkdir -vp $out/bin - cp -v ${authentik-src}/manage.py $out/bin/manage.py +runCommandLocal "authentik-manage" + { + nativeBuildInputs = [ makeWrapper ]; + } + '' + mkdir -vp $out/bin + cp -v ${authentik-src}/manage.py $out/bin/manage.py - wrapProgram $out/bin/manage.py \ - --prefix PATH : ${authentikComponents.pythonEnv}/bin \ - --prefix PYTHONPATH : ${authentikComponents.staticWorkdirDeps} -'' + wrapProgram $out/bin/manage.py \ + --prefix PATH : ${authentikComponents.pythonEnv}/bin \ + --prefix PYTHONPATH : ${authentikComponents.staticWorkdirDeps} + '' diff --git a/components/migrate.nix b/components/migrate.nix index de94174..dd76c30 100644 --- a/components/migrate.nix +++ b/components/migrate.nix @@ -1,21 +1,24 @@ -{ authentik-src -, authentikComponents -, makeWrapper -, runCommandLocal +{ + authentik-src, + authentikComponents, + makeWrapper, + runCommandLocal, }: -runCommandLocal "authentik-migrate.py" { - nativeBuildInputs = [ makeWrapper ]; -} '' - mkdir -vp $out/bin - cp ${authentik-src}/lifecycle/migrate.py $out/bin/migrate.py - chmod +w $out/bin/migrate.py - patchShebangs $out/bin/migrate.py - substituteInPlace $out/bin/migrate.py \ - --replace \ - 'migration_path in Path(__file__).parent.absolute().glob("system_migrations/*.py")' \ - 'migration_path in Path("${authentikComponents.staticWorkdirDeps}/lifecycle").glob("system_migrations/*.py")' - wrapProgram $out/bin/migrate.py \ - --prefix PATH : ${authentikComponents.pythonEnv}/bin \ - --prefix PYTHONPATH : ${authentikComponents.staticWorkdirDeps} -'' +runCommandLocal "authentik-migrate.py" + { + nativeBuildInputs = [ makeWrapper ]; + } + '' + mkdir -vp $out/bin + cp ${authentik-src}/lifecycle/migrate.py $out/bin/migrate.py + chmod +w $out/bin/migrate.py + patchShebangs $out/bin/migrate.py + substituteInPlace $out/bin/migrate.py \ + --replace \ + 'migration_path in Path(__file__).parent.absolute().glob("system_migrations/*.py")' \ + 'migration_path in Path("${authentikComponents.staticWorkdirDeps}/lifecycle").glob("system_migrations/*.py")' + wrapProgram $out/bin/migrate.py \ + --prefix PATH : ${authentikComponents.pythonEnv}/bin \ + --prefix PYTHONPATH : ${authentikComponents.staticWorkdirDeps} + '' diff --git a/components/pythonEnv.nix b/components/pythonEnv.nix index 4bc6d9f..76b830e 100644 --- a/components/pythonEnv.nix +++ b/components/pythonEnv.nix @@ -1,9 +1,10 @@ -{ authentik-src -, authentikPoetryOverrides -, defaultPoetryOverrides -, lib -, mkPoetryEnv -, python312 +{ + authentik-src, + authentikPoetryOverrides, + defaultPoetryOverrides, + lib, + mkPoetryEnv, + python312, }: mkPoetryEnv { @@ -12,13 +13,13 @@ mkPoetryEnv { overrides = [ defaultPoetryOverrides ] ++ authentikPoetryOverrides; - groups = ["main"]; - checkGroups = []; + groups = [ "main" ]; + checkGroups = [ ]; # workaround to remove dev-dependencies for the current combination of legacy # used by authentik and poetry2nix's behavior - pyproject = builtins.toFile "patched-pyproject.toml" (lib.replaceStrings - ["tool.poetry.dev-dependencies"] - ["tool.poetry.group.dev.dependencies"] - (builtins.readFile "${authentik-src}/pyproject.toml") + pyproject = builtins.toFile "patched-pyproject.toml" ( + lib.replaceStrings [ "tool.poetry.dev-dependencies" ] [ "tool.poetry.group.dev.dependencies" ] ( + builtins.readFile "${authentik-src}/pyproject.toml" + ) ); } diff --git a/components/staticWorkdirDeps.nix b/components/staticWorkdirDeps.nix index 8e07bb8..2b85f96 100644 --- a/components/staticWorkdirDeps.nix +++ b/components/staticWorkdirDeps.nix @@ -1,7 +1,8 @@ -{ authentik-src -, authentikComponents -, linkFarm -, applyPatches +{ + authentik-src, + authentikComponents, + linkFarm, + applyPatches, }: let patched-src = applyPatches { @@ -14,11 +15,32 @@ let }; in linkFarm "authentik-static-workdir-deps" [ - { name = "authentik"; path = "${patched-src}/authentik"; } - { name = "locale"; path = "${authentik-src}/locale"; } - { name = "blueprints"; path = "${authentik-src}/blueprints"; } - { name = "internal"; path = "${authentik-src}/internal"; } - { name = "lifecycle"; path = "${patched-src}/lifecycle"; } - { name = "schemas"; path = "${authentik-src}/schemas"; } - { name = "web"; path = authentikComponents.frontend; } + { + name = "authentik"; + path = "${patched-src}/authentik"; + } + { + name = "locale"; + path = "${authentik-src}/locale"; + } + { + name = "blueprints"; + path = "${authentik-src}/blueprints"; + } + { + name = "internal"; + path = "${authentik-src}/internal"; + } + { + name = "lifecycle"; + path = "${patched-src}/lifecycle"; + } + { + name = "schemas"; + path = "${authentik-src}/schemas"; + } + { + name = "web"; + path = authentikComponents.frontend; + } ] diff --git a/default.nix b/default.nix index 2cccff2..6466507 100644 --- a/default.nix +++ b/default.nix @@ -1,10 +1,9 @@ -(import - ( - let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; - sha256 = lock.nodes.flake-compat.locked.narHash; - } - ) - { src = ./.; } -).defaultNix +(import ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } +) { src = ./.; }).defaultNix diff --git a/flake.nix b/flake.nix index 0fe8d80..2a1ac10 100644 --- a/flake.nix +++ b/flake.nix @@ -30,101 +30,150 @@ flake-utils.follows = "flake-utils"; }; }; - authentik-src = { # change version string in outputs as well when updating + authentik-src = { + # change version string in outputs as well when updating url = "github:goauthentik/authentik/version/2024.12.3"; flake = false; }; }; - outputs = inputs@{ - self, - nixpkgs, - flake-parts, - poetry2nix, - napalm, - authentik-src, - ... - }: + outputs = + inputs@{ + self, + nixpkgs, + flake-parts, + poetry2nix, + napalm, + authentik-src, + ... + }: - flake-parts.lib.mkFlake - { inherit inputs; } - ({ inputs, lib, withSystem, ... }: - let - authentik-version = "2024.12.3"; # to pass to the drvs of some components - in { - systems = import inputs.systems; - flake = { self, ... }: { - nixosModules.default = { pkgs, ... }: { - imports = [ ./module.nix ]; - services.authentik.authentikComponents = pkgs.lib.mkDefault (withSystem pkgs.stdenv.hostPlatform.system ( - { config, ... }: - { inherit (config.packages) manage staticWorkdirDeps migrate pythonEnv frontend gopkgs docs; } - )); - }; + flake-parts.lib.mkFlake { inherit inputs; } ( + { + inputs, + lib, + withSystem, + ... + }: + let + authentik-version = "2024.12.3"; # to pass to the drvs of some components + in + { + systems = import inputs.systems; + flake = + { self, ... }: + { + nixosModules.default = + { pkgs, ... }: + { + imports = [ ./module.nix ]; + services.authentik.authentikComponents = pkgs.lib.mkDefault ( + withSystem pkgs.stdenv.hostPlatform.system ( + { config, ... }: + { + inherit (config.packages) + manage + staticWorkdirDeps + migrate + pythonEnv + frontend + gopkgs + docs + ; + } + ) + ); + }; - # returns a scope which includes the attrset `authentikComponents` - # - # the returned scope may be overridden using its `overrideScope` function to - # create a new scope with patched versions of individual authentik components - # - # see ./tests/override-scope.nix for a usage example - lib.mkAuthentikScope = let authentik-version' = authentik-version; in { - pkgs, - system ? pkgs.stdenv.hostPlatform.system, - authentik-version ? authentik-version', - mkPoetryEnv ? (import inputs.poetry2nix { inherit pkgs; }).mkPoetryEnv, - defaultPoetryOverrides ? (import inputs.poetry2nix { inherit pkgs; }).defaultPoetryOverrides, - authentikPoetryOverrides ? import ./poetry2nix-python-overrides.nix pkgs, - buildNapalmPackage ? napalm.legacyPackages.${system}.buildPackage - }: - import ./components { - inherit pkgs authentik-src authentik-version mkPoetryEnv defaultPoetryOverrides authentikPoetryOverrides buildNapalmPackage; + # returns a scope which includes the attrset `authentikComponents` + # + # the returned scope may be overridden using its `overrideScope` function to + # create a new scope with patched versions of individual authentik components + # + # see ./tests/override-scope.nix for a usage example + lib.mkAuthentikScope = + let + authentik-version' = authentik-version; + in + { + pkgs, + system ? pkgs.stdenv.hostPlatform.system, + authentik-version ? authentik-version', + mkPoetryEnv ? (import inputs.poetry2nix { inherit pkgs; }).mkPoetryEnv, + defaultPoetryOverrides ? (import inputs.poetry2nix { inherit pkgs; }).defaultPoetryOverrides, + authentikPoetryOverrides ? import ./poetry2nix-python-overrides.nix pkgs, + buildNapalmPackage ? napalm.legacyPackages.${system}.buildPackage, + }: + import ./components { + inherit + pkgs + authentik-src + authentik-version + mkPoetryEnv + defaultPoetryOverrides + authentikPoetryOverrides + buildNapalmPackage + ; + }; }; - }; - perSystem = { pkgs, system, self', ... }: let - inherit (self.lib.mkAuthentikScope { inherit pkgs; }) authentikComponents; - in { - packages = { - inherit (authentikComponents) - docs - frontend - pythonEnv - gopkgs - staticWorkdirDeps - migrate - manage; + perSystem = + { + pkgs, + system, + self', + ... + }: + let + inherit (self.lib.mkAuthentikScope { inherit pkgs; }) authentikComponents; + in + { + packages = { + inherit (authentikComponents) + docs + frontend + pythonEnv + gopkgs + staticWorkdirDeps + migrate + manage + ; - terraform-provider-authentik = inputs.nixpkgs.legacyPackages.${system}.buildGo123Module rec { - pname = "terraform-provider-authentik"; - version = "2024.10.1"; - src = pkgs.fetchFromGitHub { - owner = "goauthentik"; - repo = pname; - rev = "v${version}"; - sha256 = "sha256-vU1VHDlxwi5YblVBa3lE1BLuk1Qr3AMSmHY9adkLQZU="; + terraform-provider-authentik = inputs.nixpkgs.legacyPackages.${system}.buildGo123Module rec { + pname = "terraform-provider-authentik"; + version = "2024.10.1"; + src = pkgs.fetchFromGitHub { + owner = "goauthentik"; + repo = pname; + rev = "v${version}"; + sha256 = "sha256-vU1VHDlxwi5YblVBa3lE1BLuk1Qr3AMSmHY9adkLQZU="; + }; + doCheck = false; # tests are run against authentik -> vm test + vendorHash = "sha256-MtTfEOev6NrZyly5VrTVhoIJZsQX/4xyZcQul5fVO50="; + postInstall = '' + path="$out/libexec/terraform-providers/registry.terraform.io/goauthentik/authentik/${version}/''${GOOS}_''${GOARCH}/" + mkdir -p "$path" + mv $out/bin/${pname} $path/${pname}_v${version} + rmdir $out/bin + ''; + }; + }; + checks = { + default = self.checks.${system}.vmtest; + vmtest = ( + import tests/minimal-vmtest.nix { + inherit pkgs authentik-version; + inherit (self) nixosModules; + } + ); + override-scope = ( + import tests/override-scope.nix { + inherit pkgs authentik-version; + inherit (self) nixosModules; + inherit (self.lib) mkAuthentikScope; + } + ); }; - doCheck = false; # tests are run against authentik -> vm test - vendorHash = "sha256-MtTfEOev6NrZyly5VrTVhoIJZsQX/4xyZcQul5fVO50="; - postInstall = '' - path="$out/libexec/terraform-providers/registry.terraform.io/goauthentik/authentik/${version}/''${GOOS}_''${GOARCH}/" - mkdir -p "$path" - mv $out/bin/${pname} $path/${pname}_v${version} - rmdir $out/bin - ''; }; - }; - checks = { - default = self.checks.${system}.vmtest; - vmtest = (import tests/minimal-vmtest.nix { - inherit pkgs authentik-version; - inherit (self) nixosModules; - }); - override-scope = (import tests/override-scope.nix { - inherit pkgs authentik-version; - inherit (self) nixosModules; - inherit (self.lib) mkAuthentikScope; - }); - }; - }; - }); + } + ); } diff --git a/module.nix b/module.nix index 8963d2b..970e3c0 100644 --- a/module.nix +++ b/module.nix @@ -1,41 +1,49 @@ -{ config -, lib -, pkgs -, ... +{ + config, + lib, + pkgs, + ... }: let inherit (lib) - types; + types + ; inherit (lib.attrsets) attrNames getAttrs - mapAttrsToList; + mapAttrsToList + ; inherit (lib.lists) flatten - toList; + toList + ; inherit (lib.modules) mkDefault mkIf mkMerge - mkOverride; + mkOverride + ; inherit (lib.options) mkEnableOption - mkOption; + mkOption + ; inherit (lib.strings) concatStringsSep optionalString - versionOlder; + versionOlder + ; inherit (lib.trivial) boolToString - isBool; + isBool + ; - settingsFormat = pkgs.formats.yaml {}; + settingsFormat = pkgs.formats.yaml { }; in { options.services = { @@ -50,7 +58,7 @@ in settings = mkOption { type = types.submodule { freeformType = settingsFormat.type; - options = {}; + options = { }; }; }; @@ -141,211 +149,233 @@ in config = mkMerge [ # authentik server - (mkIf config.services.authentik.enable (let - cfg = config.services.authentik; + (mkIf config.services.authentik.enable ( + let + cfg = config.services.authentik; - # https://goauthentik.io/docs/installation/docker-compose#startup - tz = "UTC"; + # https://goauthentik.io/docs/installation/docker-compose#startup + tz = "UTC"; - # Passed to each service and to the `ak` wrapper using `systemd-run(1)` - serviceDefaults = { - DynamicUser = true; - User = "authentik"; - EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; - }; - akOptions = flatten (mapAttrsToList - # Map defaults for each authentik service (listed above) to command line parameters for - # `systemd-run(1)` in order to spin up an environment with correct (dynamic) user, - # state directory and environment to run `ak` inside. - (k: vs: map - (v: "--property ${k}=${if isBool v then boolToString v else toString v}") - (toList vs)) - # Read serviceDefaults from `authentik.service`. That way, module system primitives (mk*) - # can be used inside `serviceDefaults` and it doesn't need to be evaluated here again. - (getAttrs (attrNames serviceDefaults) config.systemd.services.authentik.serviceConfig // { - StateDirectory = "authentik"; - })); - in - { - services = { - authentik.settings = { - blueprints_dir = mkDefault "${cfg.authentikComponents.staticWorkdirDeps}/blueprints"; - template_dir = mkDefault "${cfg.authentikComponents.staticWorkdirDeps}/templates"; - postgresql = mkIf cfg.createDatabase { - user = mkDefault "authentik"; - name = mkDefault "authentik"; - host = mkDefault ""; + # Passed to each service and to the `ak` wrapper using `systemd-run(1)` + serviceDefaults = { + DynamicUser = true; + User = "authentik"; + EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; + }; + akOptions = flatten ( + mapAttrsToList + # Map defaults for each authentik service (listed above) to command line parameters for + # `systemd-run(1)` in order to spin up an environment with correct (dynamic) user, + # state directory and environment to run `ak` inside. + (k: vs: map (v: "--property ${k}=${if isBool v then boolToString v else toString v}") (toList vs)) + # Read serviceDefaults from `authentik.service`. That way, module system primitives (mk*) + # can be used inside `serviceDefaults` and it doesn't need to be evaluated here again. + ( + getAttrs (attrNames serviceDefaults) config.systemd.services.authentik.serviceConfig + // { + StateDirectory = "authentik"; + } + ) + ); + in + { + services = { + authentik.settings = { + blueprints_dir = mkDefault "${cfg.authentikComponents.staticWorkdirDeps}/blueprints"; + template_dir = mkDefault "${cfg.authentikComponents.staticWorkdirDeps}/templates"; + postgresql = mkIf cfg.createDatabase { + user = mkDefault "authentik"; + name = mkDefault "authentik"; + host = mkDefault ""; + }; + cert_discovery_dir = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) "env://CREDENTIALS_DIRECTORY"; + storage.media = { + backend = mkDefault "file"; + file = mkDefault { + path = "/var/lib/authentik/media"; + }; + }; + media.enable_upload = mkDefault true; }; - cert_discovery_dir = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) "env://CREDENTIALS_DIRECTORY"; - storage.media = { - backend = mkDefault "file"; - file = mkDefault { - path = "/var/lib/authentik/media"; + redis.servers.authentik = { + enable = true; + port = 6379; + }; + postgresql = mkIf cfg.createDatabase { + enable = true; + ensureDatabases = [ "authentik" ]; + ensureUsers = [ + { + name = "authentik"; + ensureDBOwnership = true; + } + ]; + }; + }; + + environment.systemPackages = [ + (pkgs.writeShellScriptBin "ak" '' + exec ${config.systemd.package}/bin/systemd-run --pty --collect \ + ${concatStringsSep " \\\n" akOptions} \ + --working-directory /var/lib/authentik \ + -- ${cfg.authentikComponents.manage}/bin/manage.py "$@" + '') + ]; + + environment.etc."authentik/config.yml".source = + settingsFormat.generate "authentik.yml" cfg.settings; + + systemd.services = { + authentik-migrate = { + requiredBy = [ "authentik.service" ]; + requires = lib.optionals cfg.createDatabase [ "postgresql.service" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ] ++ lib.optionals cfg.createDatabase [ "postgresql.service" ]; + before = [ "authentik.service" ]; + restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; + environment.TZ = tz; + serviceConfig = mkMerge [ + serviceDefaults + { + Type = "oneshot"; + RemainAfterExit = true; + RuntimeDirectory = "authentik-migrate"; + WorkingDirectory = "%t/authentik-migrate"; + ExecStartPre = [ + # needs access to "authentik/sources/schemas" + "${pkgs.coreutils}/bin/ln -svf ${cfg.authentikComponents.staticWorkdirDeps}/authentik" + ]; + ExecStart = "${cfg.authentikComponents.migrate}/bin/migrate.py"; + Restart = "on-failure"; + RestartSec = "1s"; + inherit (config.systemd.services.authentik.serviceConfig) StateDirectory; + } + ]; + }; + authentik-worker = { + requiredBy = [ "authentik.service" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + before = [ "authentik.service" ]; + restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; + preStart = '' + ln -svf ${config.services.authentik.authentikComponents.staticWorkdirDeps}/* /run/authentik/ + ''; + environment.TZ = tz; + serviceConfig = mkMerge [ + serviceDefaults + { + RuntimeDirectory = "authentik"; + WorkingDirectory = "%t/authentik"; + ExecStart = "${cfg.authentikComponents.manage}/bin/manage.py worker"; + Restart = "on-failure"; + RestartSec = "1s"; + LoadCredential = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) [ + "${cfg.nginx.host}.pem:${config.security.acme.certs.${cfg.nginx.host}.directory}/fullchain.pem" + "${cfg.nginx.host}.key:${config.security.acme.certs.${cfg.nginx.host}.directory}/key.pem" + ]; + # needs access to $StateDirectory/media/public + inherit (config.systemd.services.authentik.serviceConfig) StateDirectory; + } + ]; + }; + authentik = { + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ + "network-online.target" + "redis-authentik.service" + ] ++ (lib.optionals cfg.createDatabase [ "postgresql.service" ]); + restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; + preStart = '' + ln -svf ${cfg.authentikComponents.staticWorkdirDeps}/* /var/lib/authentik/ + ${optionalString (cfg.settings.storage.media.backend == "file") '' + mkdir -p ${cfg.settings.storage.media.file.path} + ''} + ''; + environment.TZ = tz; + serviceConfig = mkMerge [ + serviceDefaults + { + StateDirectory = "authentik"; + UMask = "0027"; + # TODO /run might be sufficient + WorkingDirectory = "%S/authentik"; + ExecStart = "${cfg.authentikComponents.gopkgs}/bin/server"; + Restart = "on-failure"; + RestartSec = "1s"; + } + ]; + }; + }; + + services.nginx = mkIf cfg.nginx.enable { + enable = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + virtualHosts.${cfg.nginx.host} = { + inherit (cfg.nginx) enableACME; + forceSSL = cfg.nginx.enableACME; + locations."/" = { + proxyWebsockets = true; + proxyPass = "https://localhost:9443"; }; }; - media.enable_upload = mkDefault true; }; - redis.servers.authentik = { - enable = true; - port = 6379; - }; - postgresql = mkIf cfg.createDatabase { - enable = true; - ensureDatabases = [ "authentik" ]; - ensureUsers = [ - { name = "authentik"; ensureDBOwnership = true; } - ]; - }; - }; + } + )) - environment.systemPackages = [ - (pkgs.writeShellScriptBin "ak" '' - exec ${config.systemd.package}/bin/systemd-run --pty --collect \ - ${concatStringsSep " \\\n" akOptions} \ - --working-directory /var/lib/authentik \ - -- ${cfg.authentikComponents.manage}/bin/manage.py "$@" - '') - ]; - - environment.etc."authentik/config.yml".source = settingsFormat.generate "authentik.yml" cfg.settings; - - systemd.services = { - authentik-migrate = { - requiredBy = [ "authentik.service" ]; - requires = lib.optionals cfg.createDatabase [ "postgresql.service" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ] ++ lib.optionals cfg.createDatabase [ "postgresql.service" ]; - before = [ "authentik.service" ]; - restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; - environment.TZ = tz; - serviceConfig = mkMerge [ serviceDefaults { - Type = "oneshot"; - RemainAfterExit = true; - RuntimeDirectory = "authentik-migrate"; - WorkingDirectory = "%t/authentik-migrate"; - ExecStartPre = [ - # needs access to "authentik/sources/schemas" - "${pkgs.coreutils}/bin/ln -svf ${cfg.authentikComponents.staticWorkdirDeps}/authentik" - ]; - ExecStart = "${cfg.authentikComponents.migrate}/bin/migrate.py"; - Restart = "on-failure"; - RestartSec = "1s"; - inherit (config.systemd.services.authentik.serviceConfig) StateDirectory; - } ]; - }; - authentik-worker = { - requiredBy = [ "authentik.service" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; - before = [ "authentik.service" ]; - restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; - preStart = '' - ln -svf ${config.services.authentik.authentikComponents.staticWorkdirDeps}/* /run/authentik/ - ''; - environment.TZ = tz; - serviceConfig = mkMerge [ serviceDefaults { - RuntimeDirectory = "authentik"; - WorkingDirectory = "%t/authentik"; - ExecStart = "${cfg.authentikComponents.manage}/bin/manage.py worker"; - Restart = "on-failure"; - RestartSec = "1s"; - LoadCredential = mkIf (cfg.nginx.enable && cfg.nginx.enableACME) [ - "${cfg.nginx.host}.pem:${config.security.acme.certs.${cfg.nginx.host}.directory}/fullchain.pem" - "${cfg.nginx.host}.key:${config.security.acme.certs.${cfg.nginx.host}.directory}/key.pem" - ]; - # needs access to $StateDirectory/media/public - inherit (config.systemd.services.authentik.serviceConfig) StateDirectory; - } ]; - }; - authentik = { + # LDAP outpost + (mkIf config.services.authentik-ldap.enable ( + let + cfg = config.services.authentik-ldap; + in + { + systemd.services.authentik-ldap = { wantedBy = [ "multi-user.target" ]; wants = [ "network-online.target" ]; after = [ "network-online.target" - "redis-authentik.service" - ] ++ (lib.optionals cfg.createDatabase [ "postgresql.service" ]); - restartTriggers = [ config.environment.etc."authentik/config.yml".source ]; - preStart = '' - ln -svf ${cfg.authentikComponents.staticWorkdirDeps}/* /var/lib/authentik/ - ${optionalString (cfg.settings.storage.media.backend == "file") '' - mkdir -p ${cfg.settings.storage.media.file.path} - ''} - ''; - environment.TZ = tz; - serviceConfig = mkMerge [ serviceDefaults { - StateDirectory = "authentik"; + "authentik.service" + ]; + serviceConfig = { + RuntimeDirectory = "authentik-ldap"; UMask = "0027"; - # TODO /run might be sufficient - WorkingDirectory = "%S/authentik"; - ExecStart = "${cfg.authentikComponents.gopkgs}/bin/server"; + WorkingDirectory = "%t/authentik-ldap"; + DynamicUser = true; + ExecStart = "${config.services.authentik.authentikComponents.gopkgs}/bin/ldap"; + EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; Restart = "on-failure"; - RestartSec = "1s"; - } ]; - }; - }; - - services.nginx = mkIf cfg.nginx.enable { - enable = true; - recommendedTlsSettings = true; - recommendedProxySettings = true; - virtualHosts.${cfg.nginx.host} = { - inherit (cfg.nginx) enableACME; - forceSSL = cfg.nginx.enableACME; - locations."/" = { - proxyWebsockets = true; - proxyPass = "https://localhost:9443"; }; }; - }; - })) - - # LDAP outpost - (mkIf config.services.authentik-ldap.enable (let - cfg = config.services.authentik-ldap; - in - { - systemd.services.authentik-ldap = { - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ - "network-online.target" - "authentik.service" - ]; - serviceConfig = { - RuntimeDirectory = "authentik-ldap"; - UMask = "0027"; - WorkingDirectory = "%t/authentik-ldap"; - DynamicUser = true; - ExecStart = "${config.services.authentik.authentikComponents.gopkgs}/bin/ldap"; - EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; - Restart = "on-failure"; - }; - }; - })) + } + )) # RADIUS outpost - (mkIf config.services.authentik-radius.enable (let - cfg = config.services.authentik-radius; - in - { - systemd.services.authentik-radius = { - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ - "network-online.target" - "authentik.service" - ]; - serviceConfig = { - RuntimeDirectory = "authentik-radius"; - UMask = "0027"; - WorkingDirectory = "%t/authentik-radius"; - DynamicUser = true; - ExecStart = "${config.services.authentik.authentikComponents.gopkgs}/bin/radius"; - EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; - Restart = "on-failure"; + (mkIf config.services.authentik-radius.enable ( + let + cfg = config.services.authentik-radius; + in + { + systemd.services.authentik-radius = { + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ + "network-online.target" + "authentik.service" + ]; + serviceConfig = { + RuntimeDirectory = "authentik-radius"; + UMask = "0027"; + WorkingDirectory = "%t/authentik-radius"; + DynamicUser = true; + ExecStart = "${config.services.authentik.authentikComponents.gopkgs}/bin/radius"; + EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ]; + Restart = "on-failure"; + }; }; - }; - })) + } + )) # This is an attempt to solve a rather ugly problem that was # caused by previously setting a default for the option diff --git a/poetry2nix-python-overrides.nix b/poetry2nix-python-overrides.nix index dd1c434..06d491e 100644 --- a/poetry2nix-python-overrides.nix +++ b/poetry2nix-python-overrides.nix @@ -1,158 +1,169 @@ -pkgs: -[ +pkgs: [ # modules missing only setuptools - (final: prev: - (builtins.listToAttrs (map (name: { - inherit name; - value = prev.${name}.overrideAttrs (oA: { - nativeBuildInputs = (oA.nativeBuildInputs or []) ++ [ final.setuptools ]; - }); - }) [ - "django-cte" - "django-tenants" - "dumb-init" - "drf-orjson-renderer" - ])) + ( + final: prev: + (builtins.listToAttrs ( + map + (name: { + inherit name; + value = prev.${name}.overrideAttrs (oA: { + nativeBuildInputs = (oA.nativeBuildInputs or [ ]) ++ [ final.setuptools ]; + }); + }) + [ + "django-cte" + "django-tenants" + "dumb-init" + "drf-orjson-renderer" + ] + )) ) (final: prev: { - xmlsec = prev.xmlsec.overridePythonAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ final.setuptools final.pkgconfig ]; - buildInputs = [ pkgs.xmlsec.dev pkgs.xmlsec pkgs.libxml2 pkgs.libtool ]; - env.NIX_CFLAGS_COMPILE = "-Wno-error=incompatible-pointer-types"; - }); - opencontainers = prev.opencontainers.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.setuptools - final.pytest - ]; - postPatch = '' - substituteInPlace setup.py --replace-fail '"pytest-runner"' ''' - ''; - }); - psycopg-c = prev.psycopg-c.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.setuptools - final.tomli - pkgs.postgresql - ]; - }); - twisted = prev.twisted.overrideAttrs (oA: { - buildInputs = oA.buildInputs ++ [ - final.hatchling - final.hatch-fancy-pypi-readme - ]; - }); - #cryptography = prev.cryptography.overridePythonAttrs (oA: { - # cargoDeps = pkgs.rustPlatform.fetchCargoTarball { - # src = oA.src; - # sourceRoot = "${oA.pname}-${oA.version}/src/rust"; - # name = "${oA.pname}-${oA.version}"; - # sha256 = "sha256-PgxPcFocEhnQyrsNtCN8YHiMptBmk1PUhEDQFdUR1nU="; - # }; - #}); - dnspython = prev.dnspython.overrideAttrs (oA: { - buildInputs = oA.buildInputs ++ [ - final.hatchling - ]; - }); - sqlparse = prev.sqlparse.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.hatchling - ]; - }); - scim2-filter-parser = prev.scim2-filter-parser.overrideAttrs (oA: { - patches = [ - (pkgs.fetchpatch { - name = "replace-poetry-with-poetry-core.patch"; - url = "https://patch-diff.githubusercontent.com/raw/15five/scim2-filter-parser/pull/43.patch"; - hash = "sha256-PjJH1S5CDe/BMI0+mB34KdpNNcHfexBFYBmHolsWH4o="; - }) - ]; - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.poetry-core - ]; - }); - pendulum = prev.pendulum.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - pkgs.rustPlatform.cargoSetupHook - pkgs.rustPlatform.maturinBuildHook - ]; - cargoRoot = "rust"; - cargoDeps = pkgs.rustPlatform.fetchCargoTarball { - src = oA.src; - sourceRoot = "${oA.pname}-${oA.version}/rust"; - name = "${oA.pname}-${oA.version}"; - sha256 = "sha256-6fw0KgnPIMfdseWcunsGjvjVB+lJNoG3pLDqkORPJ0I="; - }; - }); - django-pgactivity = prev.django-pgactivity.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.poetry-core - ]; - }); - docker = prev.docker.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - prev.hatchling - prev.hatch-vcs - ]; - }); - django-pglock= prev.django-pglock.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.poetry-core - ]; - }); - # https://github.com/pyradius/pyrad/pull/168/files - # not included in the latest release :/ - pyrad = prev.pyrad.overrideAttrs (oA: { - postPatch = '' - substituteInPlace pyproject.toml \ - --replace-fail "poetry.masonry.api" "poetry.core.masonry.api" \ - --replace-fail "repository =" "Repository =" - ''; - }); - msgraph-sdk = prev.msgraph-sdk.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.flit-core - ]; - }); - python-kadmin-rs = prev.python-kadmin-rs.overrideAttrs (oA: { - pythonImportsCheck = [ "kadmin" ]; - nativeBuildInputs = oA.nativeBuildInputs ++ [ - pkgs.rustPlatform.cargoSetupHook - pkgs.rustc - pkgs.cargo - final.setuptools - final.setuptools-scm - final.setuptools-rust - pkgs.sccache - pkgs.pkg-config - pkgs.rustPlatform.bindgenHook - pkgs.libkrb5 - ]; - buildInputs = oA.buildInputs ++ [ - pkgs.krb5 - ]; - cargoDeps = pkgs.rustPlatform.fetchCargoTarball { - inherit (oA) pname version src; - hash = "sha256-iH2fm4OUwLdx+lqmPNOkzM3LH6gBVYDtZ+livhOQrE4="; - }; - }); - gssapi = prev.gssapi.overrideAttrs (oA: { - nativeBuildInputs = oA.nativeBuildInputs ++ [ - final.setuptools - final.cython - pkgs.krb5 - ]; - postPatch = '' - substituteInPlace setup.py \ - --replace-fail 'get_output(f"{kc} gssapi --prefix")' '"${pkgs.krb5.dev}"' - ''; - pythonImportsCheck = [ "gssapi" ]; - }); - # break dependency cycle that causes an infinite recursion - ua-parser-builtins = prev.ua-parser-builtins.overridePythonAttrs (oA: { - propagatedBuildInputs = builtins.filter (p: p.pname != "ua-parser") oA.propagatedBuildInputs; - }); - } - ) + xmlsec = prev.xmlsec.overridePythonAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.setuptools + final.pkgconfig + ]; + buildInputs = [ + pkgs.xmlsec.dev + pkgs.xmlsec + pkgs.libxml2 + pkgs.libtool + ]; + env.NIX_CFLAGS_COMPILE = "-Wno-error=incompatible-pointer-types"; + }); + opencontainers = prev.opencontainers.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.setuptools + final.pytest + ]; + postPatch = '' + substituteInPlace setup.py --replace-fail '"pytest-runner"' ''' + ''; + }); + psycopg-c = prev.psycopg-c.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.setuptools + final.tomli + pkgs.postgresql + ]; + }); + twisted = prev.twisted.overrideAttrs (oA: { + buildInputs = oA.buildInputs ++ [ + final.hatchling + final.hatch-fancy-pypi-readme + ]; + }); + #cryptography = prev.cryptography.overridePythonAttrs (oA: { + # cargoDeps = pkgs.rustPlatform.fetchCargoTarball { + # src = oA.src; + # sourceRoot = "${oA.pname}-${oA.version}/src/rust"; + # name = "${oA.pname}-${oA.version}"; + # sha256 = "sha256-PgxPcFocEhnQyrsNtCN8YHiMptBmk1PUhEDQFdUR1nU="; + # }; + #}); + dnspython = prev.dnspython.overrideAttrs (oA: { + buildInputs = oA.buildInputs ++ [ + final.hatchling + ]; + }); + sqlparse = prev.sqlparse.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.hatchling + ]; + }); + scim2-filter-parser = prev.scim2-filter-parser.overrideAttrs (oA: { + patches = [ + (pkgs.fetchpatch { + name = "replace-poetry-with-poetry-core.patch"; + url = "https://patch-diff.githubusercontent.com/raw/15five/scim2-filter-parser/pull/43.patch"; + hash = "sha256-PjJH1S5CDe/BMI0+mB34KdpNNcHfexBFYBmHolsWH4o="; + }) + ]; + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.poetry-core + ]; + }); + pendulum = prev.pendulum.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + pkgs.rustPlatform.cargoSetupHook + pkgs.rustPlatform.maturinBuildHook + ]; + cargoRoot = "rust"; + cargoDeps = pkgs.rustPlatform.fetchCargoTarball { + src = oA.src; + sourceRoot = "${oA.pname}-${oA.version}/rust"; + name = "${oA.pname}-${oA.version}"; + sha256 = "sha256-6fw0KgnPIMfdseWcunsGjvjVB+lJNoG3pLDqkORPJ0I="; + }; + }); + django-pgactivity = prev.django-pgactivity.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.poetry-core + ]; + }); + docker = prev.docker.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + prev.hatchling + prev.hatch-vcs + ]; + }); + django-pglock = prev.django-pglock.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.poetry-core + ]; + }); + # https://github.com/pyradius/pyrad/pull/168/files + # not included in the latest release :/ + pyrad = prev.pyrad.overrideAttrs (oA: { + postPatch = '' + substituteInPlace pyproject.toml \ + --replace-fail "poetry.masonry.api" "poetry.core.masonry.api" \ + --replace-fail "repository =" "Repository =" + ''; + }); + msgraph-sdk = prev.msgraph-sdk.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.flit-core + ]; + }); + python-kadmin-rs = prev.python-kadmin-rs.overrideAttrs (oA: { + pythonImportsCheck = [ "kadmin" ]; + nativeBuildInputs = oA.nativeBuildInputs ++ [ + pkgs.rustPlatform.cargoSetupHook + pkgs.rustc + pkgs.cargo + final.setuptools + final.setuptools-scm + final.setuptools-rust + pkgs.sccache + pkgs.pkg-config + pkgs.rustPlatform.bindgenHook + pkgs.libkrb5 + ]; + buildInputs = oA.buildInputs ++ [ + pkgs.krb5 + ]; + cargoDeps = pkgs.rustPlatform.fetchCargoTarball { + inherit (oA) pname version src; + hash = "sha256-iH2fm4OUwLdx+lqmPNOkzM3LH6gBVYDtZ+livhOQrE4="; + }; + }); + gssapi = prev.gssapi.overrideAttrs (oA: { + nativeBuildInputs = oA.nativeBuildInputs ++ [ + final.setuptools + final.cython + pkgs.krb5 + ]; + postPatch = '' + substituteInPlace setup.py \ + --replace-fail 'get_output(f"{kc} gssapi --prefix")' '"${pkgs.krb5.dev}"' + ''; + pythonImportsCheck = [ "gssapi" ]; + }); + # break dependency cycle that causes an infinite recursion + ua-parser-builtins = prev.ua-parser-builtins.overridePythonAttrs (oA: { + propagatedBuildInputs = builtins.filter (p: p.pname != "ua-parser") oA.propagatedBuildInputs; + }); + }) ] diff --git a/shell.nix b/shell.nix index 6234bb4..493783d 100644 --- a/shell.nix +++ b/shell.nix @@ -1,10 +1,9 @@ -(import - ( - let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in - fetchTarball { - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; - sha256 = lock.nodes.flake-compat.locked.narHash; - } - ) - { src = ./.; } -).shellNix +(import ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + in + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } +) { src = ./.; }).shellNix diff --git a/tests/minimal-vmtest.nix b/tests/minimal-vmtest.nix index 3cbc297..0586757 100644 --- a/tests/minimal-vmtest.nix +++ b/tests/minimal-vmtest.nix @@ -1,6 +1,7 @@ -{ pkgs -, authentik-version -, nixosModules +{ + pkgs, + authentik-version, + nixosModules, }: let # use a root-owned EnvironmentFile in production instead (services.authentik.environmentFile) @@ -80,7 +81,7 @@ pkgs.nixosTest { machine.succeed("su - alice -c 'xdotool key --delay 100 Page_Down' >&2") # sometimes the cursor covers the version string machine.succeed("su - alice -c 'xdotool mousemove_relative 50 50' >&2") - machine.wait_for_text("${builtins.replaceStrings ["."] [".?"] authentik-version}") + machine.wait_for_text("${builtins.replaceStrings [ "." ] [ ".?" ] authentik-version}") machine.screenshot("4_correct_version_in_admin_interface") with subtest("nginx proxies to authentik"): diff --git a/tests/override-scope.nix b/tests/override-scope.nix index ab86738..96db5ee 100644 --- a/tests/override-scope.nix +++ b/tests/override-scope.nix @@ -1,20 +1,21 @@ -{ pkgs -, authentik-version -, nixosModules -, mkAuthentikScope +{ + pkgs, + authentik-version, + nixosModules, + mkAuthentikScope, }: /* - * This is just meant as a demonstration on how to override the scope which includes the - * authentik components. This is an extended version of ./minimal-vmtest.nix - * - * First, a new scope is created from the default one using `overrideScope` on the result - * from `mkAuthentikScope`. - * Components with overrides in that scope are used by their dependents, i.e. dependents - * of `pythonEnv` (e.g. gopkgs) also pull in that overridden `pythonEnv` - * Then, that scope is passed to the module via the `services.authentik.authentikComponents` option - * And finally, the test script checks if the patched welcome string is present. - */ + This is just meant as a demonstration on how to override the scope which includes the + authentik components. This is an extended version of ./minimal-vmtest.nix + + First, a new scope is created from the default one using `overrideScope` on the result + from `mkAuthentikScope`. + Components with overrides in that scope are used by their dependents, i.e. dependents + of `pythonEnv` (e.g. gopkgs) also pull in that overridden `pythonEnv` + Then, that scope is passed to the module via the `services.authentik.authentikComponents` option + And finally, the test script checks if the patched welcome string is present. +*/ let # use a root-owned EnvironmentFile in production instead (services.authentik.environmentFile) @@ -26,22 +27,25 @@ let # creates a new scope using python 3.12 for mkPoetryEnv # and overrides the welcome string for the default oobe intial-setup flow - customScope = (mkAuthentikScope { inherit pkgs; }).overrideScope - (final: prev: { + customScope = (mkAuthentikScope { inherit pkgs; }).overrideScope ( + final: prev: { authentikComponents = prev.authentikComponents // { pythonEnv = prev.authentikComponents.pythonEnv.overrideAttrs (_: { python = pkgs.python312; }); staticWorkdirDeps = prev.authentikComponents.staticWorkdirDeps.overrideAttrs (oA: { - buildCommand = oA.buildCommand + '' - rm -v $out/blueprints - cp -vr ${prev.authentik-src}/blueprints $out/blueprints - substituteInPlace $out/blueprints/default/flow-oobe.yaml \ - --replace "Welcome to authentik" "${customWelcome}" - ''; + buildCommand = + oA.buildCommand + + '' + rm -v $out/blueprints + cp -vr ${prev.authentik-src}/blueprints $out/blueprints + substituteInPlace $out/blueprints/default/flow-oobe.yaml \ + --replace "Welcome to authentik" "${customWelcome}" + ''; }); }; - }); + } + ); in pkgs.nixosTest { name = "authentik"; @@ -117,7 +121,7 @@ pkgs.nixosTest { machine.succeed("su - alice -c 'xdotool key --delay 100 Page_Down' >&2") # sometimes the cursor covers the version string machine.succeed("su - alice -c 'xdotool mousemove_relative 50 50' >&2") - machine.wait_for_text("${builtins.replaceStrings ["."] [".?"] authentik-version}") + machine.wait_for_text("${builtins.replaceStrings [ "." ] [ ".?" ] authentik-version}") machine.screenshot("4_correct_version_in_admin_interface") with subtest("nginx proxies to authentik"):