Files
kubelogin/pkg/usecases/authentication/devicecode/devicecode.go

68 lines
1.9 KiB
Go

package devicecode
import (
"context"
"fmt"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client"
)
type Option struct {
SkipOpenBrowser bool
BrowserCommand string
}
// DeviceCode provides the oauth2 device code flow.
type DeviceCode struct {
Browser browser.Interface
Logger logger.Interface
}
func (u *DeviceCode) Do(ctx context.Context, in *Option, oidcClient client.Interface) (*oidc.TokenSet, error) {
u.Logger.V(1).Infof("starting the oauth2 device code flow")
authResponse, err := oidcClient.GetDeviceAuthorization(ctx)
if err != nil {
return nil, err
}
if authResponse.VerificationURIComplete == "" {
u.Logger.Printf("Please enter the following code when asked in your browser: %s", authResponse.UserCode)
u.openURL(ctx, in, authResponse.VerificationURI)
} else {
u.openURL(ctx, in, authResponse.VerificationURIComplete)
}
tokenSet, err := oidcClient.ExchangeDeviceCode(ctx, authResponse)
u.Logger.V(1).Infof("finished the oauth2 device code flow")
if err != nil {
return nil, fmt.Errorf("unable to exchange device code: %w", err)
}
return tokenSet, nil
}
func (u *DeviceCode) openURL(ctx context.Context, o *Option, url string) {
if o != nil && o.SkipOpenBrowser {
u.Logger.Printf("Please visit the following URL in your browser: %s", url)
return
}
u.Logger.V(1).Infof("opening %s in the browser", url)
if o != nil && o.BrowserCommand != "" {
if err := u.Browser.OpenCommand(ctx, url, o.BrowserCommand); err != nil {
u.Logger.Printf(`error: could not open the browser: %s
Please visit the following URL in your browser manually: %s`, err, url)
}
return
}
if err := u.Browser.Open(url); err != nil {
u.Logger.Printf(`error: could not open the browser: %s
Please visit the following URL in your browser manually: %s`, err, url)
}
}