From ba706191125bf0fbddd56e533c4f7815c60934f0 Mon Sep 17 00:00:00 2001 From: mitchell Date: Mon, 11 Sep 2023 19:10:12 -0400 Subject: [PATCH 1/2] `state auth signup` sends the user to the signup page instead of the login page. --- internal/runners/auth/signup.go | 2 +- pkg/cmdlets/auth/login.go | 37 ++++++++++++++++++++++++++------- pkg/cmdlets/auth/signup.go | 16 +++++++++++++- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/internal/runners/auth/signup.go b/internal/runners/auth/signup.go index 9d9adad467..1b7e8bb656 100644 --- a/internal/runners/auth/signup.go +++ b/internal/runners/auth/signup.go @@ -30,7 +30,7 @@ func (s *Signup) Run(params *SignupParams) error { } if !params.Prompt { - return authlet.AuthenticateWithBrowser(s.Outputer, s.Auth, s.Prompter) // user can sign up from this page too + return authlet.SignupWithBrowser(s.Outputer, s.Auth, s.Prompter) } return authlet.Signup(s.Configurable, s.Outputer, s.Prompter, s.Auth) } diff --git a/pkg/cmdlets/auth/login.go b/pkg/cmdlets/auth/login.go index 896c1d5a28..9c32358882 100644 --- a/pkg/cmdlets/auth/login.go +++ b/pkg/cmdlets/auth/login.go @@ -1,8 +1,12 @@ package auth import ( + "fmt" + "net/url" + "strings" "time" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/keypairs" "github.com/ActiveState/cli/internal/locale" @@ -121,7 +125,7 @@ func RequireAuthentication(message string, cfg keypairs.Configurable, out output return errs.Wrap(err, "Authenticate failed") } case locale.T("prompt_signup_browser_action"): - if err := AuthenticateWithBrowser(out, auth, prompt); err != nil { // user can sign up from this page too + if err := SignupWithBrowser(out, auth, prompt); err != nil { return errs.Wrap(err, "Signup failed") } case locale.T("prompt_signup_action"): @@ -226,22 +230,41 @@ func promptToken(credentials *mono_models.Credentials, out output.Outputer, prom func AuthenticateWithBrowser(out output.Outputer, auth *authentication.Auth, prompt prompt.Prompter) error { logging.Debug("Authenticating with browser") + err := authenticateWithBrowser(out, auth, prompt, false) + if err != nil { + return errs.Wrap(err, "Error authenticating with browser") + } + + out.Notice(locale.T("auth_device_success")) + + return nil +} + +// authenticateWithBrowser authenticates after signup if applicable. +func authenticateWithBrowser(out output.Outputer, auth *authentication.Auth, prompt prompt.Prompter, signup bool) error { response, err := model.RequestDeviceAuthorization() if err != nil { return locale.WrapError(err, "err_auth_device") } + if response.VerificationURIComplete == nil { + return errs.New("Invalid response: Missing verification URL.") + } + + verificationUrl := *response.VerificationURIComplete + if signup { + baseUrl := strings.TrimPrefix(*response.VerificationURIComplete, "https://"+constants.PlatformURL) + verificationUrl = fmt.Sprintf("%s?nextRoute=%s", constants.PlatformSignupURL, url.QueryEscape(baseUrl)) + } + // Print code to user if response.UserCode == nil { return errs.New("Invalid response: Missing user code.") } - out.Notice(locale.Tr("auth_device_verify_security_code", *response.UserCode, *response.VerificationURIComplete)) + out.Notice(locale.Tr("auth_device_verify_security_code", *response.UserCode, verificationUrl)) // Open URL in browser - if response.VerificationURIComplete == nil { - return errs.New("Invalid response: Missing verification URL.") - } - err = OpenURI(*response.VerificationURIComplete) + err = OpenURI(verificationUrl) if err != nil { logging.Warning("Could not open browser: %v", err) out.Notice(locale.Tr("err_browser_open")) @@ -275,7 +298,5 @@ func AuthenticateWithBrowser(out output.Outputer, auth *authentication.Auth, pro return locale.WrapError(err, "err_auth_token", "Failed to create token after authenticating with browser.") } - out.Notice(locale.T("auth_device_success")) - return nil } diff --git a/pkg/cmdlets/auth/signup.go b/pkg/cmdlets/auth/signup.go index fd25b08838..1ebdf43408 100644 --- a/pkg/cmdlets/auth/signup.go +++ b/pkg/cmdlets/auth/signup.go @@ -1,12 +1,13 @@ package auth import ( + "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/keypairs" "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" "github.com/ActiveState/cli/internal/multilog" "github.com/ActiveState/cli/internal/output" "github.com/ActiveState/cli/internal/prompt" - "github.com/ActiveState/cli/pkg/cmdlets/legalprompt" "github.com/ActiveState/cli/pkg/platform/api" "github.com/ActiveState/cli/pkg/platform/api/mono" @@ -165,3 +166,16 @@ func UsernameValidator(val interface{}) error { } return nil } + +func SignupWithBrowser(out output.Outputer, auth *authentication.Auth, prompt prompt.Prompter) error { + logging.Debug("Signing up with browser") + + err := authenticateWithBrowser(out, auth, prompt, true) + if err != nil { + return errs.Wrap(err, "Error signing up with browser") + } + + out.Notice(locale.Tl("auth_signup_success", "Successfully signed up and authorized this device")) + + return nil +} From 55501ea8b60b2d5b50b646b901bee04410c85650 Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 13 Sep 2023 14:05:50 -0400 Subject: [PATCH 2/2] Use Go's url package to manipulate URLs instead of strings and fmt packages. --- pkg/cmdlets/auth/login.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/pkg/cmdlets/auth/login.go b/pkg/cmdlets/auth/login.go index 9c32358882..8424bd7c1c 100644 --- a/pkg/cmdlets/auth/login.go +++ b/pkg/cmdlets/auth/login.go @@ -1,9 +1,7 @@ package auth import ( - "fmt" "net/url" - "strings" "time" "github.com/ActiveState/cli/internal/constants" @@ -251,20 +249,36 @@ func authenticateWithBrowser(out output.Outputer, auth *authentication.Auth, pro return errs.New("Invalid response: Missing verification URL.") } - verificationUrl := *response.VerificationURIComplete + verificationURL := *response.VerificationURIComplete if signup { - baseUrl := strings.TrimPrefix(*response.VerificationURIComplete, "https://"+constants.PlatformURL) - verificationUrl = fmt.Sprintf("%s?nextRoute=%s", constants.PlatformSignupURL, url.QueryEscape(baseUrl)) + // verificationURL is of the form: + // https://platform.activestate.com/authorize/device?user-code=... + // Transform it to the form: + // https://platform.activestate.com/create-account?nextRoute=%2Fauthorize%2Fdevice%3Fuser-code%3D... + parsedURL, err := url.Parse(verificationURL) + if err != nil { + return errs.Wrap(err, "Verification URL is not valid") + } + + signupURL, err := url.Parse(constants.PlatformSignupURL) + if err != nil { + return errs.Wrap(err, "constants.PlatformSignupURL is not valid") + } + query := signupURL.Query() + query.Add("nextRoute", parsedURL.RequestURI()) + signupURL.RawQuery = query.Encode() + + verificationURL = signupURL.String() } // Print code to user if response.UserCode == nil { return errs.New("Invalid response: Missing user code.") } - out.Notice(locale.Tr("auth_device_verify_security_code", *response.UserCode, verificationUrl)) + out.Notice(locale.Tr("auth_device_verify_security_code", *response.UserCode, verificationURL)) // Open URL in browser - err = OpenURI(verificationUrl) + err = OpenURI(verificationURL) if err != nil { logging.Warning("Could not open browser: %v", err) out.Notice(locale.Tr("err_browser_open"))