diff --git a/pkg/commands/sso/root.go b/pkg/commands/sso/root.go index 09616b184..1f599d6bb 100644 --- a/pkg/commands/sso/root.go +++ b/pkg/commands/sso/root.go @@ -72,41 +72,6 @@ func NewRootCommand(parent argparser.Registerer, g *global.Data) *RootCommand { func (c *RootCommand) Exec(in io.Reader, out io.Writer) error { profileName, _ := c.identifyProfileAndFlow() - // We need to prompt the user, so they know we're about to open their web - // browser, but we also need to handle the scenario where the `sso` command is - // invoked indirectly via ../../app/run.go as that package will have its own - // (similar) prompt before invoking this command. So to avoid a double prompt, - // the app package will set `SkipAuthPrompt: true`. - if !c.Globals.SkipAuthPrompt && !c.Globals.Flags.AutoYes && !c.Globals.Flags.NonInteractive { - msg := fmt.Sprintf("We're going to authenticate the '%s' profile", profileName) - text.Important(out, "%s. We need to open your browser to authenticate you.", msg) - text.Break(out) - cont, err := text.AskYesNo(out, text.BoldYellow("Do you want to continue? [y/N]: "), in) - text.Break(out) - if err != nil { - return err - } - if !cont { - return fsterr.SkipExitError{ - Skip: true, - Err: fsterr.ErrDontContinue, - } - } - } - - var serverErr error - go func() { - err := c.Globals.AuthServer.Start() - if err != nil { - serverErr = err - } - }() - if serverErr != nil { - return serverErr - } - - text.Info(out, "Starting a local server to handle the authentication flow.") - // For creating/updating a profile we set `prompt` because we want to ensure // that another session (from a different profile) doesn't cause unexpected // errors for the user flow. This forces a re-auth. @@ -122,12 +87,18 @@ func (c *RootCommand) Exec(in io.Reader, out io.Writer) error { c.Globals.AuthServer.SetParam("account_hint", c.ProfileSwitchCustomerID) } default: + if c.profile != "" { + profileName = c.profile + } // Handle `fastly sso` being invoked directly. p := profile.Get(profileName, c.Globals.Config.Profiles) if p == nil { err := fmt.Errorf(profile.DoesNotExist, profileName) c.Globals.ErrLog.Add(err) - return err + return fsterr.RemediationError{ + Inner: err, + Remediation: fsterr.ProfileRemediation, + } } c.Globals.AuthServer.SetParam("prompt", "login") c.Globals.AuthServer.SetParam("login_hint", p.Email) @@ -142,6 +113,45 @@ func (c *RootCommand) Exec(in io.Reader, out io.Writer) error { c.InvokedFromSSO = true } + // We need to prompt the user, so they know we're about to open their web + // browser, but we also need to handle the scenario where the `sso` command is + // invoked indirectly via ../../app/run.go as that package will have its own + // (similar) prompt before invoking this command. So to avoid a double prompt, + // the app package will set `SkipAuthPrompt: true`. + if !c.Globals.SkipAuthPrompt && !c.Globals.Flags.AutoYes && !c.Globals.Flags.NonInteractive { + var defaultMsg string + if c.InvokedFromSSO { + defaultMsg = " and make it the default" + } + msg := fmt.Sprintf("We're going to authenticate the '%s' profile%s", profileName, defaultMsg) + text.Important(out, "%s. We need to open your browser to authenticate you.", msg) + text.Break(out) + cont, err := text.AskYesNo(out, text.BoldYellow("Do you want to continue? [y/N]: "), in) + text.Break(out) + if err != nil { + return err + } + if !cont { + return fsterr.SkipExitError{ + Skip: true, + Err: fsterr.ErrDontContinue, + } + } + } + + var serverErr error + go func() { + err := c.Globals.AuthServer.Start() + if err != nil { + serverErr = err + } + }() + if serverErr != nil { + return serverErr + } + + text.Info(out, "Starting a local server to handle the authentication flow.") + authorizationURL, err := c.Globals.AuthServer.AuthURL() if err != nil { return fsterr.RemediationError{ diff --git a/pkg/commands/sso/sso_test.go b/pkg/commands/sso/sso_test.go index b3ab720ea..d62658b06 100644 --- a/pkg/commands/sso/sso_test.go +++ b/pkg/commands/sso/sso_test.go @@ -87,7 +87,7 @@ func TestSSO(t *testing.T) { TestScenario: testutil.TestScenario{ Args: args("sso"), WantOutputs: []string{ - "We're going to authenticate the 'user' profile.", + "We're going to authenticate the 'user' profile", "We need to open your browser to authenticate you.", "Session token (persisted to your local configuration): 123", }, @@ -108,7 +108,7 @@ func TestSSO(t *testing.T) { TestScenario: testutil.TestScenario{ Args: args("sso test_user"), WantOutputs: []string{ - "We're going to authenticate the 'test_user' profile.", + "We're going to authenticate the 'test_user' profile", "We need to open your browser to authenticate you.", "Session token (persisted to your local configuration): 123", },