Skip to content
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

Handle Invalid API Key #3539

Closed
wants to merge 5 commits into from
Closed
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
4 changes: 4 additions & 0 deletions internal/locale/locales/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,10 @@ err_read_projectfile:
other: The activestate.yaml at {{.V0}} could not be read.
err_auth_fail_totp:
other: A two-factor authentication code is required.
err_invalid_token:
other: Invalid API token
err_invalid_credentials:
other: Invalid credentials
cve_title:
other: Vulnerability Summary
cve_description:
Expand Down
9 changes: 9 additions & 0 deletions internal/runners/auth/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package auth

import (
"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/keypairs"
"github.com/ActiveState/cli/internal/locale"
"github.com/ActiveState/cli/internal/output"
Expand Down Expand Up @@ -91,6 +92,14 @@ func (a *Auth) authenticate(params *AuthParams) error {
return auth.AuthenticateWithToken(params.Token, a.Auth)
}

if token := a.Auth.AvailableAPIToken(); token != "" {
err := auth.AuthenticateWithToken(token, a.Auth)
if err != nil {
return errs.Wrap(err, "Failed to authenticate with API key")
}
return nil
}
Comment on lines +95 to +101
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was this added for? This scenario is already handled, afaik.


if params.NonInteractive {
return locale.NewInputError("err_auth_needinput")
}
Expand Down
27 changes: 24 additions & 3 deletions pkg/platform/authentication/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type ErrUnauthorized struct{ *locale.LocalizedError }

type ErrTokenRequired struct{ *locale.LocalizedError }

type ErrInvalidToken struct{ *locale.LocalizedError }

var errNotYetGranted = locale.NewInputError("err_auth_device_noauth")

// jwtLifetime is the lifetime of the JWT. This is defined by the API, but the API doesn't communicate this.
Expand All @@ -45,6 +47,7 @@ type Auth struct {
client *mono_client.Mono
clientAuth *runtime.ClientAuthInfoWriter
bearerToken string
envToken string
user *mono_models.User
cfg Configurable
lastRenewal *time.Time
Expand Down Expand Up @@ -93,6 +96,7 @@ func New(cfg Configurable) *Auth {
auth := &Auth{
cfg: cfg,
jwtLifetime: jwtLifetime,
envToken: os.Getenv(constants.APIKeyEnvVarName),
}

return auth
Expand Down Expand Up @@ -249,6 +253,11 @@ func (s *Auth) AuthenticateWithModel(credentials *mono_models.Credentials) error
return errs.AddTips(&ErrUnauthorized{locale.WrapExternalError(err, "err_unauthorized")}, tips...)
case *apiAuth.PostLoginRetryWith:
return errs.AddTips(&ErrTokenRequired{locale.WrapExternalError(err, "err_auth_fail_totp")}, tips...)
case *apiAuth.PostLoginBadRequest:
if credentials.Token != "" {
return errs.AddTips(&ErrInvalidToken{locale.WrapExternalError(err, "err_invalid_token")}, tips...)
}
return errs.AddTips(locale.WrapExternalError(err, "err_invalid_credentials"), tips...)
default:
if os.IsTimeout(err) {
return locale.NewExternalError("err_api_auth_timeout", "Timed out waiting for authentication response. Please try again.")
Expand Down Expand Up @@ -303,9 +312,20 @@ func (s *Auth) AuthenticateWithDevicePolling(deviceCode strfmt.UUID, interval ti
// AuthenticateWithToken will try to authenticate using the given token
func (s *Auth) AuthenticateWithToken(token string) error {
logging.Debug("AuthenticateWithToken")
return s.AuthenticateWithModel(&mono_models.Credentials{
err := s.AuthenticateWithModel(&mono_models.Credentials{
Token: token,
})
if err != nil {
var invalidTokenErr *ErrInvalidToken
if errors.As(err, &invalidTokenErr) && s.envToken != "" {
logging.Debug("Invalid token, clearing stored token")
s.envToken = ""
return errs.Wrap(err, "Invalid API token")
}
return errs.Wrap(err, "Failed to authenticate with token")
}

return nil
}

// UpdateSession authenticates with the given access token obtained via a Platform
Expand Down Expand Up @@ -464,10 +484,11 @@ func (s *Auth) NewAPIKey(name string) (string, error) {
}

func (s *Auth) AvailableAPIToken() (v string) {
if tkn := os.Getenv(constants.APIKeyEnvVarName); tkn != "" {
if s.envToken != "" {
logging.Debug("Using API token passed via env var")
return tkn
return s.envToken
}

return s.cfg.GetString(ApiTokenConfigKey)
}

Expand Down
Loading