diff --git a/modules/services/deluge.nix b/modules/services/deluge.nix index e0d3832..cc24b2c 100644 --- a/modules/services/deluge.nix +++ b/modules/services/deluge.nix @@ -203,6 +203,28 @@ in type = lib.types.listOf lib.types.path; description = "Location of additional plugins. Each item in the list must be the path to the directory containing the plugin .egg file."; default = []; + example = lib.literalExpression '' + additionalPlugins = [ + (pkgs.callPackage ({ python3, fetchFromGitHub }: python3.pkgs.buildPythonPackage { + name = "deluge-autotracker"; + version = "1.0.0"; + src = fetchFromGitHub { + owner = "ibizaman"; + repo = "deluge-autotracker"; + rev = "cc40d816a497bbf1c2ebeb3d8b1176210548a3e6"; + sha256 = "sha256-0LpVdv1fak2a5eX4unjhUcN7nMAl9fgpr3X+7XnQE6c="; + } + "/autotracker"; + doCheck = false; + format = "other"; + nativeBuildInputs = [ python3.pkgs.setuptools ]; + buildPhase = ''' + mkdir "$out" + python3 setup.py install --install-lib "$out" + '''; + doInstallPhase = false; + }) {}) + ]; + ''; }; logLevel = lib.mkOption { @@ -236,11 +258,11 @@ in enabled_plugins = cfg.enabledPlugins ++ lib.optional (lib.any (x: x.enable) [ - config.shb.arr.radarr - config.shb.arr.sonarr - config.shb.arr.bazarr - config.shb.arr.readarr - config.shb.arr.lidarr + config.services.radarr + config.services.sonarr + config.services.bazarr + config.services.readarr + config.services.lidarr ]) "Label"; inherit (cfg.settings) @@ -301,11 +323,20 @@ in ({ inherit (cfg) subdomain domain ssl; upstream = "http://127.0.0.1:${toString config.services.deluge.web.port}"; - autheliaRules = lib.mkIf (cfg.authEndpoint != null) [{ - domain = fqdn; - policy = "two_factor"; - subject = ["group:deluge_user"]; - }]; + autheliaRules = lib.mkIf (cfg.authEndpoint != null) [ + { + domain = fqdn; + policy = "bypass"; + resources = [ + "^/json" + ]; + } + { + domain = fqdn; + policy = "two_factor"; + subject = ["group:deluge_user"]; + } + ]; } // (lib.optionalAttrs (cfg.authEndpoint != null) { inherit (cfg) authEndpoint; })) diff --git a/test/common.nix b/test/common.nix index a6209fa..1eff79b 100644 --- a/test/common.nix +++ b/test/common.nix @@ -3,14 +3,17 @@ }: { accessScript = { - fqdn + subdomain + , domain , hasSSL , waitForServices ? s: [] , waitForPorts ? p: [] , waitForUnixSocket ? u: [] , extraScript ? {...}: "" + , redirectSSO ? false }: { nodes, ... }: let + fqdn = "${subdomain}.${domain}"; proto_fqdn = if hasSSL args then "https://${fqdn}" else "http://${fqdn}"; args = { @@ -26,8 +29,14 @@ start_all() '' - + lib.strings.concatMapStrings (s: ''server.wait_for_unit("${s}")'' + "\n") (waitForServices args) - + lib.strings.concatMapStrings (p: ''server.wait_for_open_port(${toString p})'' + "\n") (waitForPorts args) + + lib.strings.concatMapStrings (s: ''server.wait_for_unit("${s}")'' + "\n") ( + waitForServices args + ++ (lib.optionals redirectSSO [ "authelia-auth.${domain}.service" ]) + ) + + lib.strings.concatMapStrings (p: ''server.wait_for_open_port(${toString p})'' + "\n") ( + waitForPorts args + ++ (lib.optionals redirectSSO [ nodes.server.services.authelia.instances."auth.${domain}".settings.server.port ] ) + ) + lib.strings.concatMapStrings (u: ''server.wait_for_open_unix_socket("${u}")'' + "\n") (waitForUnixSocket args) + '' if ${if hasSSL args then "True" else "False"}: @@ -35,21 +44,139 @@ client.succeed("rm -r /etc/ssl/certs") client.copy_from_host(str(pathlib.Path(os.environ.get("out", os.getcwd())) / "ca-certificates.crt"), "/etc/ssl/certs/ca-certificates.crt") - def curl(target, format, endpoint, succeed=True): - return json.loads(target.succeed( - "curl --fail-with-body --silent --show-error --output /dev/null --location" - + " --cookie-jar /tmp/cookies" + def curl(target, format, endpoint, data="", extra=""): + data = ' '.join(data.replace("\n", "").split()) + extra = ' '.join(extra.replace("\n", "").split()) + c = target.succeed( + "curl --show-error --location" + + " --cookie-jar cookie.txt" + + " --cookie cookie.txt" + " --connect-to ${fqdn}:443:server:443" + " --connect-to ${fqdn}:80:server:80" - + f" --write-out '{format}'" - + " " + endpoint - )) + # Client must be able to resolve talking to auth server + + " --connect-to auth.${domain}:443:server:443" + + (f" --data '{data}'" if data != "" else "") + + (f" --silent --output /dev/null --write-out '{format}'" if format != "" else "") + + (f" {extra}" if extra != "" else "") + + f" {endpoint}" + ) + # print(c) + return json.loads(c) + '' + + (if (! redirectSSO) then '' with subtest("access"): response = curl(client, """{"code":%{response_code}}""", "${proto_fqdn}") if response['code'] != 200: raise Exception(f"Code is {response['code']}") + '' else '' + with subtest("unauthenticated access is not granted"): + response = curl(client, """{"code":%{response_code},"auth_host":"%{urle.host}","auth_query":"%{urle.query}","all":%{json}}""", "${proto_fqdn}") + + if response['code'] != 200: + raise Exception(f"Code is {response['code']}") + if response['auth_host'] != "auth.${domain}": + raise Exception(f"auth host should be auth.${domain} but is {response['auth_host']}") + if response['auth_query'] != "rd=${proto_fqdn}/": + raise Exception(f"auth query should be rd=${proto_fqdn}/ but is {response['auth_query']}") '' + ) + extraScript args; + + base = pkgs: additionalModules: { + imports = [ + (pkgs.path + "/nixos/modules/profiles/headless.nix") + (pkgs.path + "/nixos/modules/profiles/qemu-guest.nix") + # TODO: replace this option by the backup contract + { + options = { + shb.backup = lib.mkOption { type = lib.types.anything; }; + }; + } + # TODO: replace postgresql.nix and authelia.nix by the sso contract + ../modules/blocks/postgresql.nix + ../modules/blocks/authelia.nix + ../modules/blocks/nginx.nix + ] ++ additionalModules; + + # Nginx port. + networking.firewall.allowedTCPPorts = [ 80 443 ]; + }; + + certs = domain: { config, ... }: { + imports = [ + ../modules/blocks/ssl.nix + ]; + + shb.certs = { + cas.selfsigned.myca = { + name = "My CA"; + }; + certs.selfsigned = { + n = { + ca = config.shb.certs.cas.selfsigned.myca; + domain = "*.${domain}"; + group = "nginx"; + }; + }; + }; + + systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; + systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; + }; + + ldap = domain: pkgs: { + imports = [ + ../modules/blocks/ldap.nix + ]; + + networking.hosts = { + "127.0.0.1" = [ "ldap.${domain}" ]; + }; + + shb.ldap = { + enable = true; + inherit domain; + subdomain = "ldap"; + ldapPort = 3890; + webUIListenPort = 17170; + dcdomain = "dc=example,dc=com"; + ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; + jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; + }; + }; + + sso = domain: pkgs: ssl: { config, ... }: { + imports = [ + ../modules/blocks/authelia.nix + ]; + + networking.hosts = { + "127.0.0.1" = [ "auth.${domain}" ]; + }; + + shb.authelia = { + enable = true; + inherit domain; + subdomain = "auth"; + ssl = config.shb.certs.certs.selfsigned.n; + + ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; + dcdomain = config.shb.ldap.dcdomain; + + secrets = { + jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; + ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; + sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; + storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; + identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; + identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' + mkdir $out + ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 + '') + "/private.pem"; + }; + }; + }; + } diff --git a/test/vm/arr.nix b/test/vm/arr.nix index b0f843b..a3ffffc 100644 --- a/test/vm/arr.nix +++ b/test/vm/arr.nix @@ -11,9 +11,10 @@ let # TODO: Test login commonTestScript = appname: cfgPathFn: let - fqdn = "${appname}.${domain}"; + subdomain = appname; + fqdn = "${subdomain}.${domain}"; in testLib.accessScript { - inherit fqdn; + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.arr.${appname}.ssl); waitForServices = { ... }: [ "${appname}.service" @@ -47,45 +48,81 @@ let ''; }; - basic = appname: cfgPathFn: pkgs.testers.runNixOSTest { + base = testLib.base pkgs' [ + ../../modules/services/arr.nix + ]; + + basic = appname: { ... }: { + shb.arr.${appname} = { + enable = true; + inherit domain; + subdomain = appname; + + settings.ApiKey.source = pkgs.writeText "APIKey" "01234567890123456789"; # Needs to be >=20 characters. + }; + }; + + basicTest = appname: cfgPathFn: pkgs.testers.runNixOSTest { name = "arr-${appname}-basic"; nodes.server = { config, pkgs, ... }: { imports = [ - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/authelia.nix - ../../modules/blocks/postgresql.nix - ../../modules/blocks/nginx.nix - ../../modules/services/arr.nix - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") + base + (basic appname) ]; - - shb.arr.${appname} = { - enable = true; - inherit domain; - subdomain = appname; - - settings.ApiKey.source = pkgs.writeText "APIKey" "01234567890123456789"; # Needs to be >=20 characters. - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; }; nodes.client = {}; testScript = commonTestScript appname cfgPathFn; }; + + https = appname: { config, ...}: { + shb.arr.${appname} = { + ssl = config.shb.certs.certs.selfsigned.n; + }; + }; + + httpsTest = appname: cfgPathFn: pkgs.testers.runNixOSTest { + name = "arr-${appname}-https"; + + nodes.server = { config, pkgs, ... }: { + imports = [ + base + (basic appname) + (testLib.certs domain) + (https appname) + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript appname cfgPathFn; + }; + + radarrCfgFn = cfg: "${cfg.dataDir}/config.xml"; + sonarrCfgFn = cfg: "${cfg.dataDir}/config.xml"; + bazarrCfgFn = cfg: "/var/lib/bazarr/config.xml"; + readarrCfgFn = cfg: "${cfg.dataDir}/config.xml"; + lidarrCfgFn = cfg: "${cfg.dataDir}/config.xml"; + jackettCfgFn = cfg: "${cfg.dataDir}/ServerConfig.json"; in { - radarr_basic = basic "radarr" (cfg: "${cfg.dataDir}/config.xml"); - sonarr_basic = basic "sonarr" (cfg: "${cfg.dataDir}/config.xml"); - bazarr_basic = basic "bazarr" (cfg: "/var/lib/bazarr/config.xml"); - readarr_basic = basic "readarr" (cfg: "${cfg.dataDir}/config.xml"); - lidarr_basic = basic "lidarr" (cfg: "${cfg.dataDir}/config.xml"); - jackett_basic = basic "jackett" (cfg: "${cfg.dataDir}/ServerConfig.json"); + radarr_basic = basicTest "radarr" radarrCfgFn; + radarr_https = httpsTest "radarr" radarrCfgFn; + + sonarr_basic = basicTest "sonarr" sonarrCfgFn; + sonarr_https = httpsTest "sonarr" sonarrCfgFn; + + bazarr_basic = basicTest "bazarr" bazarrCfgFn; + bazarr_https = httpsTest "bazarr" bazarrCfgFn; + + readarr_basic = basicTest "readarr" readarrCfgFn; + readarr_https = httpsTest "readarr" readarrCfgFn; + + lidarr_basic = basicTest "lidarr" lidarrCfgFn; + lidarr_https = httpsTest "lidarr" lidarrCfgFn; + + jackett_basic = basicTest "jackett" jackettCfgFn; + jackett_https = httpsTest "jackett" jackettCfgFn; } diff --git a/test/vm/audiobookshelf.nix b/test/vm/audiobookshelf.nix index 9b15941..65755b0 100644 --- a/test/vm/audiobookshelf.nix +++ b/test/vm/audiobookshelf.nix @@ -9,7 +9,7 @@ let fqdn = "${subdomain}.${domain}"; commonTestScript = testLib.accessScript { - inherit fqdn; + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.audiobookshelf.ssl); waitForServices = { ... }: [ "audiobookshelf.service" @@ -23,43 +23,9 @@ let # ''; }; - base = { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/audiobookshelf.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - }; - - certs = { config, ... }: { - imports = [ - ../../modules/blocks/ssl.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/audiobookshelf.nix + ]; basic = { shb.audiobookshelf = { @@ -75,45 +41,6 @@ let }; sso = { config, ... }: { - imports = [ - ../../modules/blocks/authelia.nix - ../../modules/blocks/ldap.nix - ../../modules/blocks/postgresql.nix - ]; - - shb.ldap = { - enable = true; - inherit domain; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - shb.authelia = { - enable = true; - inherit domain; - subdomain = "auth"; - ssl = config.shb.certs.certs.selfsigned.n; - - ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; - dcdomain = config.shb.ldap.dcdomain; - - secrets = { - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - mkdir $out - ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - '') + "/private.pem"; - }; - }; - shb.audiobookshelf = { authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; ssoSecretFile = pkgs.writeText "ssoSecretFile" "ssoSecretFile"; @@ -124,15 +51,12 @@ in basic = pkgs.testers.runNixOSTest { name = "audiobookshelf-basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; nodes.client = {}; @@ -144,14 +68,9 @@ in nodes.server = lib.mkMerge [ base - certs + (testLib.certs domain) basic https - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } ]; nodes.client = {}; @@ -162,13 +81,17 @@ in sso = pkgs.testers.runNixOSTest { name = "audiobookshelf-sso"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - sso - ]; + nodes.server = { config, ... }: { + imports = [ + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) + sso + ]; + }; nodes.client = {}; diff --git a/test/vm/deluge.nix b/test/vm/deluge.nix index f5ebc01..7bcffa6 100644 --- a/test/vm/deluge.nix +++ b/test/vm/deluge.nix @@ -4,12 +4,11 @@ let subdomain = "d"; domain = "example.com"; - fqdn = "${subdomain}.${domain}"; testLib = pkgs.callPackage ../common.nix {}; - commonTestScript = testLib.accessScript { - inherit fqdn; + commonTestScript = lib.makeOverridable testLib.accessScript { + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.deluge.ssl); waitForServices = { ... }: [ "nginx.service" @@ -20,68 +19,50 @@ let node.config.shb.deluge.daemonPort node.config.shb.deluge.webPort ]; - extraScript = { node, ... }: '' + extraScript = { node, proto_fqdn, ... }: '' print(${node.name}.succeed('journalctl -n100 -u deluged')) print(${node.name}.succeed('systemctl status deluged')) print(${node.name}.succeed('systemctl status delugeweb')) - ''; - }; - # TODO: Test login directly to deluge daemon to exercise extraUsers - authTestScript = { nodes, ... }: - let - hasSSL = !(isNull nodes.server.shb.deluge.ssl); - proto_fqdn = if hasSSL then "https://${fqdn}" else "http://${fqdn}"; - delugeCurlCfg = pkgs.writeText "curl.cfg" '' - request = "POST" - compressed - cookie = "cookie_deluge.txt" - cookie-jar = "cookie_deluge.txt" - header = "Content-Type: application/json" - header = "Accept: application/json" - url = "${proto_fqdn}/json" - write-out = "\n" - ''; - in - '' with subtest("web connect"): - print(server.succeed("cat ${nodes.server.services.deluge.dataDir}/.config/deluge/auth")) + print(server.succeed("cat ${node.config.services.deluge.dataDir}/.config/deluge/auth")) - response = json.loads(client.succeed( - "curl --fail-with-body --show-error -K ${delugeCurlCfg}" - + " --connect-to ${fqdn}:443:server:443" - + " --connect-to ${fqdn}:80:server:80" - + """ --data '{"method": "auth.login", "params": ["deluge"], "id": 1}'""" - )) + response = curl(client, "", "${proto_fqdn}/json", extra = """ + -H "Content-Type: application/json" + -H "Accept: application/json" + """, data = """ + {"method": "auth.login", "params": ["deluge"], "id": 1} + """) print(response) + if response['error']: + raise Exception(f"error is {response['error']}") if not response['result']: - raise Exception(f"result is {response['code']}") + raise Exception(f"response is {response}") - response = json.loads(client.succeed( - "curl --fail-with-body --show-error -K ${delugeCurlCfg}" - + " --connect-to ${fqdn}:443:server:443" - + " --connect-to ${fqdn}:80:server:80" - + """ --data '{"method": "web.get_hosts", "params": [], "id": 1}'""" - )) + response = curl(client, "", "${proto_fqdn}/json", extra = """ + -H "Content-Type: application/json" + -H "Accept: application/json" + """, data = """ + {"method": "web.get_hosts", "params": [], "id": 1} + """) print(response) + if response['error']: + raise Exception(f"error is {response['error']}") hostID = response['result'][0][0] - response = json.loads(client.succeed( - "curl --fail-with-body --show-error -K ${delugeCurlCfg}" - + " --connect-to ${fqdn}:443:server:443" - + " --connect-to ${fqdn}:80:server:80" - + f""" --data '{{"method": "web.connect", "params": ["{hostID}"], "id": 1}}'""" - )) + response = curl(client, "", "${proto_fqdn}/json", extra = """ + -H "Content-Type: application/json" + -H "Accept: application/json" + """, data = f""" + {{"method": "web.connect", "params": ["{hostID}"], "id": 1}} + """) print(response) if response['error']: raise Exception(f"result had an error {response['error']}") ''; + }; prometheusTestScript = { nodes, ... }: - let - hasSSL = !(isNull nodes.server.shb.deluge.ssl); - proto_fqdn = if hasSSL then "https://${fqdn}" else "http://${fqdn}"; - in '' server.wait_for_open_port(${toString nodes.server.services.prometheus.exporters.deluge.port}) with subtest("prometheus"): @@ -92,54 +73,11 @@ let print(response) ''; - base = { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.arr.radarr.enable = lib.mkEnableOption "radarr"; - shb.arr.sonarr.enable = lib.mkEnableOption "sonarr"; - shb.arr.bazarr.enable = lib.mkEnableOption "bazarr"; - shb.arr.readarr.enable = lib.mkEnableOption "readarr"; - shb.arr.lidarr.enable = lib.mkEnableOption "lidarr"; - }; - } - ../../modules/blocks/nginx.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - }; - - certs = { config, ... }: { - imports = [ - ../../modules/blocks/ssl.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/deluge.nix + ]; basic = { config, ... }: { - imports = [ - ../../modules/services/deluge.nix - ]; - shb.deluge = { enable = true; inherit domain subdomain; @@ -168,59 +106,7 @@ let }; }; - ldap = { config, ... }: { - imports = [ - ../../modules/blocks/ldap.nix - ]; - - shb.ldap = { - enable = true; - inherit domain; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - networking.hosts = { - "127.0.0.1" = [ "${config.shb.ldap.subdomain}.${domain}" ]; - }; - }; - sso = { config, ... }: { - imports = [ - ../../modules/blocks/authelia.nix - ../../modules/blocks/postgresql.nix - ]; - - shb.authelia = { - enable = true; - inherit domain; - subdomain = "auth"; - ssl = config.shb.certs.certs.selfsigned.n; - - ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; - dcdomain = config.shb.ldap.dcdomain; - - secrets = { - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - mkdir $out - ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - '') + "/private.pem"; - }; - }; - - networking.hosts = { - "127.0.0.1" = [ "${config.shb.authelia.subdomain}.${domain}" ]; - }; - shb.deluge = { authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; }; @@ -230,79 +116,69 @@ in basic = pkgs.testers.runNixOSTest { name = "deluge_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; nodes.client = {}; - testScript = inputs: - (commonTestScript inputs) - + (authTestScript inputs); + testScript = commonTestScript; }; https = pkgs.testers.runNixOSTest { name = "deluge_https"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; - testScript = inputs: - (commonTestScript inputs) - + (authTestScript inputs); + testScript = commonTestScript; }; - # TODO: make this work, needs to authenticate to Authelia - # - # sso = pkgs.testers.runNixOSTest { - # name = "deluge_sso"; - # - # nodes.server = lib.mkMerge [ - # base - # basic - # certs - # https - # ldap - # sso - # ]; - # - # nodes.client = {}; - # - # testScript = commonTestScript; - # }; + sso = pkgs.testers.runNixOSTest { + name = "deluge_sso"; + + nodes.server = { config, ... }: { + imports = [ + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) + sso + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript.override { + redirectSSO = true; + }; + }; prometheus = pkgs.testers.runNixOSTest { name = "deluge_https"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - prometheus - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + prometheus + ]; + }; nodes.client = {}; diff --git a/test/vm/grocy.nix b/test/vm/grocy.nix index d01c6f5..a51fc98 100644 --- a/test/vm/grocy.nix +++ b/test/vm/grocy.nix @@ -8,8 +8,8 @@ let domain = "example.com"; fqdn = "${subdomain}.${domain}"; - commonTestScript = testLib.accessScript { - inherit fqdn; + commonTestScript = lib.makeOverridable testLib.accessScript { + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.grocy.ssl); waitForServices = { ... }: [ "phpfpm-grocy.service" @@ -23,43 +23,9 @@ let # ''; }; - base = { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/grocy.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - }; - - certs = { config, ... }: { - imports = [ - ../../modules/blocks/ssl.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/grocy.nix + ]; basic = { config, ... }: { shb.grocy = { @@ -76,17 +42,14 @@ let in { basic = pkgs.testers.runNixOSTest { - name = "grocy-basic"; + name = "grocy_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; nodes.client = {}; @@ -94,19 +57,16 @@ in }; https = pkgs.testers.runNixOSTest { - name = "grocy-https"; + name = "grocy_https"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; diff --git a/test/vm/home-assistant.nix b/test/vm/home-assistant.nix index bdaf909..d56df14 100644 --- a/test/vm/home-assistant.nix +++ b/test/vm/home-assistant.nix @@ -6,10 +6,9 @@ let subdomain = "ha"; domain = "example.com"; - fqdn = "${subdomain}.${domain}"; - commonTestScript = testLib.accessScript { - inherit fqdn; + commonTestScript = lib.makeOverridable testLib.accessScript { + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.home-assistant.ssl); waitForServices = { ... }: [ "home-assistant.service" @@ -20,46 +19,14 @@ let ]; }; - base = { config, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/nginx.nix - ../../modules/blocks/postgresql.nix - ../../modules/blocks/ssl.nix - ../../modules/services/home-assistant.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/home-assistant.nix + ]; basic = { config, ... }: { shb.home-assistant = { enable = true; inherit subdomain domain; - ssl = config.shb.certs.certs.selfsigned.n; config = { name = "Tiserbox"; @@ -72,26 +39,13 @@ let }; }; + https = { config, ...}: { + shb.home-assistant = { + ssl = config.shb.certs.certs.selfsigned.n; + }; + }; + ldap = { config, ... }: { - imports = [ - ../../modules/blocks/ldap.nix - ]; - - shb.ldap = { - enable = true; - inherit domain; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - networking.hosts = { - "127.0.0.1" = [ "${config.shb.ldap.subdomain}.${domain}" ]; - }; - shb.home-assistant = { ldap = { enable = true; @@ -105,50 +59,39 @@ let # Not yet supported # # sso = { config, ... }: { - # imports = [ - # ../../modules/blocks/authelia.nix - # ]; - # - # shb.authelia = { - # enable = true; - # inherit domain; - # subdomain = "auth"; - # ssl = config.shb.certs.certs.selfsigned.n; - # - # ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; - # dcdomain = config.shb.ldap.dcdomain; - # - # secrets = { - # jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - # ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - # sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - # storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - # identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - # identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - # mkdir $out - # ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - # '') + "/private.pem"; + # shb.home-assistant = { + # sso = { # }; # }; - # - # networking.hosts = { - # "127.0.0.1" = [ "${config.shb.authelia.subdomain}.${domain}" ]; - # }; # }; in { basic = pkgs.testers.runNixOSTest { - name = "vaultwarden_basic"; + name = "homeassistant_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript; + }; + + https = pkgs.testers.runNixOSTest { + name = "homeassistant_https"; + + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; @@ -156,18 +99,16 @@ in }; ldap = pkgs.testers.runNixOSTest { - name = "vaultwarden_ldap"; + name = "homeassistant_ldap"; - nodes.server = lib.mkMerge [ - base - basic - ldap - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + (testLib.ldap domain pkgs') + ldap + ]; + }; nodes.client = {}; @@ -181,8 +122,12 @@ in # # nodes.server = lib.mkMerge [ # base + # (testLib.certs domain) # basic + # https # ldap + # (testLib.ldap domain pkgs') + # (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) # sso # ]; # diff --git a/test/vm/jellyfin.nix b/test/vm/jellyfin.nix index aadca81..3fd3474 100644 --- a/test/vm/jellyfin.nix +++ b/test/vm/jellyfin.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, ... }: +{ pkgs, ... }: let pkgs' = pkgs; @@ -6,10 +6,9 @@ let subdomain = "j"; domain = "example.com"; - fqdn = "${subdomain}.${domain}"; commonTestScript = testLib.accessScript { - inherit fqdn; + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.jellyfin.ssl); waitForServices = { ... }: [ "jellyfin.service" @@ -19,31 +18,72 @@ let 8096 ]; }; + + base = testLib.base pkgs' [ + ../../modules/services/jellyfin.nix + ]; + + basic = { + shb.jellyfin = { + enable = true; + inherit domain subdomain; + }; + }; + + https = { config, ... }: { + shb.jellyfin = { + ssl = config.shb.certs.certs.selfsigned.n; + }; + }; + + ldap = { config, ... }: { + shb.jellyfin = { + ldap = { + enable = true; + host = "127.0.0.1"; + port = config.shb.ldap.ldapPort; + dcdomain = config.shb.ldap.dcdomain; + passwordFile = config.shb.ldap.ldapUserPasswordFile; + }; + }; + }; + + sso = { config, ... }: { + shb.jellyfin = { + sso = { + enable = true; + endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; + secretFile = pkgs.writeText "ssoSecretFile" "ssoSecretFile"; + }; + }; + }; in { basic = pkgs.testers.runNixOSTest { - name = "jellyfin-basic"; + name = "jellyfin_basic"; - nodes.server = { config, pkgs, ... }: { + nodes.server = { imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/jellyfin.nix + base + basic ]; + }; - shb.jellyfin = { - enable = true; - domain = "example.com"; - subdomain = "j"; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; + nodes.client = {}; + + testScript = commonTestScript; + }; + + https = pkgs.testers.runNixOSTest { + name = "jellyfin_https"; + + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; }; nodes.client = {}; @@ -52,104 +92,19 @@ in }; ldap = pkgs.testers.runNixOSTest { - name = "jellyfin-ldap"; + name = "jellyfin_ldap"; - nodes.server = { config, pkgs, ... }: { + nodes.server = { imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/ldap.nix - ../../modules/services/jellyfin.nix + base + basic + (testLib.ldap domain pkgs') + ldap ]; - - shb.ldap = { - enable = true; - domain = "example.com"; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - shb.jellyfin = { - enable = true; - domain = "example.com"; - subdomain = "j"; - - ldap = { - enable = true; - host = "127.0.0.1"; - port = config.shb.ldap.ldapPort; - dcdomain = config.shb.ldap.dcdomain; - passwordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - }; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 ]; }; - + nodes.client = {}; - - testScript = commonTestScript; - }; - - cert = pkgs.testers.runNixOSTest { - name = "jellyfin_cert"; - - nodes.server = { config, pkgs, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/nginx.nix - ../../modules/blocks/postgresql.nix - ../../modules/blocks/ssl.nix - ../../modules/services/jellyfin.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.example.com"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - - shb.jellyfin = { - enable = true; - domain = "example.com"; - subdomain = "j"; - ssl = config.shb.certs.certs.selfsigned.n; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - shb.nginx.accessLog = true; - }; - - nodes.client = {}; - + testScript = commonTestScript; }; @@ -158,91 +113,14 @@ in nodes.server = { config, pkgs, ... }: { imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/authelia.nix - ../../modules/blocks/ldap.nix - ../../modules/blocks/postgresql.nix - ../../modules/blocks/ssl.nix - ../../modules/services/jellyfin.nix + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) + sso ]; - - shb.ldap = { - enable = true; - domain = "example.com"; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.example.com"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - - shb.authelia = { - enable = true; - domain = "example.com"; - subdomain = "auth"; - ssl = config.shb.certs.certs.selfsigned.n; - - ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; - dcdomain = config.shb.ldap.dcdomain; - - secrets = { - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - mkdir $out - ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - '') + "/private.pem"; - }; - }; - - shb.jellyfin = { - enable = true; - domain = "example.com"; - subdomain = "j"; - ssl = config.shb.certs.certs.selfsigned.n; - - ldap = { - enable = true; - host = "127.0.0.1"; - port = config.shb.ldap.ldapPort; - dcdomain = config.shb.ldap.dcdomain; - passwordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - }; - - sso = { - enable = true; - endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; - secretFile = pkgs.writeText "ssoSecretFile" "ssoSecretFile"; - }; - }; - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; }; nodes.client = {}; diff --git a/test/vm/monitoring.nix b/test/vm/monitoring.nix index eda1946..a349f57 100644 --- a/test/vm/monitoring.nix +++ b/test/vm/monitoring.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, ... }: +{ pkgs, ... }: let pkgs' = pkgs; @@ -6,64 +6,29 @@ let subdomain = "grafana"; domain = "example.com"; - fqdn = "${subdomain}.${domain}"; password = "securepw"; commonTestScript = testLib.accessScript { - inherit fqdn; + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.monitoring.ssl); waitForServices = { ... }: [ - "nginx.service" + "grafana.service" ]; waitForPorts = { node, ... }: [ node.config.shb.monitoring.grafanaPort ]; }; - base = { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/postgresql.nix - ../../modules/blocks/monitoring.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - }; - - certs = { config, ... }: { - imports = [ - ../../modules/blocks/ssl.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/blocks/monitoring.nix + ]; basic = { config, ... }: { shb.monitoring = { enable = true; inherit subdomain domain; + grafanaPort = 3000; adminPasswordFile = pkgs.writeText "admin_password" password; secretKeyFile = pkgs.writeText "secret_key" "secret_key"; @@ -78,17 +43,14 @@ let in { basic = pkgs.testers.runNixOSTest { - name = "monitoring-basic"; + name = "monitoring_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; nodes.client = {}; @@ -96,19 +58,16 @@ in }; https = pkgs.testers.runNixOSTest { - name = "monitoring-https"; + name = "monitoring_https"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; diff --git a/test/vm/nextcloud.nix b/test/vm/nextcloud.nix index 9a0c3f9..b666cd2 100644 --- a/test/vm/nextcloud.nix +++ b/test/vm/nextcloud.nix @@ -10,8 +10,8 @@ let testLib = pkgs.callPackage ../common.nix {}; - commonTestScript = testLib.accessScript { - inherit fqdn; + commonTestScript = lib.makeOverridable testLib.accessScript { + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.nextcloud.ssl); waitForServices = { ... }: [ "phpfpm-nextcloud.service" @@ -114,48 +114,15 @@ let ''; }; - base = { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/services/nextcloud-server.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - }; - - certs = { config, ... }: { - imports = [ - ../../modules/blocks/ssl.nix - ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/nextcloud-server.nix + ]; basic = { config, ... }: { shb.nextcloud = { enable = true; inherit domain subdomain; + dataDir = "/var/lib/nextcloud"; tracing = null; defaultPhoneRegion = "US"; @@ -177,6 +144,40 @@ let }; }; + ldap = { config, ... }: { + shb.nextcloud = { + apps.ldap = { + enable = true; + host = "127.0.0.1"; + port = config.shb.ldap.ldapPort; + dcdomain = config.shb.ldap.dcdomain; + adminName = "admin"; + adminPasswordFile = config.shb.ldap.ldapUserPasswordFile; + userGroup = "nextcloud_user"; + }; + }; + }; + + sso = { config, ... }: + let + authSecret = pkgs.writeText "authSecret" "authSecret"; + in + { + shb.nextcloud = { + apps.sso = { + enable = true; + endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; + clientID = "nextcloud"; + # adminUserGroup = "nextcloud_admin"; + + secretFile = authSecret; + secretFileForAuthelia = authSecret; + + fallbackDefaultAuth = false; + }; + }; + }; + previewgenerator = { config, ...}: { systemd.tmpfiles.rules = [ "d '/srv/nextcloud' 0750 nextcloud nextcloud - -" @@ -203,17 +204,14 @@ let in { basic = pkgs.testers.runNixOSTest { - name = "nextcloud-basic"; + name = "nextcloud_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; nodes.client = {}; @@ -221,19 +219,16 @@ in }; https = pkgs.testers.runNixOSTest { - name = "nextcloud-https"; + name = "nextcloud_https"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; @@ -242,20 +237,17 @@ in }; previewGenerator = pkgs.testers.runNixOSTest { - name = "nextcloud-previewGenerator"; + name = "nextcloud_previewGenerator"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - previewgenerator - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + previewgenerator + ]; + }; nodes.client = {}; @@ -263,23 +255,60 @@ in }; externalStorage = pkgs.testers.runNixOSTest { - name = "nextcloud-externalStorage"; + name = "nextcloud_externalStorage"; - nodes.server = lib.mkMerge [ - base - certs - basic - https - externalstorage - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + externalstorage + ]; + }; nodes.client = {}; testScript = commonTestScript; }; + + ldap = pkgs.testers.runNixOSTest { + name = "nextcloud_ldap"; + + nodes.server = { config, ... }: { + imports = [ + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + ldap + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript; + }; + + sso = pkgs.testers.runNixOSTest { + name = "nextcloud_sso"; + + nodes.server = { config, ... }: { + imports = [ + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + ldap + (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) + sso + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript; + }; } diff --git a/test/vm/vaultwarden.nix b/test/vm/vaultwarden.nix index b294382..4b5df32 100644 --- a/test/vm/vaultwarden.nix +++ b/test/vm/vaultwarden.nix @@ -6,10 +6,9 @@ let subdomain = "v"; domain = "example.com"; - fqdn = "${subdomain}.${domain}"; - commonTestScript = testLib.accessScript { - inherit fqdn; + commonTestScript = lib.makeOverridable testLib.accessScript { + inherit subdomain domain; hasSSL = { node, ... }: !(isNull node.config.shb.vaultwarden.ssl); waitForServices = { ... }: [ "vaultwarden.service" @@ -21,112 +20,38 @@ let ]; }; - base = { config, ... }: { - imports = [ - (pkgs'.path + "/nixos/modules/profiles/headless.nix") - (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") - { - options = { - shb.backup = lib.mkOption { type = lib.types.anything; }; - }; - } - ../../modules/blocks/nginx.nix - ../../modules/blocks/postgresql.nix - ../../modules/blocks/ssl.nix - ../../modules/services/vaultwarden.nix - ]; - - # Nginx port. - networking.firewall.allowedTCPPorts = [ 80 443 ]; - - shb.certs = { - cas.selfsigned.myca = { - name = "My CA"; - }; - certs.selfsigned = { - n = { - ca = config.shb.certs.cas.selfsigned.myca; - domain = "*.${domain}"; - group = "nginx"; - }; - }; - }; - - systemd.services.nginx.after = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - systemd.services.nginx.requires = [ config.shb.certs.certs.selfsigned.n.systemdService ]; - }; + base = testLib.base pkgs' [ + ../../modules/services/vaultwarden.nix + ]; basic = { config, ... }: { shb.vaultwarden = { enable = true; inherit subdomain domain; - ssl = config.shb.certs.certs.selfsigned.n; + port = 8222; databasePasswordFile = pkgs.writeText "pwfile" "DBPASSWORDFILE"; }; - networking.hosts = { - "127.0.0.1" = [ fqdn ]; - }; - }; - - ldap = { config, ... }: { - imports = [ - ../../modules/blocks/ldap.nix - ]; - - shb.ldap = { - enable = true; - inherit domain; - subdomain = "ldap"; - ldapPort = 3890; - webUIListenPort = 17170; - dcdomain = "dc=example,dc=com"; - ldapUserPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - }; - - networking.hosts = { - "127.0.0.1" = [ "${config.shb.ldap.subdomain}.${domain}" ]; - }; - - # Not yet supported - # shb.vaultwarden = { - # ldapEndpoint = "http://127.0.0.1:${builtins.toString config.shb.ldap.webUIListenPort}"; + # networking.hosts = { + # "127.0.0.1" = [ fqdn ]; # }; }; - sso = { config, ... }: { - imports = [ - ../../modules/blocks/authelia.nix - ]; - - shb.authelia = { - enable = true; - inherit domain; - subdomain = "auth"; + https = { config, ... }: { + shb.vaultwarden = { ssl = config.shb.certs.certs.selfsigned.n; - - ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}"; - dcdomain = config.shb.ldap.dcdomain; - - secrets = { - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - mkdir $out - ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - '') + "/private.pem"; - }; }; + }; - networking.hosts = { - "127.0.0.1" = [ "${config.shb.authelia.subdomain}.${domain}" ]; - }; + # Not yet supported + # ldap = { config, ... }: { + # # shb.vaultwarden = { + # # ldapEndpoint = "http://127.0.0.1:${builtins.toString config.shb.ldap.webUIListenPort}"; + # # }; + # }; + sso = { config, ... }: { shb.vaultwarden = { authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; }; @@ -136,15 +61,29 @@ in basic = pkgs.testers.runNixOSTest { name = "vaultwarden_basic"; - nodes.server = lib.mkMerge [ - base - basic - { - options = { - shb.authelia = lib.mkOption { type = lib.types.anything; }; - }; - } - ]; + nodes.server = { + imports = [ + base + basic + ]; + }; + + nodes.client = {}; + + testScript = commonTestScript; + }; + + https = pkgs.testers.runNixOSTest { + name = "vaultwarden_https"; + + nodes.server = { + imports = [ + base + (testLib.certs domain) + basic + https + ]; + }; nodes.client = {}; @@ -170,15 +109,32 @@ in sso = pkgs.testers.runNixOSTest { name = "vaultwarden_sso"; - nodes.server = lib.mkMerge [ - base - basic - ldap - sso - ]; + nodes.server = { config, ... }: { + imports = [ + base + (testLib.certs domain) + basic + https + (testLib.ldap domain pkgs') + (testLib.sso domain pkgs' config.shb.certs.certs.selfsigned.n) + sso + ]; + }; nodes.client = {}; - testScript = commonTestScript; + testScript = commonTestScript.override { + extraScript = { proto_fqdn, ... }: '' + with subtest("unauthenticated access is not granted to /admin"): + response = curl(client, """{"code":%{response_code},"auth_host":"%{urle.host}","auth_query":"%{urle.query}","all":%{json}}""", "${proto_fqdn}/admin") + + if response['code'] != 200: + raise Exception(f"Code is {response['code']}") + if response['auth_host'] != "auth.${domain}": + raise Exception(f"auth host should be auth.${domain} but is {response['auth_host']}") + if response['auth_query'] != "rd=${proto_fqdn}/admin": + raise Exception(f"auth query should be rd=${proto_fqdn}/admin but is {response['auth_query']}") + ''; + }; }; }