From ac0b7dc8cb85de0e3c4072ff5bab524b099a8ac2 Mon Sep 17 00:00:00 2001 From: Bethuel Mmbaga Date: Wed, 23 Aug 2023 21:03:34 +0300 Subject: [PATCH] Enhance linux client authentication (#1093) The change clarifies the message usage, indicating that setup keys can alternatively be used in the authentication process. This approach adds flexibility in scenarios where automated authentication is unachievable, especially in non-desktop Linux environments. --- client/cmd/login.go | 74 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/client/cmd/login.go b/client/cmd/login.go index c61c0a93a..fc0ef82e5 100644 --- a/client/cmd/login.go +++ b/client/cmd/login.go @@ -3,21 +3,21 @@ package cmd import ( "context" "fmt" - "github.com/netbirdio/netbird/client/internal/auth" + "os" + "runtime" "strings" "time" "github.com/skratchdot/open-golang/open" + "github.com/spf13/cobra" "google.golang.org/grpc/codes" gstatus "google.golang.org/grpc/status" - "github.com/netbirdio/netbird/util" - - "github.com/spf13/cobra" - "github.com/netbirdio/netbird/client/internal" + "github.com/netbirdio/netbird/client/internal/auth" "github.com/netbirdio/netbird/client/proto" "github.com/netbirdio/netbird/client/system" + "github.com/netbirdio/netbird/util" ) var loginCmd = &cobra.Command{ @@ -191,17 +191,63 @@ func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *int func openURL(cmd *cobra.Command, verificationURIComplete, userCode string) { var codeMsg string - if userCode != "" { - if !strings.Contains(verificationURIComplete, userCode) { - codeMsg = fmt.Sprintf("and enter the code %s to authenticate.", userCode) + if userCode != "" && !strings.Contains(verificationURIComplete, userCode) { + codeMsg = fmt.Sprintf("and enter the code %s to authenticate.", userCode) + } + + browserAuthMsg := "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 + " " + codeMsg + + setupKeyAuthMsg := "\nAlternatively, you may want to use a setup key, see:\n\n" + + "https://docs.netbird.io/how-to/register-machines-using-setup-keys" + + authenticateUsingBrowser := func() { + cmd.Println(browserAuthMsg) + if err := open.Run(verificationURIComplete); err != nil { + cmd.Println(setupKeyAuthMsg) } } - 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 + " " + codeMsg + " \n\n") - if err != nil { - cmd.Printf("Alternatively, you may want to use a setup key, see:\n\n https://docs.netbird.io/how-to/register-machines-using-setup-keys\n") + switch runtime.GOOS { + case "windows", "darwin": + authenticateUsingBrowser() + case "linux": + if isLinuxRunningDesktop() { + authenticateUsingBrowser() + } else { + // If current flow is PKCE, it implies the server is anticipating the redirect to localhost. + // Devices lacking browser support are incompatible with this flow.Therefore, + // these devices will need to resort to setup keys instead. + if isPKCEFlow(verificationURIComplete) { + cmd.Println("Please proceed with setting up this device using setup keys, see:\n\n" + + "https://docs.netbird.io/how-to/register-machines-using-setup-keys") + } else { + cmd.Println(browserAuthMsg) + } + } } } + +// isLinuxRunningDesktop checks if a Linux OS is running desktop environment. +func isLinuxRunningDesktop() bool { + for _, env := range os.Environ() { + values := strings.Split(env, "=") + if len(values) == 2 { + key, value := values[0], values[1] + if key == "XDG_CURRENT_DESKTOP" && value != "" { + return true + } + } + } + return false +} + +// isPKCEFlow determines if the PKCE flow is active or not, +// by checking the existence of redirect_uri inside the verification URL. +func isPKCEFlow(verificationURL string) bool { + if verificationURL == "" { + return false + } + return strings.Contains(verificationURL, "redirect_uri") +}