Files
Hidetake IwataandGitHub 3d114bfeba Lock token cache file before authentication (#1126)
* Lock token cache file in authentication

* Fix tests

* make generate

* Lock before FindByKey

* Fix test
2024-09-21 14:54:32 +09:00

231 lines
7.8 KiB
Go

package standalone
import (
"context"
"errors"
"testing"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/kubeconfig/loader_mock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/kubeconfig/writer_mock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/authentication_mock"
"github.com/int128/kubelogin/pkg/kubeconfig"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/testing/clock"
testingJWT "github.com/int128/kubelogin/pkg/testing/jwt"
"github.com/int128/kubelogin/pkg/testing/logger"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/usecases/authentication"
)
func TestStandalone_Do(t *testing.T) {
expiryTime := time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC)
issuedIDToken := testingJWT.EncodeF(t, func(claims *testingJWT.Claims) {
claims.Issuer = "https://accounts.google.com"
claims.Subject = "YOUR_SUBJECT"
claims.ExpiresAt = jwt.NewNumericDate(expiryTime)
})
t.Run("FullOptions", func(t *testing.T) {
var grantOptionSet authentication.GrantOptionSet
ctx := context.TODO()
in := Input{
KubeconfigFilename: "/path/to/kubeconfig",
KubeconfigContext: "theContext",
KubeconfigUser: "theUser",
GrantOptionSet: grantOptionSet,
}
currentAuthProvider := &kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "theUser",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
IDPCertificateAuthority: "/path/to/cert2",
IDPCertificateAuthorityData: "BASE64ENCODED2",
}
mockLoader := loader_mock.NewMockInterface(t)
mockLoader.EXPECT().
GetCurrentAuthProvider("/path/to/kubeconfig", kubeconfig.ContextName("theContext"), kubeconfig.UserName("theUser")).
Return(currentAuthProvider, nil)
mockWriter := writer_mock.NewMockInterface(t)
mockWriter.EXPECT().
UpdateAuthProvider(kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "theUser",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
IDPCertificateAuthority: "/path/to/cert2",
IDPCertificateAuthorityData: "BASE64ENCODED2",
IDToken: issuedIDToken,
RefreshToken: "YOUR_REFRESH_TOKEN",
}).
Return(nil)
mockAuthentication := authentication_mock.NewMockInterface(t)
mockAuthentication.EXPECT().
Do(ctx, authentication.Input{
Provider: oidc.Provider{
IssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
},
GrantOptionSet: grantOptionSet,
TLSClientConfig: tlsclientconfig.Config{
CACertFilename: []string{"/path/to/cert2"},
CACertData: []string{"BASE64ENCODED2"},
},
}).
Return(&authentication.Output{
TokenSet: oidc.TokenSet{
IDToken: issuedIDToken,
RefreshToken: "YOUR_REFRESH_TOKEN",
},
}, nil)
u := Standalone{
Authentication: mockAuthentication,
KubeconfigLoader: mockLoader,
KubeconfigWriter: mockWriter,
Logger: logger.New(t),
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
}
if err := u.Do(ctx, in); err != nil {
t.Errorf("Do returned error: %+v", err)
}
})
t.Run("HasValidIDToken", func(t *testing.T) {
ctx := context.TODO()
in := Input{}
currentAuthProvider := &kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "theUser",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
IDToken: issuedIDToken,
}
mockLoader := loader_mock.NewMockInterface(t)
mockLoader.EXPECT().
GetCurrentAuthProvider("", kubeconfig.ContextName(""), kubeconfig.UserName("")).
Return(currentAuthProvider, nil)
u := Standalone{
Authentication: authentication_mock.NewMockInterface(t),
KubeconfigLoader: mockLoader,
Logger: logger.New(t),
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
}
if err := u.Do(ctx, in); err != nil {
t.Errorf("Do returned error: %+v", err)
}
})
t.Run("NoOIDCConfig", func(t *testing.T) {
ctx := context.TODO()
in := Input{}
mockLoader := loader_mock.NewMockInterface(t)
mockLoader.EXPECT().
GetCurrentAuthProvider("", kubeconfig.ContextName(""), kubeconfig.UserName("")).
Return(nil, errors.New("no oidc config"))
mockAuthentication := authentication_mock.NewMockInterface(t)
u := Standalone{
Authentication: mockAuthentication,
KubeconfigLoader: mockLoader,
Logger: logger.New(t),
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
}
if err := u.Do(ctx, in); err == nil {
t.Errorf("err wants non-nil but nil")
}
})
t.Run("AuthenticationError", func(t *testing.T) {
ctx := context.TODO()
in := Input{}
currentAuthProvider := &kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "google",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
}
mockLoader := loader_mock.NewMockInterface(t)
mockLoader.EXPECT().
GetCurrentAuthProvider("", kubeconfig.ContextName(""), kubeconfig.UserName("")).
Return(currentAuthProvider, nil)
mockAuthentication := authentication_mock.NewMockInterface(t)
mockAuthentication.EXPECT().
Do(ctx, authentication.Input{
Provider: oidc.Provider{
IssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
},
}).
Return(nil, errors.New("authentication error"))
u := Standalone{
Authentication: mockAuthentication,
KubeconfigLoader: mockLoader,
Logger: logger.New(t),
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
}
if err := u.Do(ctx, in); err == nil {
t.Errorf("err wants non-nil but nil")
}
})
t.Run("WriteError", func(t *testing.T) {
ctx := context.TODO()
in := Input{}
currentAuthProvider := &kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "google",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
}
mockLoader := loader_mock.NewMockInterface(t)
mockLoader.EXPECT().
GetCurrentAuthProvider("", kubeconfig.ContextName(""), kubeconfig.UserName("")).
Return(currentAuthProvider, nil)
mockWriter := writer_mock.NewMockInterface(t)
mockWriter.EXPECT().
UpdateAuthProvider(kubeconfig.AuthProvider{
LocationOfOrigin: "/path/to/kubeconfig",
UserName: "google",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
IDToken: issuedIDToken,
RefreshToken: "YOUR_REFRESH_TOKEN",
}).
Return(errors.New("I/O error"))
mockAuthentication := authentication_mock.NewMockInterface(t)
mockAuthentication.EXPECT().
Do(ctx, authentication.Input{
Provider: oidc.Provider{
IssuerURL: "https://accounts.google.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
},
}).
Return(&authentication.Output{
TokenSet: oidc.TokenSet{
IDToken: issuedIDToken,
RefreshToken: "YOUR_REFRESH_TOKEN",
},
}, nil)
u := Standalone{
Authentication: mockAuthentication,
KubeconfigLoader: mockLoader,
KubeconfigWriter: mockWriter,
Logger: logger.New(t),
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
}
if err := u.Do(ctx, in); err == nil {
t.Errorf("err wants non-nil but nil")
}
})
}