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

Add error msg if API Token is expired #1634

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
17 changes: 11 additions & 6 deletions cmd/cloud/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ import (
)

var (
authLogin = auth.Login
defaultDomain = "astronomer.io"
client = httputil.NewHTTPClient()
isDeploymentFile = false
parseAPIToken = util.ParseAPIToken
errNotAPIToken = errors.New("the API token given does not appear to be an Astro API Token")
authLogin = auth.Login
defaultDomain = "astronomer.io"
client = httputil.NewHTTPClient()
isDeploymentFile = false
parseAPIToken = util.ParseAPIToken
errNotAPIToken = errors.New("the API token given does not appear to be an Astro API Token")
errExpiredAPIToken = errors.New("the API token given has expired")
)

const (
Expand Down Expand Up @@ -407,6 +408,10 @@ func checkAPIToken(isDeploymentFile bool, platformCoreClient astroplatformcore.C
if len(claims.Permissions) == 0 {
return false, errNotAPIToken
}
if claims.ExpiresAt.Before(time.Now()) {
fmt.Printf("The given API Token %s has expired", claims.APITokenID)
ichung08 marked this conversation as resolved.
Show resolved Hide resolved
return false, errExpiredAPIToken
}

var wsID, orgID string
for _, permission := range claims.Permissions {
Expand Down
75 changes: 66 additions & 9 deletions cmd/cloud/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package cloud
import (
"bytes"
"encoding/json"
"github.com/golang-jwt/jwt/v4"
"io"
"net/http"
"testing"
"time"

astroplatformcore "github.com/astronomer/astro-cli/astro-client-platform-core"
"github.com/astronomer/astro-cli/config"
Expand Down Expand Up @@ -328,6 +330,8 @@ func TestCheckToken(t *testing.T) {
}

func TestCheckAPIToken(t *testing.T) {
var mockClaims util.CustomClaims
var permissions []string
testUtil.InitTestConfig(testUtil.LocalPlatform)
mockOrgsResponse := astroplatformcore.ListOrganizationsResponse{
HTTPResponse: &http.Response{
Expand All @@ -339,14 +343,59 @@ func TestCheckAPIToken(t *testing.T) {
},
},
}
permissions = []string{
"workspaceId:workspace-id",
"organizationId:org-ID",
}
mockClaims = util.CustomClaims{
Permissions: permissions,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: "test-issuer",
Subject: "test-subject",
Audience: jwt.ClaimStrings{"audience1", "audience2"}, // Audience can be a single string or an array of strings
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // Set expiration date 24 hours from now
NotBefore: jwt.NewNumericDate(time.Now()), // Set not before to current time
IssuedAt: jwt.NewNumericDate(time.Now()), // Set issued at to current time
ID: "your-id",
},
}

t.Run("test context switch", func(t *testing.T) {
permissions := []string{
"workspaceId:workspace-id",
"organizationId:org-ID",
authLogin = func(domain, token string, coreClient astrocore.CoreClient, platformCoreClient astroplatformcore.CoreClient, out io.Writer, shouldDisplayLoginLink bool) error {
return nil
}

parseAPIToken = func(astroAPIToken string) (*util.CustomClaims, error) {
return &mockClaims, nil
}
mockClaims := util.CustomClaims{

mockPlatformCoreClient.On("ListOrganizationsWithResponse", mock.Anything, &astroplatformcore.ListOrganizationsParams{}).Return(&mockOrgsResponse, nil).Once()

t.Setenv("ASTRO_API_TOKEN", "token")

// Switch context
domain := "astronomer-dev.io"
err := context.Switch(domain)
assert.NoError(t, err)

// run CheckAPIKeys
_, err = checkAPIToken(true, mockPlatformCoreClient)
assert.NoError(t, err)
})

t.Run("bad claims", func(t *testing.T) {
permissions = []string{}
mockClaims = util.CustomClaims{
Permissions: permissions,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: "test-issuer",
Subject: "test-subject",
Audience: jwt.ClaimStrings{"audience1", "audience2"},
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: "test-id",
},
}

authLogin = func(domain, token string, coreClient astrocore.CoreClient, platformCoreClient astroplatformcore.CoreClient, out io.Writer, shouldDisplayLoginLink bool) error {
Expand All @@ -368,13 +417,21 @@ func TestCheckAPIToken(t *testing.T) {

// run CheckAPIKeys
_, err = checkAPIToken(true, mockPlatformCoreClient)
assert.NoError(t, err)
assert.ErrorIs(t, err, errNotAPIToken)
})

t.Run("bad claims", func(t *testing.T) {
permissions := []string{}
mockClaims := util.CustomClaims{
t.Run("expired token", func(t *testing.T) {
mockClaims = util.CustomClaims{
Permissions: permissions,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: "test-issuer",
Subject: "test-subject",
Audience: jwt.ClaimStrings{"audience1", "audience2"},
ExpiresAt: jwt.NewNumericDate(time.Now().Add(-1 * time.Hour)),
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: "test-id",
},
}

authLogin = func(domain, token string, coreClient astrocore.CoreClient, platformCoreClient astroplatformcore.CoreClient, out io.Writer, shouldDisplayLoginLink bool) error {
Expand All @@ -396,6 +453,6 @@ func TestCheckAPIToken(t *testing.T) {

// run CheckAPIKeys
_, err = checkAPIToken(true, mockPlatformCoreClient)
assert.ErrorIs(t, err, errNotAPIToken)
assert.ErrorIs(t, err, errExpiredAPIToken)
})
}