Skip to content

Commit ce82b9c

Browse files
authored
[envsec] Ensure id token is refreshed (#166)
## Summary * Ensure refresh updates id token, previously it was only updating access token. * Changed GetSession and a few internal functions to return errors instead of just swallowing it up. ## How was it tested? ``` envsec auth logout envsec auth whoami envsec auth login envsec auth whoami envsec auth refresh # inspected id token to ensure it was refreshed ```
1 parent 9513156 commit ce82b9c

File tree

5 files changed

+39
-65
lines changed

5 files changed

+39
-65
lines changed

envsec/internal/envcli/auth.go

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package envcli
66
import (
77
"fmt"
88

9-
"github.com/pkg/errors"
109
"github.com/spf13/cobra"
1110
"go.jetpack.io/envsec/internal/envvar"
1211
"go.jetpack.io/pkg/sandbox/auth"
@@ -20,7 +19,6 @@ func authCmd() *cobra.Command {
2019

2120
cmd.AddCommand(loginCmd())
2221
cmd.AddCommand(logoutCmd())
23-
cmd.AddCommand(refreshCmd())
2422
cmd.AddCommand(whoAmICmd())
2523

2624
return cmd
@@ -70,31 +68,6 @@ func logoutCmd() *cobra.Command {
7068
return cmd
7169
}
7270

73-
// This is for debugging purposes only. Hidden.
74-
func refreshCmd() *cobra.Command {
75-
cmd := &cobra.Command{
76-
Use: "refresh",
77-
Short: "Refresh credentials",
78-
Args: cobra.ExactArgs(0),
79-
Hidden: true,
80-
RunE: func(cmd *cobra.Command, args []string) error {
81-
client, err := newAuthClient()
82-
if err != nil {
83-
return err
84-
}
85-
86-
_, ok := client.GetSession(cmd.Context())
87-
if !ok {
88-
return errors.New("Failed to refresh: not logged in. Run `envsec auth login` to log in")
89-
}
90-
fmt.Fprintln(cmd.OutOrStdout(), "Refreshed successfully")
91-
return nil
92-
},
93-
}
94-
95-
return cmd
96-
}
97-
9871
type whoAmICmdFlags struct {
9972
showTokens bool
10073
}
@@ -111,9 +84,9 @@ func whoAmICmd() *cobra.Command {
11184
return err
11285
}
11386

114-
tok, ok := client.GetSession(cmd.Context())
115-
if !ok {
116-
return errors.New("not logged in. Run `envsec auth login` to log in")
87+
tok, err := client.GetSession(cmd.Context())
88+
if err != nil {
89+
return fmt.Errorf("error: %w. Run `envsec auth login` to log in", err)
11790
}
11891
idClaims := tok.IDClaims()
11992

@@ -136,7 +109,6 @@ func whoAmICmd() *cobra.Command {
136109
fmt.Fprintf(cmd.OutOrStdout(), "Access Token: %s\n", tok.AccessToken)
137110
fmt.Fprintf(cmd.OutOrStdout(), "ID Token: %s\n", tok.IDToken)
138111
fmt.Fprintf(cmd.OutOrStdout(), "Refresh Token: %s\n", tok.RefreshToken)
139-
140112
}
141113

142114
return nil

envsec/internal/envcli/flags.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package envcli
55

66
import (
77
"context"
8+
"fmt"
89
"os"
910

1011
"github.com/pkg/errors"
@@ -56,8 +57,8 @@ func (f *configFlags) validateProjectID(orgID typeids.OrganizationID) (string, e
5657
}
5758
config, err := jetcloud.ProjectConfig(wd)
5859
if errors.Is(err, os.ErrNotExist) {
59-
return "", errors.Errorf(
60-
"Project ID not specified. You must run `envsec init` or specify --project-id in this directory",
60+
return "", fmt.Errorf(
61+
"project ID not specified. You must run `envsec init` or specify --project-id in this directory",
6162
)
6263
} else if err != nil {
6364
return "", errors.WithStack(err)
@@ -81,7 +82,6 @@ type cmdConfig struct {
8182

8283
func (f *configFlags) genConfig(ctx context.Context) (*cmdConfig, error) {
8384
var tok *session.Token
84-
var ok bool
8585
var err error
8686

8787
if f.orgID == "" {
@@ -90,10 +90,11 @@ func (f *configFlags) genConfig(ctx context.Context) (*cmdConfig, error) {
9090
return nil, err
9191
}
9292

93-
tok, ok = client.GetSession(ctx)
94-
if !ok {
95-
return nil, errors.Errorf(
96-
"To use envsec you must log in (`envsec auth login`) or specify --project-id and --org-id",
93+
tok, err = client.GetSession(ctx)
94+
if err != nil {
95+
return nil, fmt.Errorf(
96+
"error: %w. To use envsec you must log in (`envsec auth login`) or specify --project-id and --org-id",
97+
err,
9798
)
9899
}
99100
}

envsec/internal/envcli/init.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ func initCmd() *cobra.Command {
1919
if err != nil {
2020
return err
2121
}
22-
tok, ok := client.GetSession(cmd.Context())
23-
if !ok {
24-
return errors.New("not logged in, run `envsec auth login`")
22+
tok, err := client.GetSession(cmd.Context())
23+
if err != nil {
24+
return fmt.Errorf("error: %w, run `envsec auth login`", err)
2525
}
2626

2727
wd, err := os.Getwd()

pkg/sandbox/auth/auth.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package auth
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"os"
78
"path/filepath"
@@ -15,6 +16,8 @@ import (
1516
"go.jetpack.io/pkg/sandbox/auth/internal/tokenstore"
1617
)
1718

19+
var ErrNotLoggedIn = fmt.Errorf("not logged in")
20+
1821
type Client struct {
1922
issuer string
2023
clientID string
@@ -58,40 +61,37 @@ func (c *Client) LogoutFlow() error {
5861
return c.RevokeSession()
5962
}
6063

61-
// GetSession returns the current valid session token, if any. If token is expired,
62-
// it will attempt to refresh it. If no token is found, or is unable to be refreshed,
63-
// it will return nil and false.
64-
// TODO: automatically refresh token as needed
65-
func (c *Client) GetSession(ctx context.Context) (*session.Token, bool) {
66-
tok := c.store.ReadToken(c.issuer, c.clientID)
67-
if tok == nil {
68-
return nil, false
64+
// GetSession returns the current valid session token, if any. If token is
65+
// expired, it will attempt to refresh it. If no token is found, or is unable
66+
// to be refreshed, it will return error.
67+
func (c *Client) GetSession(ctx context.Context) (*session.Token, error) {
68+
tok, err := c.store.ReadToken(c.issuer, c.clientID)
69+
if errors.Is(err, os.ErrNotExist) {
70+
return nil, ErrNotLoggedIn
71+
} else if err != nil {
72+
return nil, err
6973
}
7074

7175
// Refresh if the token is no longer valid:
7276
if !tok.Valid() {
73-
tok = c.refresh(ctx, tok)
74-
if !tok.Valid() {
75-
return nil, false
77+
tok, err = c.refresh(ctx, tok)
78+
if err != nil {
79+
return nil, err
7680
}
7781
}
7882

79-
return tok, true
83+
return tok, nil
8084
}
8185

8286
func (c *Client) refresh(
8387
ctx context.Context,
8488
tok *session.Token,
85-
) *session.Token {
86-
if tok == nil {
87-
return nil
88-
}
89-
89+
) (*session.Token, error) {
9090
// TODO: figure out how to share oidc provider and oauth2 client
9191
// with auth flow:
9292
provider, err := oidc.NewProvider(ctx, c.issuer)
9393
if err != nil {
94-
return tok
94+
return tok, err
9595
}
9696

9797
conf := oauth2.Config{
@@ -104,18 +104,19 @@ func (c *Client) refresh(
104104
tokenSource := conf.TokenSource(ctx, &tok.Token)
105105
newToken, err := tokenSource.Token()
106106
if err != nil {
107-
return tok
107+
return tok, err
108108
}
109109

110110
if newToken.AccessToken != tok.AccessToken {
111111
tok.Token = *newToken
112+
tok.IDToken = newToken.Extra("id_token").(string)
112113
err = c.store.WriteToken(c.issuer, c.clientID, tok)
113114
if err != nil {
114-
return tok
115+
return tok, err
115116
}
116117
}
117118

118-
return tok
119+
return tok, nil
119120
}
120121

121122
func (c *Client) RevokeSession() error {

pkg/sandbox/auth/internal/tokenstore/tokenstore.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ func New(rootDir string) (*Store, error) {
2323
}, nil
2424
}
2525

26-
func (s *Store) ReadToken(issuer string, clientID string) *session.Token {
26+
func (s *Store) ReadToken(issuer string, clientID string) (*session.Token, error) {
2727
var tok session.Token
2828
path := s.path(issuer, clientID)
2929
err := readJSONFile(path, &tok)
3030
if err != nil {
31-
return nil
31+
return nil, err
3232
}
33-
return &tok
33+
return &tok, nil
3434
}
3535

3636
func (s *Store) WriteToken(issuer string, clientID string, tok *session.Token) error {

0 commit comments

Comments
 (0)