1
0
mirror of https://github.com/pocket-id/pocket-id.git synced 2026-02-15 18:05:05 +00:00

feat: implement token introspection (#405)

Co-authored-by: Kyle Mendell <kmendell@ofkm.us>
Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
Andreas Schneider
2025-04-09 09:18:03 +02:00
committed by GitHub
parent 8d6c1e5c08
commit 7e5d16be9b
9 changed files with 416 additions and 14 deletions

View File

@@ -6,12 +6,15 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"fmt"
"os"
"path/filepath"
"sync"
"testing"
"time"
"github.com/lestrrat-go/jwx/v3/jws"
"github.com/lestrrat-go/jwx/v3/jwa"
"github.com/lestrrat-go/jwx/v3/jwk"
"github.com/lestrrat-go/jwx/v3/jwt"
@@ -651,8 +654,13 @@ func TestGenerateVerifyIdToken(t *testing.T) {
}
}
// Create headers with the specified type
hdrs := jws.NewHeaders()
err = hdrs.Set(jws.TypeKey, "ID+JWT")
require.NoError(t, err, "Failed to set header type")
// Sign the token
signed, err := jwt.Sign(token, jwt.WithKey(jwa.RS256(), service.privateKey))
signed, err := jwt.Sign(token, jwt.WithKey(jwa.RS256(), service.privateKey, jws.WithProtectedHeaders(hdrs)))
require.NoError(t, err, "Failed to sign token")
tokenString := string(signed)
@@ -1172,6 +1180,63 @@ func TestGenerateVerifyOauthAccessToken(t *testing.T) {
})
}
func TestVerifyTokenTypeHeader(t *testing.T) {
mockConfig := &AppConfigService{}
tempDir := t.TempDir()
// Helper function to create a token with a specific type header
createTokenWithType := func(tokenType string) (string, error) {
// Create a simple JWT token
token := jwt.New()
err := token.Set("test_claim", "test_value")
if err != nil {
return "", fmt.Errorf("failed to set claim: %w", err)
}
// Create headers with the specified type
hdrs := jws.NewHeaders()
if tokenType != "" {
err = hdrs.Set(jws.TypeKey, tokenType)
if err != nil {
return "", fmt.Errorf("failed to set type header: %w", err)
}
}
// Sign the token with the headers
service := &JwtService{}
err = service.init(mockConfig, tempDir)
require.NoError(t, err, "Failed to initialize JWT service")
signed, err := jwt.Sign(token, jwt.WithKey(jwa.RS256(), service.privateKey, jws.WithProtectedHeaders(hdrs)))
if err != nil {
return "", fmt.Errorf("failed to sign token: %w", err)
}
return string(signed), nil
}
t.Run("succeeds when token type matches expected type", func(t *testing.T) {
// Create a token with "JWT" type
tokenString, err := createTokenWithType("JWT")
require.NoError(t, err, "Failed to create test token")
// Verify the token type
err = VerifyTokenTypeHeader(tokenString, "JWT")
assert.NoError(t, err, "Should accept token with matching type")
})
t.Run("fails when token type doesn't match expected type", func(t *testing.T) {
// Create a token with "AT+JWT" type
tokenString, err := createTokenWithType("AT+JWT")
require.NoError(t, err, "Failed to create test token")
// Verify the token with different expected type
err = VerifyTokenTypeHeader(tokenString, "JWT")
require.Error(t, err, "Should reject token with non-matching type")
assert.Contains(t, err.Error(), "header mismatch: expected 'JWT', got 'AT+JWT'")
})
}
func importKey(t *testing.T, privateKeyRaw any, path string) string {
t.Helper()