fix(jwt): fix handling of non-expiring JWT tokens BE-11242 (#12220)

pull/12223/head
andres-portainer 2 months ago committed by GitHub
parent dbe7cd16d4
commit 5fd4f52e35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -381,7 +381,9 @@ func (bouncer *RequestBouncer) RevokeJWT(token string) {
func (bouncer *RequestBouncer) cleanUpExpiredJWTPass() {
bouncer.revokedJWT.Range(func(key, value any) bool {
if time.Now().After(value.(time.Time)) {
if t := value.(time.Time); t.IsZero() {
return true
} else if time.Now().After(t) {
bouncer.revokedJWT.Delete(key)
}

@ -473,6 +473,17 @@ func TestJWTRevocation(t *testing.T) {
token, _, err := jwtService.GenerateToken(&portainer.TokenData{ID: 1})
require.NoError(t, err)
settings, err := store.Settings().Settings()
require.NoError(t, err)
settings.KubeconfigExpiry = "0"
err = store.Settings().UpdateSettings(settings)
require.NoError(t, err)
kubeToken, err := jwtService.GenerateTokenForKubeconfig(&portainer.TokenData{ID: 1})
require.NoError(t, err)
apiKeyService := apikey.NewAPIKeyService(nil, nil)
bouncer := NewRequestBouncer(store, jwtService, apiKeyService)
@ -491,6 +502,7 @@ func TestJWTRevocation(t *testing.T) {
require.NoError(t, err)
bouncer.RevokeJWT(token)
bouncer.RevokeJWT(kubeToken)
revokeLen := func() (l int) {
bouncer.revokedJWT.Range(func(key, value any) bool {
@ -501,7 +513,7 @@ func TestJWTRevocation(t *testing.T) {
return l
}
require.Equal(t, 1, revokeLen())
require.Equal(t, 2, revokeLen())
_, err = bouncer.JWTAuthLookup(r)
require.Error(t, err)
@ -513,5 +525,5 @@ func TestJWTRevocation(t *testing.T) {
bouncer.cleanUpExpiredJWTPass()
require.Equal(t, 0, revokeLen())
require.Equal(t, 1, revokeLen())
}

@ -137,6 +137,10 @@ func (service *Service) ParseAndVerifyToken(token string) (*portainer.TokenData,
return nil, "", time.Time{}, errInvalidJWTToken
}
if cl.ExpiresAt == nil {
cl.ExpiresAt = &jwt.NumericDate{}
}
return &portainer.TokenData{
ID: portainer.UserID(cl.UserID),
Username: cl.Username,

@ -3,14 +3,20 @@ package jwt
import (
"testing"
"github.com/golang-jwt/jwt/v4"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
i "github.com/portainer/portainer/api/internal/testhelpers"
"github.com/portainer/portainer/api/datastore"
"github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/assert"
)
func TestService_GenerateTokenForKubeconfig(t *testing.T) {
_, store := datastore.MustNewTestStore(t, true, false)
err := store.User().Create(&portainer.User{ID: 1})
assert.NoError(t, err)
type fields struct {
userSessionTimeout string
dataStore dataservices.DataStore
@ -20,13 +26,17 @@ func TestService_GenerateTokenForKubeconfig(t *testing.T) {
data *portainer.TokenData
}
mySettings := &portainer.Settings{
KubeconfigExpiry: "0",
}
settings, err := store.Settings().Settings()
assert.NoError(t, err)
settings.KubeconfigExpiry = "0"
err = store.Settings().UpdateSettings(settings)
assert.NoError(t, err)
myFields := fields{
userSessionTimeout: "24h",
dataStore: i.NewDatastore(i.WithSettingsService(mySettings)),
dataStore: store,
}
myTokenData := &portainer.TokenData{
@ -66,6 +76,9 @@ func TestService_GenerateTokenForKubeconfig(t *testing.T) {
return
}
_, _, _, err = service.ParseAndVerifyToken(got)
assert.NoError(t, err)
parsedToken, err := jwt.ParseWithClaims(got, &claims{}, func(token *jwt.Token) (any, error) {
return service.secrets[kubeConfigScope], nil
})

Loading…
Cancel
Save