1import ./make-test-python.nix (
2 { pkgs, ... }:
3 let
4 certs = import ./common/acme/server/snakeoil-certs.nix;
5 serverDomain = certs.domain;
6
7 testCredentials = {
8 password = "Password1_cZPEwpCWvrReripJmAZdmVIZd8HHoHcl";
9 };
10
11 # copy certs to store to work around mount namespacing
12 certsPath = pkgs.runCommandNoCC "snakeoil-certs" { } ''
13 mkdir $out
14 cp ${certs."${serverDomain}".cert} $out/snakeoil.crt
15 cp ${certs."${serverDomain}".key} $out/snakeoil.key
16 '';
17 in
18 {
19 name = "kanidm";
20 meta.maintainers = with pkgs.lib.maintainers; [
21 Flakebi
22 oddlama
23 ];
24
25 nodes.server =
26 { pkgs, ... }:
27 {
28 services.kanidm = {
29 enableServer = true;
30 serverSettings = {
31 origin = "https://${serverDomain}";
32 domain = serverDomain;
33 bindaddress = "[::]:443";
34 ldapbindaddress = "[::1]:636";
35 tls_chain = "${certsPath}/snakeoil.crt";
36 tls_key = "${certsPath}/snakeoil.key";
37 };
38 };
39
40 security.pki.certificateFiles = [ certs.ca.cert ];
41
42 networking.hosts."::1" = [ serverDomain ];
43 networking.firewall.allowedTCPPorts = [ 443 ];
44
45 users.users.kanidm.shell = pkgs.bashInteractive;
46
47 environment.systemPackages = with pkgs; [
48 kanidm
49 openldap
50 ripgrep
51 ];
52 };
53
54 nodes.client =
55 { nodes, ... }:
56 {
57 services.kanidm = {
58 enableClient = true;
59 clientSettings = {
60 uri = "https://${serverDomain}";
61 verify_ca = true;
62 verify_hostnames = true;
63 };
64 enablePam = true;
65 unixSettings = {
66 pam_allowed_login_groups = [ "shell" ];
67 };
68 };
69
70 networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ serverDomain ];
71
72 security.pki.certificateFiles = [ certs.ca.cert ];
73 };
74
75 testScript =
76 { nodes, ... }:
77 let
78 ldapBaseDN = builtins.concatStringsSep "," (
79 map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain)
80 );
81
82 # We need access to the config file in the test script.
83 filteredConfig = pkgs.lib.converge (pkgs.lib.filterAttrsRecursive (
84 _: v: v != null
85 )) nodes.server.services.kanidm.serverSettings;
86 serverConfigFile = (pkgs.formats.toml { }).generate "server.toml" filteredConfig;
87 in
88 ''
89 server.start()
90 client.start()
91 server.wait_for_unit("kanidm.service")
92 client.systemctl("start network-online.target")
93 client.wait_for_unit("network-online.target")
94
95 with subtest("Test HTTP interface"):
96 server.wait_until_succeeds("curl -Lsf https://${serverDomain} | grep Kanidm")
97
98 with subtest("Test LDAP interface"):
99 server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'")
100
101 with subtest("Recover idm_admin account"):
102 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("'")
103
104 with subtest("Test CLI login"):
105 client.wait_until_tty_matches("1", "login: ")
106 client.send_chars("root\n")
107 client.send_chars("kanidm login -D idm_admin\n")
108 client.wait_until_tty_matches("1", "Enter password: ")
109 client.send_chars(f"{idm_admin_password}\n")
110 client.wait_until_tty_matches("1", "Login Success for idm_admin")
111
112 with subtest("Test unixd connection"):
113 client.wait_for_unit("kanidm-unixd.service")
114 client.wait_for_file("/run/kanidm-unixd/sock")
115 client.wait_until_succeeds("kanidm-unix status | grep online")
116
117 with subtest("Test user creation"):
118 client.wait_for_unit("getty@tty1.service")
119 client.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
120 client.succeed("kanidm person create testuser TestUser")
121 client.succeed("kanidm person posix set --shell \"$SHELL\" testuser")
122 client.send_chars("kanidm person posix set-password testuser\n")
123 client.wait_until_tty_matches("1", "Enter new")
124 client.send_chars("${testCredentials.password}\n")
125 client.wait_until_tty_matches("1", "Reenter")
126 client.send_chars("${testCredentials.password}\n")
127 output = client.succeed("getent passwd testuser")
128 assert "TestUser" in output
129 client.succeed("kanidm group create shell")
130 client.succeed("kanidm group posix set shell")
131 client.succeed("kanidm group add-members shell testuser")
132
133 with subtest("Test user login"):
134 client.send_key("alt-f2")
135 client.wait_until_succeeds("[ $(fgconsole) = 2 ]")
136 client.wait_for_unit("getty@tty2.service")
137 client.wait_until_succeeds("pgrep -f 'agetty.*tty2'")
138 client.wait_until_tty_matches("2", "login: ")
139 client.send_chars("testuser\n")
140 client.wait_until_tty_matches("2", "login: testuser")
141 client.wait_until_succeeds("pgrep login")
142 client.wait_until_tty_matches("2", "Password: ")
143 client.send_chars("${testCredentials.password}\n")
144 client.wait_until_succeeds("systemctl is-active user@$(id -u testuser).service")
145 client.send_chars("touch done\n")
146 client.wait_for_file("/home/testuser@${serverDomain}/done")
147
148 server.shutdown()
149 client.shutdown()
150 '';
151 }
152)