Release NixOS 23.11
[NixPkgs.git] / nixos / tests / kanidm.nix
blob3f5bca397740efffc2da00dd3438770c2e29197a
1 import ./make-test-python.nix ({ pkgs, ... }:
2   let
3     certs = import ./common/acme/server/snakeoil-certs.nix;
4     serverDomain = certs.domain;
6     testCredentials = {
7       password = "Password1_cZPEwpCWvrReripJmAZdmVIZd8HHoHcl";
8     };
9   in
10   {
11     name = "kanidm";
12     meta.maintainers = with pkgs.lib.maintainers; [ erictapen Flakebi ];
14     nodes.server = { config, pkgs, lib, ... }: {
15       services.kanidm = {
16         enableServer = true;
17         serverSettings = {
18           origin = "https://${serverDomain}";
19           domain = serverDomain;
20           bindaddress = "[::]:443";
21           ldapbindaddress = "[::1]:636";
22           tls_chain = certs."${serverDomain}".cert;
23           tls_key = certs."${serverDomain}".key;
24         };
25       };
27       security.pki.certificateFiles = [ certs.ca.cert ];
29       networking.hosts."::1" = [ serverDomain ];
30       networking.firewall.allowedTCPPorts = [ 443 ];
32       users.users.kanidm.shell = pkgs.bashInteractive;
34       environment.systemPackages = with pkgs; [ kanidm openldap ripgrep ];
35     };
37     nodes.client = { pkgs, nodes, ... }: {
38       services.kanidm = {
39         enableClient = true;
40         clientSettings = {
41           uri = "https://${serverDomain}";
42           verify_ca = true;
43           verify_hostnames = true;
44         };
45         enablePam = true;
46         unixSettings = {
47           pam_allowed_login_groups = [ "shell" ];
48         };
49       };
51       networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ serverDomain ];
53       security.pki.certificateFiles = [ certs.ca.cert ];
54     };
56     testScript = { nodes, ... }:
57       let
58         ldapBaseDN = builtins.concatStringsSep "," (map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain));
60         # We need access to the config file in the test script.
61         filteredConfig = pkgs.lib.converge
62           (pkgs.lib.filterAttrsRecursive (_: v: v != null))
63           nodes.server.services.kanidm.serverSettings;
64         serverConfigFile = (pkgs.formats.toml { }).generate "server.toml" filteredConfig;
66       in
67       ''
68         start_all()
69         server.wait_for_unit("kanidm.service")
70         client.wait_for_unit("network-online.target")
72         with subtest("Test HTTP interface"):
73             server.wait_until_succeeds("curl -Lsf https://${serverDomain} | grep Kanidm")
75         with subtest("Test LDAP interface"):
76             server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'")
78         with subtest("Test CLI login"):
79             client.succeed("kanidm login -D anonymous")
80             client.succeed("kanidm self whoami | grep anonymous@${serverDomain}")
81             client.succeed("kanidm logout")
83         with subtest("Recover idm_admin account"):
84             idm_admin_password = server.succeed("su - kanidm -c 'kanidmd recover-account -c ${serverConfigFile} idm_admin 2>&1 | rg -o \'[A-Za-z0-9]{48}\' '").strip().removeprefix("'").removesuffix("'")
86         with subtest("Test unixd connection"):
87             client.wait_for_unit("kanidm-unixd.service")
88             client.wait_for_file("/run/kanidm-unixd/sock")
89             client.wait_until_succeeds("kanidm-unix status | grep working!")
91         with subtest("Test user creation"):
92             client.wait_for_unit("getty@tty1.service")
93             client.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
94             client.wait_until_tty_matches("1", "login: ")
95             client.send_chars("root\n")
96             client.send_chars("kanidm login -D idm_admin\n")
97             client.wait_until_tty_matches("1", "Enter password: ")
98             client.send_chars(f"{idm_admin_password}\n")
99             client.wait_until_tty_matches("1", "Login Success for idm_admin")
100             client.succeed("kanidm person create testuser TestUser")
101             client.succeed("kanidm person posix set --shell \"$SHELL\" testuser")
102             client.send_chars("kanidm person posix set-password testuser\n")
103             client.wait_until_tty_matches("1", "Enter new")
104             client.send_chars("${testCredentials.password}\n")
105             client.wait_until_tty_matches("1", "Retype")
106             client.send_chars("${testCredentials.password}\n")
107             output = client.succeed("getent passwd testuser")
108             assert "TestUser" in output
109             client.succeed("kanidm group create shell")
110             client.succeed("kanidm group posix set shell")
111             client.succeed("kanidm group add-members shell testuser")
113         with subtest("Test user login"):
114             client.send_key("alt-f2")
115             client.wait_until_succeeds("[ $(fgconsole) = 2 ]")
116             client.wait_for_unit("getty@tty2.service")
117             client.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
118             client.wait_until_tty_matches("2", "login: ")
119             client.send_chars("testuser\n")
120             client.wait_until_tty_matches("2", "login: testuser")
121             client.wait_until_succeeds("pgrep login")
122             client.wait_until_tty_matches("2", "Password: ")
123             client.send_chars("${testCredentials.password}\n")
124             client.wait_until_succeeds("systemctl is-active user@$(id -u testuser).service")
125             client.send_chars("touch done\n")
126             client.wait_for_file("/home/testuser@${serverDomain}/done")
127       '';
128   })