Skip to content

CLOUDP-331543: Replace register flow with login flow #4051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/command/atlas-setup.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ atlas setup
:depth: 1
:class: singlecol

Register, authenticate, create, and access an Atlas cluster.
Login, authenticate, create, and access an Atlas cluster.

Public Preview: The atlas api sub-command, automatically generated from the MongoDB Atlas Admin API, offers full coverage of the Admin API and is currently in Public Preview (please provide feedback at https://feedback.mongodb.com/forums/930808-atlas-cli).
Admin API capabilities have their own release lifecycle, which you can check via the provided API endpoint documentation link.



This command takes you through registration, login, default profile creation, creating your first free tier cluster and connecting to it using MongoDB Shell.
This command takes you through login, default profile creation, creating your first free tier cluster and connecting to it using MongoDB Shell.

Syntax
------
Expand Down Expand Up @@ -79,7 +79,7 @@ Options
* - --gov
-
- false
- Register with Atlas for Government.
- Login with Atlas for Government.
* - -h, --help
-
- false
Expand Down
2 changes: 1 addition & 1 deletion docs/command/atlas.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Related Commands
* :ref:`atlas-processes` - Manage MongoDB processes for your project.
* :ref:`atlas-projects` - Manage your Atlas projects.
* :ref:`atlas-security` - Manage security configuration for your project.
* :ref:`atlas-setup` - Register, authenticate, create, and access an Atlas cluster.
* :ref:`atlas-setup` - Login, authenticate, create, and access an Atlas cluster.
* :ref:`atlas-streams` - Manage your Atlas Stream Processing deployments.
* :ref:`atlas-teams` - Manage your Atlas teams.
* :ref:`atlas-users` - Manage your Atlas users.
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func (opts *LoginOpts) handleBrowser(uri string) {
}

if !opts.force {
_, _ = fmt.Fprintf(opts.OutWriter, "\nPress Enter to open the browser to complete authentication...")
_, _ = fmt.Fprintf(opts.OutWriter, "\nPress Enter to open the browser and complete authentication...")
_, _ = fmt.Scanln()
}
if errBrowser := browser.OpenURL(uri); errBrowser != nil {
Expand Down
69 changes: 26 additions & 43 deletions internal/cli/setup/setup_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ type AtlasClusterQuickStarter interface {
type Opts struct {
cli.ProjectOpts
cli.WatchOpts
register auth.RegisterOpts
login auth.LoginOpts
config profileReader
store AtlasClusterQuickStarter
defaultName string
Expand Down Expand Up @@ -164,8 +164,7 @@ type Opts struct {
connectionString string

// control
skipRegister bool
skipLogin bool
skipLogin bool
}

type clusterSettings struct {
Expand Down Expand Up @@ -408,26 +407,18 @@ func (opts *Opts) setupCloseHandler() {
}

func (opts *Opts) Run(ctx context.Context) error {
if !opts.skipRegister {
_, _ = fmt.Fprintf(opts.OutWriter, `
This command will help you:
1. Create and verify your MongoDB Atlas account in your browser.
2. Return to the terminal to create your first free MongoDB database in Atlas.
`)
if err := opts.register.RegisterRun(ctx); err != nil {
return err
}
} else if !opts.skipLogin {
if !opts.skipLogin {
_, _ = fmt.Fprintf(opts.OutWriter, `Next steps:
1. Log in and verify your MongoDB Atlas account in your browser.
2. Return to the terminal to create your first free MongoDB database in Atlas.

If you wish to register a new account, run: 'atlas auth register'.
`)

if err := opts.register.LoginRun(ctx); err != nil {
if err := opts.login.LoginRun(ctx); err != nil {
return err
}
}

if err := opts.clusterPreRun(ctx, opts.OutWriter); err != nil {
return err
}
Expand All @@ -445,8 +436,8 @@ func (opts *Opts) clusterPreRun(ctx context.Context, outWriter io.Writer) error

return opts.PreRunE(
opts.initStore(ctx),
opts.register.SyncWithOAuthAccessProfile(defaultProfile),
opts.register.InitFlow(defaultProfile),
opts.login.SyncWithOAuthAccessProfile(defaultProfile),
opts.login.InitFlow(defaultProfile),
opts.InitOutput(outWriter, ""),
)
}
Expand Down Expand Up @@ -586,7 +577,6 @@ func (opts *Opts) promptConnect() error {
}

func (opts *Opts) PreRun(ctx context.Context) error {
opts.skipRegister = true
opts.skipLogin = true

if err := validate.NoAPIKeys(); err != nil {
Expand All @@ -596,14 +586,14 @@ func (opts *Opts) PreRun(ctx context.Context) error {
// The error is useful in other components that call `validate.NoAPIKeys()`
return nil
}
if err := opts.register.RefreshAccessToken(ctx); err != nil && commonerrors.IsInvalidRefreshToken(err) {
opts.skipLogin = false
return nil
}

// if profile has access token and refresh token is valid, we can skip login
if _, err := auth.AccountWithAccessToken(); err == nil {
return nil
if err := opts.login.RefreshAccessToken(ctx); err != nil && !commonerrors.IsInvalidRefreshToken(err) {
return nil
}
}
opts.skipRegister = false
opts.skipLogin = false
return nil
}

Expand Down Expand Up @@ -669,8 +659,8 @@ func Builder() *cobra.Command {
cmd := &cobra.Command{
Use: "setup",
Aliases: []string{"quickstart"},
Short: "Register, authenticate, create, and access an Atlas cluster.",
Long: `This command takes you through registration, login, default profile creation, creating your first free tier cluster and connecting to it using MongoDB Shell.`,
Short: "Login, authenticate, create, and access an Atlas cluster.",
Long: `This command takes you through login, default profile creation, creating your first free tier cluster and connecting to it using MongoDB Shell.`,
Example: ` # Override default cluster settings like name, provider, or database username by using the command options
atlas setup --clusterName Test --provider GCP --username dbuserTest`,
Hidden: false,
Expand All @@ -679,29 +669,22 @@ func Builder() *cobra.Command {
defaultProfile := config.Default()
opts.config = defaultProfile
opts.OutWriter = cmd.OutOrStdout()
opts.register.OutWriter = opts.OutWriter
opts.login.OutWriter = opts.OutWriter

if err := opts.register.SyncWithOAuthAccessProfile(defaultProfile)(); err != nil {
if err := opts.login.SyncWithOAuthAccessProfile(defaultProfile)(); err != nil {
return err
}
if err := opts.register.InitFlow(defaultProfile)(); err != nil {
if err := opts.login.InitFlow(defaultProfile)(); err != nil {
return err
}
if err := opts.PreRun(cmd.Context()); err != nil {
return nil
}
var preRun []prerun.CmdOpt
// registration pre run if applicable
if !opts.skipRegister {
preRun = append(preRun,
opts.register.LoginPreRun(cmd.Context()),
validate.NoAPIKeys,
validate.NoAccessToken,
)
}

if !opts.skipLogin && opts.skipRegister {
preRun = append(preRun, opts.register.LoginPreRun(cmd.Context()))
// login pre run if applicable
if !opts.skipLogin {
opts.login.Asker = &telemetry.Ask{}
preRun = append(preRun, opts.login.LoginPreRun(cmd.Context()))
}
preRun = append(preRun, opts.validateTier)
preRun = append(preRun, validate.AutoScalingMode(opts.AutoScalingMode))
Expand All @@ -714,9 +697,9 @@ func Builder() *cobra.Command {
},
}

// Register and login related
cmd.Flags().BoolVar(&opts.register.IsGov, "gov", false, "Register with Atlas for Government.")
cmd.Flags().BoolVar(&opts.register.NoBrowser, "noBrowser", false, "Don't try to open a browser session.")
// Login related
cmd.Flags().BoolVar(&opts.login.IsGov, "gov", false, "Login with Atlas for Government.")
cmd.Flags().BoolVar(&opts.login.NoBrowser, "noBrowser", false, "Don't try to open a browser session.")
// Setup related
cmd.Flags().StringVar(&opts.MDBVersion, flag.MDBVersion, "", usage.DeploymentMDBVersion)
cmd.Flags().StringVar(&opts.connectWith, flag.ConnectWith, "", usage.ConnectWithAtlasSetup)
Expand Down
25 changes: 12 additions & 13 deletions internal/cli/setup/setup_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,33 @@ func Test_setupOpts_PreRunWithAPIKeys(t *testing.T) {
opts := &Opts{}

opts.OutWriter = buf
opts.register.WithFlow(mockFlow)
opts.login.WithFlow(mockFlow)

config.SetPublicAPIKey("publicKey")
config.SetPrivateAPIKey("privateKey")

require.NoError(t, opts.PreRun(ctx))

assert.True(t, opts.skipRegister)
assert.Equal(t, 0, buf.Len())
assert.True(t, opts.skipLogin)
t.Cleanup(func() {
config.SetPublicAPIKey("")
config.SetPrivateAPIKey("")
})
}

func Test_setupOpts_RunSkipRegister(t *testing.T) {
func Test_setupOpts_RunSkipLogin(t *testing.T) {
ctrl := gomock.NewController(t)
mockFlow := mocks.NewMockRefresher(ctrl)
ctx := t.Context()
buf := new(bytes.Buffer)

opts := &Opts{
skipLogin: true,
}
opts.register.WithFlow(mockFlow)

config.SetAccessToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ")
opts := &Opts{}
opts.login.WithFlow(mockFlow)

opts.OutWriter = buf
require.NoError(t, opts.PreRun(ctx))
assert.True(t, opts.skipRegister)
assert.False(t, opts.skipLogin)
}

func TestCluster_Run(t *testing.T) {
Expand Down Expand Up @@ -109,7 +108,7 @@ func TestCluster_Run(t *testing.T) {
Tag: map[string]string{"env": "test"},
AutoScalingMode: clusterWideScaling,
}
opts.register.WithFlow(mockFlow)
opts.login.WithFlow(mockFlow)

projectIPAccessList := opts.newProjectIPAccessList()

Expand Down Expand Up @@ -169,7 +168,7 @@ func TestCluster_Run_LatestAPI(t *testing.T) {
Tag: map[string]string{"env": "test"},
AutoScalingMode: "independentShardingScaling",
}
opts.register.WithFlow(mockFlow)
opts.login.WithFlow(mockFlow)

projectIPAccessList := opts.newProjectIPAccessList()

Expand Down Expand Up @@ -237,7 +236,7 @@ func TestCluster_Run_CheckFlagsSet(t *testing.T) {
MDBVersion: "7.0",
AutoScalingMode: clusterWideScaling,
}
opts.register.WithFlow(mockFlow)
opts.login.WithFlow(mockFlow)

projectIPAccessList := opts.newProjectIPAccessList()

Expand Down
Loading