Refactor and rename ./internal/oidcclient/login to ./internal/oidcclient.
This commit is contained in:
parent
4ef41f969d
commit
7f6a82aa91
@ -10,15 +10,15 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
|
||||
"go.pinniped.dev/internal/oidcclient/login"
|
||||
"go.pinniped.dev/internal/oidcclient"
|
||||
)
|
||||
|
||||
//nolint: gochecknoinits
|
||||
func init() {
|
||||
loginCmd.AddCommand(oidcLoginCommand(login.Run))
|
||||
loginCmd.AddCommand(oidcLoginCommand(oidcclient.Login))
|
||||
}
|
||||
|
||||
func oidcLoginCommand(loginFunc func(issuer string, clientID string, opts ...login.Option) (*login.Token, error)) *cobra.Command {
|
||||
func oidcLoginCommand(loginFunc func(issuer string, clientID string, opts ...oidcclient.Option) (*oidcclient.Token, error)) *cobra.Command {
|
||||
var (
|
||||
cmd = cobra.Command{
|
||||
Args: cobra.NoArgs,
|
||||
@ -40,18 +40,18 @@ func oidcLoginCommand(loginFunc func(issuer string, clientID string, opts ...log
|
||||
mustMarkRequired(&cmd, "issuer", "client-id")
|
||||
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
opts := []login.Option{
|
||||
login.WithContext(cmd.Context()),
|
||||
login.WithScopes(scopes),
|
||||
opts := []oidcclient.Option{
|
||||
oidcclient.WithContext(cmd.Context()),
|
||||
oidcclient.WithScopes(scopes),
|
||||
}
|
||||
|
||||
if listenPort != 0 {
|
||||
opts = append(opts, login.WithListenPort(listenPort))
|
||||
opts = append(opts, oidcclient.WithListenPort(listenPort))
|
||||
}
|
||||
|
||||
// --skip-browser replaces the default "browser open" function with one that prints to stderr.
|
||||
if skipBrowser {
|
||||
opts = append(opts, login.WithBrowserOpen(func(url string) error {
|
||||
opts = append(opts, oidcclient.WithBrowserOpen(func(url string) error {
|
||||
cmd.PrintErr("Please log in: ", url, "\n")
|
||||
return nil
|
||||
}))
|
||||
@ -69,8 +69,8 @@ func oidcLoginCommand(loginFunc func(issuer string, clientID string, opts ...log
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
},
|
||||
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
|
||||
ExpirationTimestamp: &metav1.Time{Time: tok.IDTokenExpiry},
|
||||
Token: tok.IDToken,
|
||||
ExpirationTimestamp: &tok.IDToken.Expiry,
|
||||
Token: tok.IDToken.Token,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -9,9 +9,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/oidcclient/login"
|
||||
"go.pinniped.dev/internal/oidcclient"
|
||||
)
|
||||
|
||||
func TestLoginOIDCCommand(t *testing.T) {
|
||||
@ -87,13 +88,18 @@ func TestLoginOIDCCommand(t *testing.T) {
|
||||
var (
|
||||
gotIssuer string
|
||||
gotClientID string
|
||||
gotOptions []login.Option
|
||||
gotOptions []oidcclient.Option
|
||||
)
|
||||
cmd := oidcLoginCommand(func(issuer string, clientID string, opts ...login.Option) (*login.Token, error) {
|
||||
cmd := oidcLoginCommand(func(issuer string, clientID string, opts ...oidcclient.Option) (*oidcclient.Token, error) {
|
||||
gotIssuer = issuer
|
||||
gotClientID = clientID
|
||||
gotOptions = opts
|
||||
return &login.Token{IDToken: "test-id-token", IDTokenExpiry: time1}, nil
|
||||
return &oidcclient.Token{
|
||||
IDToken: &oidcclient.IDToken{
|
||||
Token: "test-id-token",
|
||||
Expiry: metav1.NewTime(time1),
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package login implements a CLI OIDC login flow.
|
||||
package login
|
||||
// Package oidcclient implements a CLI OIDC login flow.
|
||||
package oidcclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/pkg/browser"
|
||||
"golang.org/x/oauth2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.pinniped.dev/internal/httputil/httperr"
|
||||
"go.pinniped.dev/internal/httputil/securityheader"
|
||||
@ -55,13 +56,7 @@ type callbackResult struct {
|
||||
err error
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
*oauth2.Token
|
||||
IDToken string `json:"id_token"`
|
||||
IDTokenExpiry time.Time `json:"id_token_expiry"`
|
||||
}
|
||||
|
||||
// Option is an optional configuration for Run().
|
||||
// Option is an optional configuration for Login().
|
||||
type Option func(*handlerState) error
|
||||
|
||||
// WithContext specifies a specific context.Context under which to perform the login. If this option is not specified,
|
||||
@ -105,8 +100,8 @@ func WithBrowserOpen(openURL func(url string) error) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Run an OAuth2/OIDC authorization code login using a localhost listener.
|
||||
func Run(issuer string, clientID string, opts ...Option) (*Token, error) {
|
||||
// Login performs an OAuth2/OIDC authorization code login using a localhost listener.
|
||||
func Login(issuer string, clientID string, opts ...Option) (*Token, error) {
|
||||
h := handlerState{
|
||||
issuer: issuer,
|
||||
clientID: clientID,
|
||||
@ -262,9 +257,18 @@ func (h *handlerState) handleAuthCodeCallback(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
|
||||
h.callbacks <- callbackResult{token: &Token{
|
||||
Token: oauth2Tok,
|
||||
IDToken: idTok,
|
||||
IDTokenExpiry: validated.Expiry,
|
||||
AccessToken: &AccessToken{
|
||||
Token: oauth2Tok.AccessToken,
|
||||
Type: oauth2Tok.TokenType,
|
||||
Expiry: metav1.NewTime(oauth2Tok.Expiry),
|
||||
},
|
||||
RefreshToken: &RefreshToken{
|
||||
Token: oauth2Tok.RefreshToken,
|
||||
},
|
||||
IDToken: &IDToken{
|
||||
Token: idTok,
|
||||
Expiry: metav1.NewTime(validated.Expiry),
|
||||
},
|
||||
}}
|
||||
_, _ = w.Write([]byte("you have been logged in and may now close this tab"))
|
||||
return nil
|
@ -1,7 +1,7 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package login
|
||||
package oidcclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.pinniped.dev/internal/httputil/httperr"
|
||||
"go.pinniped.dev/internal/mocks/mockkeyset"
|
||||
@ -26,18 +27,21 @@ import (
|
||||
"go.pinniped.dev/internal/oidcclient/state"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
func TestLogin(t *testing.T) {
|
||||
time1 := time.Date(3020, 10, 12, 13, 14, 15, 16, time.UTC)
|
||||
testToken := Token{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "test-access-token",
|
||||
RefreshToken: "test-refresh-token",
|
||||
Expiry: time1.Add(1 * time.Minute),
|
||||
AccessToken: &AccessToken{
|
||||
Token: "test-access-token",
|
||||
Expiry: metav1.NewTime(time1.Add(1 * time.Minute)),
|
||||
},
|
||||
RefreshToken: &RefreshToken{
|
||||
Token: "test-refresh-token",
|
||||
},
|
||||
IDToken: &IDToken{
|
||||
Token: "test-id-token",
|
||||
Expiry: metav1.NewTime(time1.Add(2 * time.Minute)),
|
||||
},
|
||||
IDToken: "test-id-token",
|
||||
IDTokenExpiry: time1.Add(2 * time.Minute),
|
||||
}
|
||||
_ = testToken
|
||||
|
||||
// Start a test server that returns 500 errors
|
||||
errorServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -223,7 +227,7 @@ func TestRun(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tok, err := Run(tt.issuer, tt.clientID,
|
||||
tok, err := Login(tt.issuer, tt.clientID,
|
||||
WithContext(context.Background()),
|
||||
WithListenPort(0),
|
||||
WithScopes([]string{"test-scope"}),
|
||||
@ -393,7 +397,7 @@ func TestHandleAuthCodeCallback(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, result.err)
|
||||
require.NotNil(t, result.token)
|
||||
require.Equal(t, result.token.IDToken, tt.returnIDTok)
|
||||
require.Equal(t, result.token.IDToken.Token, tt.returnIDTok)
|
||||
}
|
||||
})
|
||||
}
|
49
internal/oidcclient/types.go
Normal file
49
internal/oidcclient/types.go
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidcclient
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// AccessToken is an OAuth2 access token.
|
||||
type AccessToken struct {
|
||||
// Token is the token that authorizes and authenticates the requests.
|
||||
Token string `json:"token"`
|
||||
|
||||
// Type is the type of token.
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
// Expiry is the optional expiration time of the access token.
|
||||
Expiry metav1.Time `json:"expiryTimestamp,omitempty"`
|
||||
}
|
||||
|
||||
// RefreshToken is an OAuth2 refresh token.
|
||||
type RefreshToken struct {
|
||||
// Token is a token that's used by the application (as opposed to the user) to refresh the access token if it expires.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// IDToken is an OpenID Connect ID token.
|
||||
type IDToken struct {
|
||||
// Token is an OpenID Connect ID token.
|
||||
Token string `json:"token"`
|
||||
|
||||
// Expiry is the optional expiration time of the ID token.
|
||||
Expiry metav1.Time `json:"expiryTimestamp,omitempty"`
|
||||
}
|
||||
|
||||
// Token contains the elements of an OIDC session.
|
||||
type Token struct {
|
||||
// AccessToken is the token that authorizes and authenticates the requests.
|
||||
AccessToken *AccessToken `json:"access,omitempty"`
|
||||
|
||||
// RefreshToken is a token that's used by the application
|
||||
// (as opposed to the user) to refresh the access token
|
||||
// if it expires.
|
||||
RefreshToken *RefreshToken `json:"refresh,omitempty"`
|
||||
|
||||
// IDToken is an OpenID Connect ID token.
|
||||
IDToken *IDToken `json:"id,omitempty"`
|
||||
}
|
Loading…
Reference in New Issue
Block a user