|
1 | 1 | package auth |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "fmt" |
5 | 6 | "os" |
6 | 7 | "path/filepath" |
7 | 8 |
|
| 9 | + "github.com/coreos/go-oidc/v3/oidc" |
8 | 10 | "go.jetpack.io/pkg/sandbox/auth/session" |
| 11 | + "golang.org/x/oauth2" |
9 | 12 |
|
10 | 13 | "go.jetpack.io/pkg/sandbox/auth/internal/authflow" |
11 | 14 | "go.jetpack.io/pkg/sandbox/auth/internal/callbackserver" |
@@ -59,16 +62,60 @@ func (c *Client) LogoutFlow() error { |
59 | 62 | // it will attempt to refresh it. If no token is found, or is unable to be refreshed, |
60 | 63 | // it will return nil and false. |
61 | 64 | // TODO: automatically refresh token as needed |
62 | | -func (c *Client) GetSession() (*session.Token, bool) { |
| 65 | +func (c *Client) GetSession(ctx context.Context) (*session.Token, bool) { |
63 | 66 | tok := c.store.ReadToken(c.issuer, c.clientID) |
64 | | - if tok == nil || !tok.Valid() { |
| 67 | + if tok == nil { |
65 | 68 | return nil, false |
66 | 69 | } |
| 70 | + |
| 71 | + // Refresh if the token is no longer valid: |
| 72 | + if !tok.Valid() { |
| 73 | + tok = c.refresh(ctx, tok) |
| 74 | + if !tok.Valid() { |
| 75 | + return nil, false |
| 76 | + } |
| 77 | + } |
| 78 | + |
67 | 79 | return tok, true |
68 | 80 | } |
69 | 81 |
|
70 | | -func (c *Client) RefreshSession() *session.Token { |
71 | | - panic("refresh session not implemented") |
| 82 | +func (c *Client) refresh( |
| 83 | + ctx context.Context, |
| 84 | + tok *session.Token, |
| 85 | +) *session.Token { |
| 86 | + if tok == nil { |
| 87 | + return nil |
| 88 | + } |
| 89 | + |
| 90 | + // TODO: figure out how to share oidc provider and oauth2 client |
| 91 | + // with auth flow: |
| 92 | + provider, err := oidc.NewProvider(ctx, c.issuer) |
| 93 | + if err != nil { |
| 94 | + return tok |
| 95 | + } |
| 96 | + |
| 97 | + conf := oauth2.Config{ |
| 98 | + ClientID: c.clientID, |
| 99 | + Endpoint: provider.Endpoint(), |
| 100 | + Scopes: []string{"openid", "offline_access"}, |
| 101 | + } |
| 102 | + |
| 103 | + // Refresh logic: |
| 104 | + tokenSource := conf.TokenSource(ctx, &tok.Token) |
| 105 | + newToken, err := tokenSource.Token() |
| 106 | + if err != nil { |
| 107 | + return tok |
| 108 | + } |
| 109 | + |
| 110 | + if newToken.AccessToken != tok.AccessToken { |
| 111 | + tok.Token = *newToken |
| 112 | + err = c.store.WriteToken(c.issuer, c.clientID, tok) |
| 113 | + if err != nil { |
| 114 | + return tok |
| 115 | + } |
| 116 | + } |
| 117 | + |
| 118 | + return tok |
72 | 119 | } |
73 | 120 |
|
74 | 121 | func (c *Client) RevokeSession() error { |
|
0 commit comments