package protocol import ( "errors" "net/url" "reflect" "testing" ) func TestParseExchangeRequest(t *testing.T) { request, err := ParseExchangeRequest(validForm()) if err != nil { t.Fatalf("ParseExchangeRequest() error = %v", err) } if request.ClientID != "homelab-infra-ci" { t.Fatalf("ClientID = %q", request.ClientID) } if !reflect.DeepEqual(request.Scopes, []string{"bao.login", "ssh.certificate"}) { t.Fatalf("Scopes = %#v", request.Scopes) } } func TestParseExchangeRequestRejectsInvalidInput(t *testing.T) { tests := []struct { name string mutate func(url.Values) code string }{ {name: "missing client id", mutate: func(v url.Values) { v.Del("client_id") }, code: "invalid_request"}, {name: "short client id", mutate: func(v url.Values) { v.Set("client_id", "ci") }, code: "invalid_request"}, {name: "uppercase client id", mutate: func(v url.Values) { v.Set("client_id", "CI-worker") }, code: "invalid_request"}, {name: "leading hyphen", mutate: func(v url.Values) { v.Set("client_id", "-ci-worker") }, code: "invalid_request"}, {name: "missing token", mutate: func(v url.Values) { v.Del("subject_token") }, code: "invalid_request"}, {name: "wrong grant", mutate: func(v url.Values) { v.Set("grant_type", "client_credentials") }, code: "unsupported_grant_type"}, {name: "missing audience", mutate: func(v url.Values) { v.Del("audience") }, code: "invalid_target"}, {name: "multiple audiences", mutate: func(v url.Values) { v.Add("audience", "second") }, code: "invalid_target"}, {name: "missing scope", mutate: func(v url.Values) { v.Del("scope") }, code: "invalid_scope"}, {name: "actor token", mutate: func(v url.Values) { v.Set("actor_token", "not-supported") }, code: "invalid_request"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { form := validForm() test.mutate(form) _, err := ParseExchangeRequest(form) var requestErr *RequestError if !errors.As(err, &requestErr) { t.Fatalf("error = %v, want RequestError", err) } if requestErr.Code != test.code { t.Fatalf("error code = %q, want %q", requestErr.Code, test.code) } }) } } func validForm() url.Values { return url.Values{ "grant_type": {TokenExchangeGrantType}, "client_id": {"homelab-infra-ci"}, "subject_token": {"test-subject-token"}, "subject_token_type": {JWTTokenType}, "requested_token_type": {AccessTokenType}, "audience": {"https://bao.ad.ddupan.top:8200"}, "scope": {"bao.login ssh.certificate"}, } }