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