mirror of
https://github.com/int128/kubelogin.git
synced 2026-08-23 21:06:15 +00:00
Refactor: extract oidc.Claims model (#202)
* Refactor: extract oidc.Claims model * Refactor: extract Claims.IsExpired()
This commit is contained in:
Vendored
+7
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/wire"
|
||||
"github.com/pkg/browser"
|
||||
@@ -33,6 +34,7 @@ type Interface interface {
|
||||
ReadString(prompt string) (string, error)
|
||||
ReadPassword(prompt string) (string, error)
|
||||
OpenBrowser(url string) error
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
// Env provides environment specific facilities.
|
||||
@@ -74,3 +76,8 @@ func (env *Env) OpenBrowser(url string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Now returns the current time.
|
||||
func (*Env) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
+15
@@ -7,6 +7,7 @@ package mock_env
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface
|
||||
@@ -32,6 +33,20 @@ func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Now mocks base method
|
||||
func (m *MockInterface) Now() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Now")
|
||||
ret0, _ := ret[0].(time.Time)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Now indicates an expected call of Now
|
||||
func (mr *MockInterfaceMockRecorder) Now() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Now", reflect.TypeOf((*MockInterface)(nil).Now))
|
||||
}
|
||||
|
||||
// OpenBrowser mocks base method
|
||||
func (m *MockInterface) OpenBrowser(arg0 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/google/wire"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
@@ -22,21 +23,14 @@ var Set = wire.NewSet(
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Decode(s string) (*Claims, error)
|
||||
}
|
||||
|
||||
// Claims represents claims of a token.
|
||||
type Claims struct {
|
||||
Subject string
|
||||
Expiry time.Time
|
||||
Pretty map[string]string // string representation for debug and logging
|
||||
Decode(s string) (*oidc.Claims, error)
|
||||
}
|
||||
|
||||
type Decoder struct{}
|
||||
|
||||
// Decode returns the claims of the JWT.
|
||||
// Note that this method does not verify the signature and always trust it.
|
||||
func (d *Decoder) Decode(s string) (*Claims, error) {
|
||||
func (d *Decoder) Decode(s string) (*oidc.Claims, error) {
|
||||
parts := strings.Split(s, ".")
|
||||
if len(parts) != 3 {
|
||||
return nil, xerrors.Errorf("token contains an invalid number of segments")
|
||||
@@ -53,7 +47,7 @@ func (d *Decoder) Decode(s string) (*Claims, error) {
|
||||
if err := json.NewDecoder(bytes.NewBuffer(b)).Decode(&rawClaims); err != nil {
|
||||
return nil, xerrors.Errorf("could not decode the json of token: %w", err)
|
||||
}
|
||||
return &Claims{
|
||||
return &oidc.Claims{
|
||||
Subject: claims.Subject,
|
||||
Expiry: time.Unix(claims.ExpiresAt, 0),
|
||||
Pretty: dumpRawClaims(rawClaims),
|
||||
|
||||
@@ -6,7 +6,7 @@ package mock_jwtdecoder
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
jwtdecoder "github.com/int128/kubelogin/pkg/adaptors/jwtdecoder"
|
||||
oidc "github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
@@ -34,10 +34,10 @@ func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
}
|
||||
|
||||
// Decode mocks base method
|
||||
func (m *MockInterface) Decode(arg0 string) (*jwtdecoder.Claims, error) {
|
||||
func (m *MockInterface) Decode(arg0 string) (*oidc.Claims, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Decode", arg0)
|
||||
ret0, _ := ret[0].(*jwtdecoder.Claims)
|
||||
ret0, _ := ret[0].(*oidc.Claims)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/google/wire"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger"
|
||||
oidcModel "github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"github.com/int128/oauth2cli"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -56,11 +57,9 @@ type GetTokenByAuthCodeInput struct {
|
||||
// TokenSet represents an output DTO of
|
||||
// Interface.GetTokenByAuthCode, Interface.GetTokenByROPC and Interface.Refresh.
|
||||
type TokenSet struct {
|
||||
IDToken string
|
||||
RefreshToken string
|
||||
IDTokenSubject string
|
||||
IDTokenExpiry time.Time
|
||||
IDTokenClaims map[string]string // string representation of claims for logging
|
||||
IDToken string
|
||||
RefreshToken string
|
||||
IDTokenClaims oidcModel.Claims
|
||||
}
|
||||
|
||||
type client struct {
|
||||
@@ -171,16 +170,20 @@ func (c *client) verifyToken(ctx context.Context, token *oauth2.Token, nonce str
|
||||
}
|
||||
return &TokenSet{
|
||||
IDToken: idTokenString,
|
||||
RefreshToken: token.RefreshToken,
|
||||
IDTokenExpiry: idToken.Expiry,
|
||||
IDTokenClaims: claims,
|
||||
RefreshToken: token.RefreshToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dumpClaims(token *oidc.IDToken) (map[string]string, error) {
|
||||
func dumpClaims(token *oidc.IDToken) (oidcModel.Claims, error) {
|
||||
var rawClaims map[string]interface{}
|
||||
err := token.Claims(&rawClaims)
|
||||
return dumpRawClaims(rawClaims), err
|
||||
pretty := dumpRawClaims(rawClaims)
|
||||
return oidcModel.Claims{
|
||||
Subject: token.Subject,
|
||||
Expiry: token.Expiry,
|
||||
Pretty: pretty,
|
||||
}, err
|
||||
}
|
||||
|
||||
func dumpRawClaims(rawClaims map[string]interface{}) map[string]string {
|
||||
|
||||
@@ -48,6 +48,7 @@ func NewCmd() cmd.Interface {
|
||||
OIDCClientFactory: factory,
|
||||
JWTDecoder: decoder,
|
||||
Logger: loggerInterface,
|
||||
Env: envEnv,
|
||||
AuthCode: authCode,
|
||||
AuthCodeKeyboard: authCodeKeyboard,
|
||||
ROPC: ropc,
|
||||
@@ -123,6 +124,7 @@ func NewCmdForHeadless(loggerInterface logger.Interface, localServerReadyFunc au
|
||||
OIDCClientFactory: factory,
|
||||
JWTDecoder: decoder,
|
||||
Logger: loggerInterface,
|
||||
Env: envEnv,
|
||||
AuthCode: authCode,
|
||||
AuthCodeKeyboard: authCodeKeyboard,
|
||||
ROPC: ropc,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package oidc
|
||||
|
||||
import "time"
|
||||
|
||||
// Claims represents claims of an ID token.
|
||||
type Claims struct {
|
||||
Subject string
|
||||
Expiry time.Time
|
||||
Pretty map[string]string // string representation for debug and logging
|
||||
}
|
||||
|
||||
// TimeProvider provides the current time.
|
||||
type TimeProvider interface {
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
// IsExpired returns true if the token is expired.
|
||||
func (c *Claims) IsExpired(timeProvider TimeProvider) bool {
|
||||
return c.Expiry.Before(timeProvider.Now())
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package oidc_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
)
|
||||
|
||||
type timeProvider time.Time
|
||||
|
||||
func (tp timeProvider) Now() time.Time {
|
||||
return time.Time(tp)
|
||||
}
|
||||
|
||||
func TestClaims_IsExpired(t *testing.T) {
|
||||
claims := oidc.Claims{
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
}
|
||||
|
||||
t.Run("Expired", func(t *testing.T) {
|
||||
tp := timeProvider(time.Date(2019, 1, 2, 4, 0, 0, 0, time.UTC))
|
||||
got := claims.IsExpired(tp)
|
||||
if got != true {
|
||||
t.Errorf("IsExpired() wants true but false")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("NotExpired", func(t *testing.T) {
|
||||
tp := timeProvider(time.Date(2019, 1, 2, 0, 0, 0, 0, time.UTC))
|
||||
got := claims.IsExpired(tp)
|
||||
if got != false {
|
||||
t.Errorf("IsExpired() wants false but true")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -66,11 +66,9 @@ func (u *AuthCode) Do(ctx context.Context, o *AuthCodeOption, client oidcclient.
|
||||
return xerrors.Errorf("error while the authorization code flow: %w", err)
|
||||
}
|
||||
out = Output{
|
||||
IDToken: tokenSet.IDToken,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
IDTokenSubject: tokenSet.IDTokenSubject,
|
||||
IDTokenExpiry: tokenSet.IDTokenExpiry,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
IDToken: tokenSet.IDToken,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -56,10 +56,8 @@ func (u *AuthCodeKeyboard) Do(ctx context.Context, o *AuthCodeKeyboardOption, cl
|
||||
return nil, xerrors.Errorf("could not get the token: %w", err)
|
||||
}
|
||||
return &Output{
|
||||
IDToken: tokenSet.IDToken,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
IDTokenSubject: tokenSet.IDTokenSubject,
|
||||
IDTokenExpiry: tokenSet.IDTokenExpiry,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
IDToken: tokenSet.IDToken,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -11,13 +11,17 @@ import (
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient/mock_oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
)
|
||||
|
||||
var nonNil = gomock.Not(gomock.Nil())
|
||||
|
||||
func TestAuthCodeKeyboard_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
timeout := 5 * time.Second
|
||||
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
@@ -37,11 +41,9 @@ func TestAuthCodeKeyboard_Do(t *testing.T) {
|
||||
}
|
||||
}).
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
}, nil)
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().
|
||||
@@ -56,11 +58,9 @@ func TestAuthCodeKeyboard_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
||||
@@ -11,11 +11,15 @@ import (
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient/mock_oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
)
|
||||
|
||||
func TestAuthCode_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
timeout := 5 * time.Second
|
||||
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
@@ -34,11 +38,9 @@ func TestAuthCode_Do(t *testing.T) {
|
||||
readyChan <- "LOCAL_SERVER_URL"
|
||||
}).
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := AuthCode{
|
||||
Logger: mock_logger.New(t),
|
||||
@@ -48,11 +50,9 @@ func TestAuthCode_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
@@ -74,11 +74,9 @@ func TestAuthCode_Do(t *testing.T) {
|
||||
readyChan <- "LOCAL_SERVER_URL"
|
||||
}).
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().
|
||||
@@ -92,11 +90,9 @@ func TestAuthCode_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
||||
@@ -2,13 +2,14 @@ package authentication
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/wire"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/certpool"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/env"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/jwtdecoder"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
@@ -67,10 +68,8 @@ type ROPCOption struct {
|
||||
// Output represents an output DTO of the Authentication use-case.
|
||||
type Output struct {
|
||||
AlreadyHasValidIDToken bool
|
||||
IDTokenSubject string
|
||||
IDTokenExpiry time.Time
|
||||
IDTokenClaims map[string]string
|
||||
IDToken string
|
||||
IDTokenClaims oidc.Claims
|
||||
RefreshToken string
|
||||
}
|
||||
|
||||
@@ -94,6 +93,7 @@ type Authentication struct {
|
||||
OIDCClientFactory oidcclient.FactoryInterface
|
||||
JWTDecoder jwtdecoder.Interface
|
||||
Logger logger.Interface
|
||||
Env env.Interface
|
||||
AuthCode *AuthCode
|
||||
AuthCodeKeyboard *AuthCodeKeyboard
|
||||
ROPC *ROPC
|
||||
@@ -109,15 +109,13 @@ func (u *Authentication) Do(ctx context.Context, in Input) (*Output, error) {
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid token and you need to remove the cache: %w", err)
|
||||
}
|
||||
if claims.Expiry.After(time.Now()) { //TODO: inject time service
|
||||
if !claims.IsExpired(u.Env) {
|
||||
u.Logger.V(1).Infof("you already have a valid token until %s", claims.Expiry)
|
||||
return &Output{
|
||||
AlreadyHasValidIDToken: true,
|
||||
IDToken: in.IDToken,
|
||||
RefreshToken: in.RefreshToken,
|
||||
IDTokenSubject: claims.Subject,
|
||||
IDTokenExpiry: claims.Expiry,
|
||||
IDTokenClaims: claims.Pretty,
|
||||
IDTokenClaims: *claims,
|
||||
}, nil
|
||||
}
|
||||
u.Logger.V(1).Infof("you have an expired token at %s", claims.Expiry)
|
||||
@@ -141,11 +139,9 @@ func (u *Authentication) Do(ctx context.Context, in Input) (*Output, error) {
|
||||
out, err := client.Refresh(ctx, in.RefreshToken)
|
||||
if err == nil {
|
||||
return &Output{
|
||||
IDToken: out.IDToken,
|
||||
RefreshToken: out.RefreshToken,
|
||||
IDTokenSubject: out.IDTokenSubject,
|
||||
IDTokenExpiry: out.IDTokenExpiry,
|
||||
IDTokenClaims: out.IDTokenClaims,
|
||||
IDToken: out.IDToken,
|
||||
IDTokenClaims: out.IDTokenClaims,
|
||||
RefreshToken: out.RefreshToken,
|
||||
}, nil
|
||||
}
|
||||
u.Logger.V(1).Infof("could not refresh the token: %s", err)
|
||||
|
||||
@@ -7,18 +7,23 @@ import (
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/jwtdecoder"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/env/mock_env"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/jwtdecoder/mock_jwtdecoder"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient/mock_oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func TestAuthentication_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
pastTime := time.Now().Add(-time.Hour) //TODO: inject time service
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
timeBeforeExpiry := time.Date(2019, 1, 2, 1, 0, 0, 0, time.UTC)
|
||||
timeAfterExpiry := time.Date(2019, 1, 2, 4, 0, 0, 0, time.UTC)
|
||||
timeout := 5 * time.Second
|
||||
|
||||
t.Run("HasValidIDToken", func(t *testing.T) {
|
||||
@@ -32,18 +37,19 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
ClientSecret: "YOUR_CLIENT_SECRET",
|
||||
IDToken: "VALID_ID_TOKEN",
|
||||
}
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().
|
||||
Now().
|
||||
Return(timeBeforeExpiry)
|
||||
mockDecoder := mock_jwtdecoder.NewMockInterface(ctrl)
|
||||
mockDecoder.EXPECT().
|
||||
Decode("VALID_ID_TOKEN").
|
||||
Return(&jwtdecoder.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: futureTime,
|
||||
Pretty: dummyTokenClaims,
|
||||
}, nil)
|
||||
Return(&dummyTokenClaims, nil)
|
||||
u := Authentication{
|
||||
OIDCClientFactory: mock_oidcclient.NewMockFactoryInterface(ctrl),
|
||||
JWTDecoder: mockDecoder,
|
||||
Logger: mock_logger.New(t),
|
||||
Env: mockEnv,
|
||||
}
|
||||
got, err := u.Do(ctx, in)
|
||||
if err != nil {
|
||||
@@ -52,8 +58,6 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
want := &Output{
|
||||
AlreadyHasValidIDToken: true,
|
||||
IDToken: "VALID_ID_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
@@ -73,23 +77,21 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
IDToken: "EXPIRED_ID_TOKEN",
|
||||
RefreshToken: "VALID_REFRESH_TOKEN",
|
||||
}
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().
|
||||
Now().
|
||||
Return(timeAfterExpiry)
|
||||
mockDecoder := mock_jwtdecoder.NewMockInterface(ctrl)
|
||||
mockDecoder.EXPECT().
|
||||
Decode("EXPIRED_ID_TOKEN").
|
||||
Return(&jwtdecoder.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: pastTime,
|
||||
Pretty: dummyTokenClaims,
|
||||
}, nil)
|
||||
Return(&dummyTokenClaims, nil)
|
||||
mockOIDCClient := mock_oidcclient.NewMockInterface(ctrl)
|
||||
mockOIDCClient.EXPECT().
|
||||
Refresh(ctx, "VALID_REFRESH_TOKEN").
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
mockOIDCClientFactory := mock_oidcclient.NewMockFactoryInterface(ctrl)
|
||||
mockOIDCClientFactory.EXPECT().
|
||||
@@ -103,17 +105,16 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
OIDCClientFactory: mockOIDCClientFactory,
|
||||
JWTDecoder: mockDecoder,
|
||||
Logger: mock_logger.New(t),
|
||||
Env: mockEnv,
|
||||
}
|
||||
got, err := u.Do(ctx, in)
|
||||
if err != nil {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
@@ -138,14 +139,14 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
IDToken: "EXPIRED_ID_TOKEN",
|
||||
RefreshToken: "EXPIRED_REFRESH_TOKEN",
|
||||
}
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().
|
||||
Now().
|
||||
Return(timeAfterExpiry)
|
||||
mockDecoder := mock_jwtdecoder.NewMockInterface(ctrl)
|
||||
mockDecoder.EXPECT().
|
||||
Decode("EXPIRED_ID_TOKEN").
|
||||
Return(&jwtdecoder.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: pastTime,
|
||||
Pretty: dummyTokenClaims,
|
||||
}, nil)
|
||||
Return(&dummyTokenClaims, nil)
|
||||
mockOIDCClient := mock_oidcclient.NewMockInterface(ctrl)
|
||||
mockOIDCClient.EXPECT().
|
||||
Refresh(ctx, "EXPIRED_REFRESH_TOKEN").
|
||||
@@ -156,11 +157,9 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
readyChan <- "LOCAL_SERVER_URL"
|
||||
}).
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
mockOIDCClientFactory := mock_oidcclient.NewMockFactoryInterface(ctrl)
|
||||
mockOIDCClientFactory.EXPECT().
|
||||
@@ -174,6 +173,7 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
OIDCClientFactory: mockOIDCClientFactory,
|
||||
JWTDecoder: mockDecoder,
|
||||
Logger: mock_logger.New(t),
|
||||
Env: mockEnv,
|
||||
AuthCode: &AuthCode{
|
||||
Logger: mock_logger.New(t),
|
||||
},
|
||||
@@ -183,11 +183,9 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "NEW_ID_TOKEN",
|
||||
RefreshToken: "NEW_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
@@ -214,11 +212,9 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
mockOIDCClient.EXPECT().
|
||||
GetTokenByROPC(gomock.Any(), "USER", "PASS").
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
mockOIDCClientFactory := mock_oidcclient.NewMockFactoryInterface(ctrl)
|
||||
mockOIDCClientFactory.EXPECT().
|
||||
@@ -240,11 +236,9 @@ func TestAuthentication_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
||||
@@ -36,10 +36,8 @@ func (u *ROPC) Do(ctx context.Context, in *ROPCOption, client oidcclient.Interfa
|
||||
return nil, xerrors.Errorf("error while the resource owner password credentials flow: %w", err)
|
||||
}
|
||||
return &Output{
|
||||
IDToken: tokenSet.IDToken,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
IDTokenSubject: tokenSet.IDTokenSubject,
|
||||
IDTokenExpiry: tokenSet.IDTokenExpiry,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
IDToken: tokenSet.IDToken,
|
||||
IDTokenClaims: tokenSet.IDTokenClaims,
|
||||
RefreshToken: tokenSet.RefreshToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -11,12 +11,16 @@ import (
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/oidcclient/mock_oidcclient"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func TestROPC_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
timeout := 5 * time.Second
|
||||
|
||||
t.Run("AskUsernameAndPassword", func(t *testing.T) {
|
||||
@@ -29,11 +33,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
mockOIDCClient.EXPECT().
|
||||
GetTokenByROPC(gomock.Any(), "USER", "PASS").
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
}, nil)
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().ReadString(usernamePrompt).Return("USER", nil)
|
||||
@@ -47,11 +49,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
@@ -71,11 +71,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
mockOIDCClient.EXPECT().
|
||||
GetTokenByROPC(gomock.Any(), "USER", "PASS").
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := ROPC{
|
||||
Logger: mock_logger.New(t),
|
||||
@@ -85,11 +83,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
@@ -108,11 +104,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
mockOIDCClient.EXPECT().
|
||||
GetTokenByROPC(gomock.Any(), "USER", "PASS").
|
||||
Return(&oidcclient.TokenSet{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
mockEnv := mock_env.NewMockInterface(ctrl)
|
||||
mockEnv.EXPECT().ReadPassword(passwordPrompt).Return("PASS", nil)
|
||||
@@ -125,11 +119,9 @@ func TestROPC_Do(t *testing.T) {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
want := &Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
||||
@@ -53,7 +53,7 @@ func (u *GetToken) Do(ctx context.Context, in Input) error {
|
||||
return xerrors.Errorf("could not get a token from the cache or provider: %w", err)
|
||||
}
|
||||
u.Logger.V(1).Infof("writing the token to client-go")
|
||||
if err := u.Interaction.Write(credentialplugin.Output{Token: out.IDToken, Expiry: out.IDTokenExpiry}); err != nil {
|
||||
if err := u.Interaction.Write(credentialplugin.Output{Token: out.IDToken, Expiry: out.IDTokenClaims.Expiry}); err != nil {
|
||||
return xerrors.Errorf("could not write the token to client-go: %w", err)
|
||||
}
|
||||
return nil
|
||||
@@ -94,15 +94,15 @@ func (u *GetToken) getTokenFromCacheOrProvider(ctx context.Context, in Input) (*
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error while authentication: %w", err)
|
||||
}
|
||||
for k, v := range out.IDTokenClaims {
|
||||
for k, v := range out.IDTokenClaims.Pretty {
|
||||
u.Logger.V(1).Infof("the ID token has the claim: %s=%v", k, v)
|
||||
}
|
||||
if out.AlreadyHasValidIDToken {
|
||||
u.Logger.V(1).Infof("you already have a valid token until %s", out.IDTokenExpiry)
|
||||
u.Logger.V(1).Infof("you already have a valid token until %s", out.IDTokenClaims.Expiry)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
u.Logger.V(1).Infof("you got a valid token until %s", out.IDTokenExpiry)
|
||||
u.Logger.V(1).Infof("you got a valid token until %s", out.IDTokenClaims.Expiry)
|
||||
newTokenCacheValue := tokencache.Value{
|
||||
IDToken: out.IDToken,
|
||||
RefreshToken: out.RefreshToken,
|
||||
|
||||
@@ -12,14 +12,18 @@ import (
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/tokencache"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/tokencache/mock_tokencache"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication/mock_authentication"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func TestGetToken_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
|
||||
t.Run("FullOptions", func(t *testing.T) {
|
||||
var grantOptionSet authentication.GrantOptionSet
|
||||
@@ -55,7 +59,6 @@ func TestGetToken_Do(t *testing.T) {
|
||||
Return(&authentication.Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
tokenCacheRepository := mock_tokencache.NewMockInterface(ctrl)
|
||||
@@ -86,7 +89,7 @@ func TestGetToken_Do(t *testing.T) {
|
||||
credentialPluginInteraction.EXPECT().
|
||||
Write(credentialplugin.Output{
|
||||
Token: "YOUR_ID_TOKEN",
|
||||
Expiry: futureTime,
|
||||
Expiry: dummyTokenClaims.Expiry,
|
||||
})
|
||||
u := GetToken{
|
||||
Authentication: mockAuthentication,
|
||||
@@ -127,7 +130,6 @@ func TestGetToken_Do(t *testing.T) {
|
||||
Return(&authentication.Output{
|
||||
AlreadyHasValidIDToken: true,
|
||||
IDToken: "VALID_ID_TOKEN",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
tokenCacheRepository := mock_tokencache.NewMockInterface(ctrl)
|
||||
@@ -144,7 +146,7 @@ func TestGetToken_Do(t *testing.T) {
|
||||
credentialPluginInteraction.EXPECT().
|
||||
Write(credentialplugin.Output{
|
||||
Token: "VALID_ID_TOKEN",
|
||||
Expiry: futureTime,
|
||||
Expiry: dummyTokenClaims.Expiry,
|
||||
})
|
||||
u := GetToken{
|
||||
Authentication: mockAuthentication,
|
||||
|
||||
@@ -96,7 +96,7 @@ func (u *Setup) DoStage2(ctx context.Context, in Stage2Input) error {
|
||||
return xerrors.Errorf("error while authentication: %w", err)
|
||||
}
|
||||
u.Logger.Printf("You got the following claims in the token:")
|
||||
for k, v := range out.IDTokenClaims {
|
||||
for k, v := range out.IDTokenClaims.Pretty {
|
||||
u.Logger.Printf("\t%s=%s", k, v)
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func (u *Setup) DoStage2(ctx context.Context, in Stage2Input) error {
|
||||
IssuerURL: in.IssuerURL,
|
||||
ClientID: in.ClientID,
|
||||
Args: makeCredentialPluginArgs(in),
|
||||
Subject: out.IDTokenSubject,
|
||||
Subject: out.IDTokenClaims.Subject,
|
||||
}
|
||||
var b strings.Builder
|
||||
if err := stage2Tpl.Execute(&b, &v); err != nil {
|
||||
|
||||
@@ -8,11 +8,17 @@ import (
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/certpool/mock_certpool"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication/mock_authentication"
|
||||
)
|
||||
|
||||
func TestSetup_DoStage2(t *testing.T) {
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
var grantOptionSet authentication.GrantOptionSet
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
@@ -47,11 +53,9 @@ func TestSetup_DoStage2(t *testing.T) {
|
||||
GrantOptionSet: grantOptionSet,
|
||||
}).
|
||||
Return(&authentication.Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenSubject: "YOUR_SUBJECT",
|
||||
IDTokenExpiry: time.Now().Add(time.Hour),
|
||||
IDTokenClaims: map[string]string{"iss": "https://accounts.google.com"},
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := Setup{
|
||||
Authentication: mockAuthentication,
|
||||
|
||||
@@ -95,15 +95,15 @@ func (u *Standalone) Do(ctx context.Context, in Input) error {
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error while authentication: %w", err)
|
||||
}
|
||||
for k, v := range out.IDTokenClaims {
|
||||
for k, v := range out.IDTokenClaims.Pretty {
|
||||
u.Logger.V(1).Infof("the ID token has the claim: %s=%v", k, v)
|
||||
}
|
||||
if out.AlreadyHasValidIDToken {
|
||||
u.Logger.Printf("You already have a valid token until %s", out.IDTokenExpiry)
|
||||
u.Logger.Printf("You already have a valid token until %s", out.IDTokenClaims.Expiry)
|
||||
return nil
|
||||
}
|
||||
|
||||
u.Logger.Printf("You got a valid token until %s", out.IDTokenExpiry)
|
||||
u.Logger.Printf("You got a valid token until %s", out.IDTokenClaims.Expiry)
|
||||
authProvider.IDToken = out.IDToken
|
||||
authProvider.RefreshToken = out.RefreshToken
|
||||
u.Logger.V(1).Infof("writing the ID token and refresh token to %s", authProvider.LocationOfOrigin)
|
||||
|
||||
@@ -10,14 +10,18 @@ import (
|
||||
"github.com/int128/kubelogin/pkg/adaptors/kubeconfig"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/kubeconfig/mock_kubeconfig"
|
||||
"github.com/int128/kubelogin/pkg/adaptors/logger/mock_logger"
|
||||
"github.com/int128/kubelogin/pkg/domain/oidc"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication"
|
||||
"github.com/int128/kubelogin/pkg/usecases/authentication/mock_authentication"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func TestStandalone_Do(t *testing.T) {
|
||||
dummyTokenClaims := map[string]string{"sub": "YOUR_SUBJECT"}
|
||||
futureTime := time.Now().Add(time.Hour) //TODO: inject time service
|
||||
dummyTokenClaims := oidc.Claims{
|
||||
Subject: "YOUR_SUBJECT",
|
||||
Expiry: time.Date(2019, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
Pretty: map[string]string{"sub": "YOUR_SUBJECT"},
|
||||
}
|
||||
|
||||
t.Run("FullOptions", func(t *testing.T) {
|
||||
var grantOptionSet authentication.GrantOptionSet
|
||||
@@ -81,7 +85,6 @@ func TestStandalone_Do(t *testing.T) {
|
||||
Return(&authentication.Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := Standalone{
|
||||
@@ -129,7 +132,6 @@ func TestStandalone_Do(t *testing.T) {
|
||||
Return(&authentication.Output{
|
||||
AlreadyHasValidIDToken: true,
|
||||
IDToken: "VALID_ID_TOKEN",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := Standalone{
|
||||
@@ -249,7 +251,6 @@ func TestStandalone_Do(t *testing.T) {
|
||||
Return(&authentication.Output{
|
||||
IDToken: "YOUR_ID_TOKEN",
|
||||
RefreshToken: "YOUR_REFRESH_TOKEN",
|
||||
IDTokenExpiry: futureTime,
|
||||
IDTokenClaims: dummyTokenClaims,
|
||||
}, nil)
|
||||
u := Standalone{
|
||||
|
||||
Reference in New Issue
Block a user