import ./make-test-python.nix ({ lib, ... }: { name = "dex-oidc"; meta.maintainers = with lib.maintainers; [ Flakebi ]; nodes.machine = { pkgs, ... }: { environment.systemPackages = with pkgs; [ jq ]; services.dex = { enable = true; settings = { issuer = "http://127.0.0.1:8080/dex"; storage = { type = "postgres"; config.host = "/var/run/postgresql"; }; web.http = "127.0.0.1:8080"; oauth2.skipApprovalScreen = true; staticClients = [ { id = "oidcclient"; name = "Client"; redirectURIs = [ "https://example.com/callback" ]; secretFile = "/etc/dex/oidcclient"; } ]; connectors = [ { type = "mockPassword"; id = "mock"; name = "Example"; config = { username = "admin"; password = "password"; }; } ]; }; }; # This should not be set from nix but through other means to not leak the secret. environment.etc."dex/oidcclient" = { mode = "0400"; user = "dex"; text = "oidcclientsecret"; }; services.postgresql = { enable = true; ensureDatabases =[ "dex" ]; ensureUsers = [ { name = "dex"; ensureDBOwnership = true; } ]; }; }; testScript = '' with subtest("Web server gets ready"): machine.wait_for_unit("dex.service", timeout=120) # Wait until server accepts connections 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) with subtest("Login"): 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() print(f"Got state {state}") # Login request returns 303 with redirect_url that has code as query parameter: # https://example.com/callback?code=kibsamwdupuy2iwqnlbqei3u6&state= 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'") print(f"Got approval code {code}") 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() print(f"Got access token {bearer}") with subtest("Get userinfo"): assert '"sub"' in machine.succeed( f"curl -fs localhost:8080/dex/userinfo --oauth2-bearer {bearer}" ) ''; })