func (c *registerCommand) run(ctx *cmd.Context) error { store := modelcmd.QualifyingClientStore{c.store} registrationParams, err := c.getParameters(ctx, store) if err != nil { return errors.Trace(err) } controllerDetails, accountDetails, err := c.controllerDetails(ctx, registrationParams) if err != nil { return errors.Trace(err) } controllerName, err := c.updateController( ctx, store, registrationParams.defaultControllerName, controllerDetails, accountDetails, ) if err != nil { return errors.Trace(err) } // Log into the controller to verify the credentials, and // list the models available. models, err := c.listModelsFunc(store, controllerName, accountDetails.User) if err != nil { return errors.Trace(err) } for _, model := range models { owner := names.NewUserTag(model.Owner) if err := store.UpdateModel( controllerName, jujuclient.JoinOwnerModelName(owner, model.Name), jujuclient.ModelDetails{model.UUID}, ); err != nil { return errors.Annotate(err, "storing model details") } } if err := store.SetCurrentController(controllerName); err != nil { return errors.Trace(err) } fmt.Fprintf( ctx.Stderr, "\nWelcome, %s. You are now logged into %q.\n", friendlyUserName(accountDetails.User), controllerName, ) return c.maybeSetCurrentModel(ctx, store, controllerName, accountDetails.User, models) }
func (c *registerCommand) Run(ctx *cmd.Context) error { store := modelcmd.QualifyingClientStore{c.store} registrationParams, err := c.getParameters(ctx, store) if err != nil { return errors.Trace(err) } _, err = store.ControllerByName(registrationParams.controllerName) if err == nil { return errors.AlreadyExistsf("controller %q", registrationParams.controllerName) } else if !errors.IsNotFound(err) { return errors.Trace(err) } // During registration we must set a new password. This has to be done // atomically with the clearing of the secret key. payloadBytes, err := json.Marshal(params.SecretKeyLoginRequestPayload{ registrationParams.newPassword, }) if err != nil { return errors.Trace(err) } // Make the registration call. If this is successful, the client's // cookie jar will be populated with a macaroon that may be used // to log in below without the user having to type in the password // again. req := params.SecretKeyLoginRequest{ Nonce: registrationParams.nonce[:], User: registrationParams.userTag.String(), PayloadCiphertext: secretbox.Seal( nil, payloadBytes, ®istrationParams.nonce, ®istrationParams.key, ), } resp, err := c.secretKeyLogin(registrationParams.controllerAddrs, req) if err != nil { return errors.Trace(err) } // Decrypt the response to authenticate the controller and // obtain its CA certificate. if len(resp.Nonce) != len(registrationParams.nonce) { return errors.NotValidf("response nonce") } var respNonce [24]byte copy(respNonce[:], resp.Nonce) payloadBytes, ok := secretbox.Open(nil, resp.PayloadCiphertext, &respNonce, ®istrationParams.key) if !ok { return errors.NotValidf("response payload") } var responsePayload params.SecretKeyLoginResponsePayload if err := json.Unmarshal(payloadBytes, &responsePayload); err != nil { return errors.Annotate(err, "unmarshalling response payload") } // Store the controller and account details. controllerDetails := jujuclient.ControllerDetails{ APIEndpoints: registrationParams.controllerAddrs, ControllerUUID: responsePayload.ControllerUUID, CACert: responsePayload.CACert, } if err := store.AddController(registrationParams.controllerName, controllerDetails); err != nil { return errors.Trace(err) } accountDetails := jujuclient.AccountDetails{ User: registrationParams.userTag.Canonical(), LastKnownAccess: string(permission.LoginAccess), } if err := store.UpdateAccount(registrationParams.controllerName, accountDetails); err != nil { return errors.Trace(err) } // Log into the controller to verify the credentials, and // list the models available. models, err := c.listModelsFunc(store, registrationParams.controllerName, accountDetails.User) if err != nil { return errors.Trace(err) } for _, model := range models { owner := names.NewUserTag(model.Owner) if err := store.UpdateModel( registrationParams.controllerName, jujuclient.JoinOwnerModelName(owner, model.Name), jujuclient.ModelDetails{model.UUID}, ); err != nil { return errors.Annotate(err, "storing model details") } } if err := store.SetCurrentController(registrationParams.controllerName); err != nil { return errors.Trace(err) } fmt.Fprintf( ctx.Stderr, "\nWelcome, %s. You are now logged into %q.\n", registrationParams.userTag.Id(), registrationParams.controllerName, ) return c.maybeSetCurrentModel(ctx, store, registrationParams.controllerName, accountDetails.User, models) }