Implement KeyCape service-token issuance
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 47s
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 47s
This commit is contained in:
parent
519f0772d2
commit
e877d2752d
10 changed files with 348 additions and 43 deletions
|
|
@ -209,7 +209,7 @@ func TestTokenHandler_WrongGrantType_FeatureNotSupported(t *testing.T) {
|
|||
h, _ := newTokenHandler(t, sessions, users)
|
||||
|
||||
params := url.Values{
|
||||
"grant_type": []string{"client_credentials"},
|
||||
"grant_type": []string{"password"},
|
||||
"client_id": []string{"test-client"},
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +226,72 @@ func TestTokenHandler_WrongGrantType_FeatureNotSupported(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func serviceTokenHandler(t *testing.T) *oidc.TokenHandler {
|
||||
t.Helper()
|
||||
h, _ := newTokenHandler(t, oidc.NewSessionStore(), &mockUserRepo{})
|
||||
h.ClientConfig["rapp-qonto"] = &domain.Client{
|
||||
ClientID: "rapp-qonto",
|
||||
AllowedScopes: []string{"finance.qonto.read"},
|
||||
GrantTypes: []string{"client_credentials"},
|
||||
ClientType: "confidential",
|
||||
ClientSecret: "test-service-secret",
|
||||
ServiceSubject: "service:rapp-qonto",
|
||||
Tenant: "tenant:friendly:binky",
|
||||
Roles: []string{"finance-reader"},
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func TestTokenHandler_ClientCredentials_ReturnsScopedServiceToken(t *testing.T) {
|
||||
h := serviceTokenHandler(t)
|
||||
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 _, ok := resp["id_token"]; ok {
|
||||
t.Fatal("service exchange must not return id_token")
|
||||
}
|
||||
claims := parseJWTPayload(t, resp["access_token"].(string))
|
||||
if claims["sub"] != "service:rapp-qonto" ||
|
||||
claims["tenant"] != "tenant:friendly:binky" ||
|
||||
claims["principal_type"] != "service" ||
|
||||
claims["scope"] != "finance.qonto.read" {
|
||||
t.Fatalf("unexpected service claims: %#v", claims)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenHandler_ClientCredentials_RejectsWrongSecret(t *testing.T) {
|
||||
h := serviceTokenHandler(t)
|
||||
req := tokenRequest(url.Values{"grant_type": {"client_credentials"}})
|
||||
req.SetBasicAuth("rapp-qonto", "wrong")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("expected 401, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenHandler_ClientCredentials_RejectsExcessScope(t *testing.T) {
|
||||
h := serviceTokenHandler(t)
|
||||
req := tokenRequest(url.Values{
|
||||
"grant_type": {"client_credentials"},
|
||||
"scope": {"finance.qonto.write"},
|
||||
})
|
||||
req.SetBasicAuth("rapp-qonto", "test-service-secret")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenHandler_PKCEMismatch_InvalidProfileUsage(t *testing.T) {
|
||||
sessions := oidc.NewSessionStore()
|
||||
users := &mockUserRepo{users: map[string]*domain.User{"alice": aliceUser()}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue