This commit is contained in:
ibizaman 2025-01-22 21:11:17 +01:00
parent 3213f119d2
commit 6ad0a926f2
2 changed files with 123 additions and 3 deletions

View file

@ -1,5 +1,8 @@
{ lib }: { lib }:
let let
inherit (lib) listOf mkOption submodule;
inherit (lib.types) str;
baseImports = pkgs: [ baseImports = pkgs: [
(pkgs.path + "/nixos/modules/profiles/headless.nix") (pkgs.path + "/nixos/modules/profiles/headless.nix")
(pkgs.path + "/nixos/modules/profiles/qemu-guest.nix") (pkgs.path + "/nixos/modules/profiles/qemu-guest.nix")
@ -85,6 +88,11 @@ let
raise Exception(f"auth host should be auth.${domain} but is {response['auth_host']}") raise Exception(f"auth host should be auth.${domain} but is {response['auth_host']}")
if response['auth_query'] != "rd=${proto_fqdn}/": if response['auth_query'] != "rd=${proto_fqdn}/":
raise Exception(f"auth query should be rd=${proto_fqdn}/ but is {response['auth_query']}") raise Exception(f"auth query should be rd=${proto_fqdn}/ but is {response['auth_query']}")
with subtest("Login"):
print(client.execute("cat /etc/hosts"))
print(client.execute("curl https://${subdomain}.${domain}"))
client.succeed("login_playwright firefox")
'' ''
) )
+ (let + (let
@ -102,6 +110,100 @@ let
server.succeed("systemctl start restic-backups-testinstance_opt_repos_A") server.succeed("systemctl start restic-backups-testinstance_opt_repos_A")
''; '';
}; };
clientLoginModule = { config, pkgs, ... }: let
cfg = config.test.login;
in {
options.test.login = {
domain = mkOption {
type = str;
default = "example.com";
};
subdomain = mkOption {
type = str;
};
usernameFieldLabel = mkOption {
type = str;
default = "username";
};
passwordFieldLabel = mkOption {
type = str;
default = "password";
};
loginButtonName = mkOption {
type = str;
default = "login";
};
testLoginWith = mkOption {
type = listOf (submodule {
options = {
username = mkOption {
type = str;
};
password = mkOption {
type = str;
};
};
});
};
startUrl = mkOption {
type = str;
};
};
config = {
networking.hosts = {
"192.168.1.2" = [ "${cfg.subdomain}.${cfg.domain}" ];
};
environment.variables = {
PLAYWRIGHT_BROWSERS_PATH = pkgs.playwright-driver.browsers;
};
environment.systemPackages = [
(pkgs.writers.writePython3Bin "login_playwright"
{
libraries = [ pkgs.python3Packages.playwright ];
}
''
import re
import sys
from playwright.sync_api import sync_playwright
from playwright.sync_api import expect
browsers = {
"chromium": ["--headless", "--disable-gpu"],
"firefox": [],
"webkit": []
}
if len(sys.argv) != 2 or sys.argv[1] not in browsers.keys():
print(f"usage: {sys.argv[0]} [{'|'.join(browsers.keys())}] <url>")
sys.exit(1)
browser_name = sys.argv[1]
browser_args = browsers.get(browser_name)
print(f"Running test on {browser_name} {' '.join(browser_args)}")
with sync_playwright() as p:
browser = getattr(p, browser_name).launch(args=browser_args)
context = browser.new_context(ignore_https_errors=True)
context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = context.new_page()
page.goto(${cfg.startUrl})
try:
expect(page).to_have_title(re.compile("Login - Authelia"))
expect(page.get_by_text("Powered by Authelia")).to_be_visible()
except Exception:
page.screenshot(path="example.png")
page.get_by_label("${cfg.username}").fill("")
page.get_by_label("${cfg.password}").fill("")
context.tracing.stop(path = "trace.zip")
browser.close()
''
)
];
};
};
in in
{ {
inherit baseImports accessScript; inherit baseImports accessScript;
@ -116,7 +218,6 @@ in
imports = imports =
( baseImports pkgs ) ( baseImports pkgs )
++ [ ++ [
# TODO: replace postgresql.nix and authelia.nix by the sso contract
../modules/blocks/postgresql.nix ../modules/blocks/postgresql.nix
../modules/blocks/authelia.nix ../modules/blocks/authelia.nix
../modules/blocks/nginx.nix ../modules/blocks/nginx.nix
@ -124,10 +225,12 @@ in
] ]
++ additionalModules; ++ additionalModules;
# Nginx port. # HTTP(s) server ports.
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];
}; };
inherit clientLoginModule;
backup = backupOption: { config, ... }: { backup = backupOption: { config, ... }: {
imports = [ imports = [
../modules/blocks/restic.nix ../modules/blocks/restic.nix

View file

@ -85,7 +85,24 @@ in
]; ];
}; };
nodes.client = {}; nodes.client = {
imports = [
testLib.clientLoginModule
];
test.login = {
inherit domain subdomain;
usernameFieldLabel = "Username";
passwordFieldLabel = "Password";
loginButtonName = "Login";
testLoginWith = [
{
username = "admin";
password = "adminpw";
}
];
};
};
testScript = commonTestScript.access; testScript = commonTestScript.access;
}; };