Files
grafana/pkg/apimachinery/identity/requester_test.go
Alexander Zobnin 294fd943c0 Chore: Update authlib (#110880)
* Chore: Update authlib

* exclude incompatible version of github.com/grafana/gomemcache

* Update go-jose to v4

* fix jose imports

* remove jose v3 from go.mod

* fix tests

* fix serialize

* fix failing live tests

* add v1 of ES256 testkeys. Port tests to use ES256 instead of HS256

* accept more signature algs for okta and azuread

* azure social graph token sig

* accept more signature algs for oauth refresh and jwt auth

* update workspace

* add a static signer for inproc

* rebase and fix ext_jwt

* fix jwt tests

* apply alex patch on gomemcache

* update linting

* fix ext_jwt panic

* update workspaces

---------

Co-authored-by: Jo Garnier <git@jguer.space>
2025-09-15 12:45:15 +02:00

127 lines
2.8 KiB
Go

package identity_test
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/pem"
"fmt"
"testing"
"time"
"github.com/go-jose/go-jose/v4"
"github.com/go-jose/go-jose/v4/jwt"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/apimachinery/identity"
)
func TestIsIDTokenExpired(t *testing.T) {
tests := []struct {
name string
token func(t *testing.T) string
expected bool
}{
{
name: "should return false when ID token is not set",
token: func(t *testing.T) string {
return ""
},
expected: false,
},
{
name: "should return false when ID token is not expired",
token: func(t *testing.T) string {
expiration := time.Now().Add(time.Hour)
return createToken(t, &expiration)
},
expected: false,
},
{
name: "should return true when ID token is expired",
token: func(t *testing.T) string {
expiration := time.Now().Add(-time.Hour)
return createToken(t, &expiration)
},
expected: true,
},
{
name: "should return false when ID token has no expiry claim",
token: func(t *testing.T) string {
return createToken(t, nil)
},
expected: false,
},
{
name: "should return false when ID token is malformed",
token: func(t *testing.T) string {
return "invalid.jwt.token"
},
expected: false,
},
{
name: "should handle token that expires exactly now",
token: func(t *testing.T) string {
expiration := time.Now().Add(-time.Millisecond)
return createToken(t, &expiration)
},
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
token := tt.token(t)
requester := &identity.StaticRequester{IDToken: token}
result := identity.IsIDTokenExpired(requester)
require.Equal(t, tt.expected, result)
})
}
}
var testKey = decodePrivateKey([]byte(`
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEID6lXWsmcv/UWn9SptjOThsy88cifgGIBj2Lu0M9I8tQoAoGCCqGSM49
AwEHoUQDQgAEsf6eNnNMNhl+q7jXsbdUf3ADPh248uoFUSSV9oBzgptyokHCjJz6
n6PKDm2W7i3S2+dAs5M5f3s7d8KiLjGZdQ==
-----END EC PRIVATE KEY-----
`))
func decodePrivateKey(data []byte) *ecdsa.PrivateKey {
block, _ := pem.Decode(data)
if block == nil {
panic("should include PEM block")
}
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
panic(fmt.Sprintf("should be able to parse ec private key: %v", err))
}
if privateKey.Curve.Params().Name != "P-256" {
panic("should be valid private key")
}
return privateKey
}
func createToken(t *testing.T, exp *time.Time) string {
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.ES256, Key: testKey}, nil)
require.NoError(t, err)
claims := struct {
jwt.Claims
}{
Claims: jwt.Claims{
Subject: "test-user",
},
}
if exp != nil {
claims.Expiry = jwt.NewNumericDate(*exp)
}
token, err := jwt.Signed(signer).Claims(claims).Serialize()
require.NoError(t, err)
return token
}