Skip to content
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
2 changes: 1 addition & 1 deletion cli/azd/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (la *loginAction) SetupFlags(persistent *pflag.FlagSet, local *pflag.FlagSe
func ensureLoggedIn(ctx context.Context) error {
azCli := commands.GetAzCliFromContext(ctx)
_, err := azCli.GetAccessToken(ctx)
if errors.Is(err, tools.ErrAzCliNotLoggedIn) {
if errors.Is(err, tools.ErrAzCliNotLoggedIn) || errors.Is(err, tools.ErrAzCliRefreshTokenExpired) {
if err := runLogin(ctx, false); err != nil {
Comment thread
weikanglim marked this conversation as resolved.
return fmt.Errorf("logging in: %w", err)
}
Expand Down
13 changes: 7 additions & 6 deletions cli/azd/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ func ensureEnvironmentInitialized(ctx context.Context, environmentName string, e
env.SetEnvName(environmentName)
}

if !hasSubID || !hasPrincipalID || !hasLocation {
if err := ensureLoggedIn(ctx); err != nil {
return fmt.Errorf("logging in: %w", err)
}
}

if !hasLocation {
var location string
location, err := promptLocation(ctx, "Please select an Azure location to use:", askOne)
Expand All @@ -182,12 +188,6 @@ func ensureEnvironmentInitialized(ctx context.Context, environmentName string, e
env.Values[environment.LocationEnvVarName] = strings.TrimSpace(location)
}

if !hasSubID || !hasPrincipalID {
if err := ensureLoggedIn(ctx); err != nil {
return fmt.Errorf("logging in: %w", err)
}
}

azCli := commands.GetAzCliFromContext(ctx)

if !hasSubID {
Expand Down Expand Up @@ -468,6 +468,7 @@ func promptTemplate(ctx context.Context, message string, askOne Asker) (string,
// promptLocation asks the user to select a location from a list of supported azure location
func promptLocation(ctx context.Context, message string, askOne Asker) (string, error) {
azCli := commands.GetAzCliFromContext(ctx)

locations, err := azCli.ListAccountLocations(ctx)
if err != nil {
return "", fmt.Errorf("listing locations: %w", err)
Expand Down
15 changes: 14 additions & 1 deletion cli/azd/pkg/tools/azcli.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import (
)

var (
ErrAzCliNotLoggedIn = errors.New("cli is not logged in")
ErrAzCliNotLoggedIn = errors.New("cli is not logged in. Try running \"azd login\" to fix")
ErrAzCliRefreshTokenExpired = errors.New("refresh token has expired. Try running \"azd login\" to fix")
Comment thread
ellismg marked this conversation as resolved.
ErrCurrentPrincipalIsNotUser = errors.New("current principal is not a user principal")
ErrClientAssertionExpired = errors.New("client assertion expired")
ErrDeploymentNotFound = errors.New("deployment not found")
Expand Down Expand Up @@ -782,6 +783,8 @@ func (cli *azCli) GetAccessToken(ctx context.Context) (AzCliAccessToken, error)
res, err := cli.runAzCommand(ctx, "account", "get-access-token", "--output", "json")
if isNotLoggedInMessage(res.Stderr) {
return AzCliAccessToken{}, ErrAzCliNotLoggedIn
} else if isRefreshTokenExpiredMessage(res.Stderr) {
return AzCliAccessToken{}, ErrAzCliRefreshTokenExpired
} else if err != nil {
return AzCliAccessToken{}, fmt.Errorf("failed running az account get-access-token: %s: %w", res.String(), err)
}
Expand Down Expand Up @@ -900,7 +903,13 @@ func (cli *azCli) runAzCommandWithArgs(ctx context.Context, args executil.RunArg
return cli.runWithResultFn(ctx, args)
}

// Azure Active Directory codes can be referenced via https://login.microsoftonline.com/error?code=<ERROR_CODE>,
// where ERROR_CODE is the digits portion of an AAD error code. Example: AADSTS70043 has error code 70043

var isNotLoggedInMessageRegex = regexp.MustCompile(`Please run ('|")az login('|") to (setup account|access your accounts)\.`)

// AADSTS70043: The refresh token has expired or is invalid due to sign-in frequency checks by conditional access.
var isRefreshTokenExpiredMessageRegex = regexp.MustCompile(`AADSTS70043`)
var isResourceSegmentMeNotFoundMessageRegex = regexp.MustCompile(`Resource not found for the segment 'me'.`)
var isDeploymentNotFoundMessageRegex = regexp.MustCompile(`ERROR: \(DeploymentNotFound\)`)
var isClientAssertionInvalidMessagedRegex = regexp.MustCompile(`ERROR: AADSTS700024: Client assertion is not within its valid time range.`)
Expand All @@ -911,6 +920,10 @@ func isNotLoggedInMessage(s string) bool {
return isNotLoggedInMessageRegex.MatchString(s)
}

func isRefreshTokenExpiredMessage(s string) bool {
return isRefreshTokenExpiredMessageRegex.MatchString(s)
}

func isResourceSegmentMeNotFoundMessage(s string) bool {
return isResourceSegmentMeNotFoundMessageRegex.MatchString(s)
}
Expand Down