From fea53b2f0ff97485ef5c1ad9090d7afbf6747f76 Mon Sep 17 00:00:00 2001 From: Bethuel Date: Fri, 5 May 2023 13:43:04 +0300 Subject: [PATCH] Fix incomplete verification URI issue in device auth flow (#838) Adds functionality to support Identity Provider (IdP) managers that do not support a complete verification URI in the device authentication flow. In cases where the verification_uri_complete field is empty, the user will be prompted with their user_code, and the verification_uri field will be used as a fallback --- client/cmd/login.go | 14 ++++++++++---- client/cmd/up.go | 2 +- client/internal/oauth.go | 5 +++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/client/cmd/login.go b/client/cmd/login.go index 72ff1e81c..92eb10aef 100644 --- a/client/cmd/login.go +++ b/client/cmd/login.go @@ -3,6 +3,7 @@ package cmd import ( "context" "fmt" + "strings" "time" "github.com/skratchdot/open-golang/open" @@ -106,7 +107,7 @@ var loginCmd = &cobra.Command{ } if loginResp.NeedsSSOLogin { - openURL(cmd, loginResp.VerificationURIComplete) + openURL(cmd, loginResp.VerificationURIComplete, loginResp.UserCode) _, err = client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode}) if err != nil { @@ -185,7 +186,7 @@ func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *int return nil, fmt.Errorf("getting a request device code failed: %v", err) } - openURL(cmd, flowInfo.VerificationURIComplete) + openURL(cmd, flowInfo.VerificationURIComplete, flowInfo.UserCode) waitTimeout := time.Duration(flowInfo.ExpiresIn) waitCTX, c := context.WithTimeout(context.TODO(), waitTimeout*time.Second) @@ -199,11 +200,16 @@ func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *int return &tokenInfo, nil } -func openURL(cmd *cobra.Command, verificationURIComplete string) { +func openURL(cmd *cobra.Command, verificationURIComplete, userCode string) { + var codeMsg string + if !strings.Contains(verificationURIComplete, userCode) { + codeMsg = fmt.Sprintf("and enter the code %s to authenticate.", userCode) + } + err := open.Run(verificationURIComplete) cmd.Printf("Please do the SSO login in your browser. \n" + "If your browser didn't open automatically, use this URL to log in:\n\n" + - " " + verificationURIComplete + " \n\n") + " " + verificationURIComplete + " " + codeMsg + " \n\n") if err != nil { cmd.Printf("Alternatively, you may want to use a setup key, see:\n\n https://www.netbird.io/docs/overview/setup-keys\n") } diff --git a/client/cmd/up.go b/client/cmd/up.go index 7adbe5054..c03e290b0 100644 --- a/client/cmd/up.go +++ b/client/cmd/up.go @@ -172,7 +172,7 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command) error { if loginResp.NeedsSSOLogin { - openURL(cmd, loginResp.VerificationURIComplete) + openURL(cmd, loginResp.VerificationURIComplete, loginResp.UserCode) _, err = client.WaitSSOLogin(ctx, &proto.WaitSSOLoginRequest{UserCode: loginResp.UserCode}) if err != nil { diff --git a/client/internal/oauth.go b/client/internal/oauth.go index 2d237925d..f8b8b8adb 100644 --- a/client/internal/oauth.go +++ b/client/internal/oauth.go @@ -148,6 +148,11 @@ func (h *Hosted) RequestDeviceCode(ctx context.Context) (DeviceAuthInfo, error) return DeviceAuthInfo{}, fmt.Errorf("unmarshaling response failed with error: %v", err) } + // Fallback to the verification_uri if the IdP doesn't support verification_uri_complete + if deviceCode.VerificationURIComplete == "" { + deviceCode.VerificationURIComplete = deviceCode.VerificationURI + } + return deviceCode, err }