diff --git a/cli/azd/cmd/auth_login.go b/cli/azd/cmd/auth_login.go index 69d5b2e4648..49dbba55c69 100644 --- a/cli/azd/cmd/auth_login.go +++ b/cli/azd/cmd/auth_login.go @@ -288,6 +288,34 @@ func newLoginAction( } func (la *loginAction) Run(ctx context.Context) (*actions.ActionResult, error) { + loginMode, err := la.authManager.Mode() + if err != nil { + return nil, err + } + if loginMode != auth.AzdBuiltIn { + la.console.MessageUxItem(ctx, &ux.WarningAltMessage{ + Message: fmt.Sprintf( + "Azd is not using the built-in authentication mode, but rather '%s'", loginMode), + }) + la.console.Message(ctx, "If you want to use 'azd auth login', you need to disable the current auth mode.") + response, err := la.console.Confirm(ctx, input.ConsoleOptions{ + Message: "Do you want to switch back to azd built-in authentication?", + DefaultValue: false, + Help: "Azd supports multiple authentication modes, including Azure CLI authentication and External " + + "request for Auth. Switching back to azd built-in authentication will try to disable the current mode.", + }) + if err != nil { + return nil, err + } + if !response { + return nil, fmt.Errorf("log in is not supported on current mode: %s", loginMode) + } + if err := la.authManager.SetBuiltInAuthMode(); err != nil { + return nil, fmt.Errorf("setting auth mode: %w", err) + } + la.console.Message(ctx, "Authentication mode set to azd built-in. Continuing login...") + } + if len(la.flags.scopes) == 0 { la.flags.scopes = la.authManager.LoginScopes() } diff --git a/cli/azd/pkg/auth/manager.go b/cli/azd/pkg/auth/manager.go index 1cfcf1073fe..de2e00fcd0b 100644 --- a/cli/azd/pkg/auth/manager.go +++ b/cli/azd/pkg/auth/manager.go @@ -1409,3 +1409,67 @@ func (m *Manager) LogInDetails(ctx context.Context) (*LogInDetails, error) { return nil, ErrNoCurrentUser } + +type AuthMode string + +const ( + AzdBuiltIn AuthMode = "azd built in" + AzDelegated AuthMode = "delegated to az cli" + ExternalRequest AuthMode = "external token request" +) + +func (m *Manager) Mode() (AuthMode, error) { + // Check external + if m.UseExternalAuth() { + return ExternalRequest, nil + } + + // check az delegation + cfg, err := m.userConfigManager.Load() + if err != nil { + return "", fmt.Errorf("fetching current user: %w", err) + } + + if shouldUseLegacyAuth(cfg) { + return AzDelegated, nil + } + + // default to azd + return AzdBuiltIn, nil +} + +func (m *Manager) SetBuiltInAuthMode() error { + currentMode, err := m.Mode() + if err != nil { + return fmt.Errorf("fetching current auth mode: %w", err) + } + if currentMode == AzdBuiltIn { + return nil + } + + if currentMode == ExternalRequest { + return fmt.Errorf("cannot change auth mode when external token mode is set. See %s", + "https://github.com/Azure/azure-dev/blob/main/cli/azd/docs/external-authentication.md") + } + + // protecting against unexpected modes. There should be only azDelegated left. + if currentMode != AzDelegated { + return fmt.Errorf("Unexpected mode found: %s", currentMode) + } + + // Unset the useAzCliAuthKey flag + cfg, err := m.userConfigManager.Load() + if err != nil { + return fmt.Errorf("reading user config: %w", err) + } + + if err := cfg.Unset(useAzCliAuthKey); err != nil { + return fmt.Errorf("unsetting %s: %w", useAzCliAuthKey, err) + } + + if err := m.userConfigManager.Save(cfg); err != nil { + return fmt.Errorf("saving user config: %w", err) + } + + return nil +}