1import ./make-test-python.nix (
2 { lib, ... }:
3 {
4 name = "dex-oidc";
5 meta.maintainers = with lib.maintainers; [ Flakebi ];
6
7 nodes.machine =
8 { pkgs, ... }:
9 {
10 environment.systemPackages = with pkgs; [ jq ];
11 services.dex = {
12 enable = true;
13 settings = {
14 issuer = "http://127.0.0.1:8080/dex";
15 storage = {
16 type = "postgres";
17 config.host = "/var/run/postgresql";
18 };
19 web.http = "127.0.0.1:8080";
20 oauth2.skipApprovalScreen = true;
21 staticClients = [
22 {
23 id = "oidcclient";
24 name = "Client";
25 redirectURIs = [ "https://example.com/callback" ];
26 secretFile = "/etc/dex/oidcclient";
27 }
28 ];
29 connectors = [
30 {
31 type = "mockPassword";
32 id = "mock";
33 name = "Example";
34 config = {
35 username = "admin";
36 password = "password";
37 };
38 }
39 ];
40 };
41 };
42
43 # This should not be set from nix but through other means to not leak the secret.
44 environment.etc."dex/oidcclient" = {
45 mode = "0400";
46 user = "dex";
47 text = "oidcclientsecret";
48 };
49
50 services.postgresql = {
51 enable = true;
52 ensureDatabases = [ "dex" ];
53 ensureUsers = [
54 {
55 name = "dex";
56 ensureDBOwnership = true;
57 }
58 ];
59 };
60 };
61
62 testScript = ''
63 with subtest("Web server gets ready"):
64 machine.wait_for_unit("dex.service", timeout=120)
65 # Wait until server accepts connections
66 machine.wait_until_succeeds("curl -fs 'localhost:8080/dex/auth/mock?client_id=oidcclient&response_type=code&redirect_uri=https://example.com/callback&scope=openid'", timeout=120)
67
68 with subtest("Login"):
69 state = machine.succeed("curl -fs 'localhost:8080/dex/auth/mock?client_id=oidcclient&response_type=code&redirect_uri=https://example.com/callback&scope=openid' | sed -n 's/.*state=\\(.*\\)\">.*/\\1/p'").strip()
70 print(f"Got state {state}")
71 # Login request returns 303 with redirect_url that has code as query parameter:
72 # https://example.com/callback?code=kibsamwdupuy2iwqnlbqei3u6&state=
73 code = machine.succeed(f"curl -fs 'localhost:8080/dex/auth/mock/login?back=&state={state}' -d 'login=admin&password=password' -w '%{{redirect_url}}' | sed -n 's/.*code=\\(.*\\)&.*/\\1/p'")
74 print(f"Got approval code {code}")
75 bearer = machine.succeed(f"curl -fs localhost:8080/dex/token -u oidcclient:oidcclientsecret -d 'grant_type=authorization_code&redirect_uri=https://example.com/callback&code={code}' | jq .access_token -r").strip()
76 print(f"Got access token {bearer}")
77
78 with subtest("Get userinfo"):
79 assert '"sub"' in machine.succeed(
80 f"curl -fs localhost:8080/dex/userinfo --oauth2-bearer {bearer}"
81 )
82 '';
83 }
84)