Implement KeyCape provider and service identity contracts
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 25s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02e3f-7301-7622-9be1-12e5f352881c
This commit is contained in:
tegwick 2026-08-23 13:10:13 +02:00
parent cdfb046b80
commit efce3e9331
15 changed files with 579 additions and 26 deletions

View file

@ -291,6 +291,30 @@ func TestTokenHandler_ClientCredentials_ReturnsScopedServiceToken(t *testing.T)
}
}
func TestTokenHandler_ClientCredentials_UsesPerClientLifetime(t *testing.T) {
h := serviceTokenHandler(t)
h.ClientConfig["rapp-qonto"].TokenLifetime = 5 * time.Minute
req := tokenRequest(url.Values{
"grant_type": {"client_credentials"},
"scope": {"finance.qonto.read"},
})
req.SetBasicAuth("rapp-qonto", "test-service-secret")
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
resp := decodeTokenResponse(t, w.Body.String())
if got := int(resp["expires_in"].(float64)); got != 300 {
t.Fatalf("expires_in: want 300, got %d", got)
}
claims := parseJWTPayload(t, resp["access_token"].(string))
ttl := int64(claims["exp"].(float64) - claims["iat"].(float64))
if ttl != 300 {
t.Fatalf("JWT lifetime: want 300 seconds, got %d", ttl)
}
}
func TestTokenHandler_ClientCredentials_RejectsWrongSecret(t *testing.T) {
h := serviceTokenHandler(t)
req := tokenRequest(url.Values{"grant_type": {"client_credentials"}})