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

feat: compress token before storing in cache to allow for larger tokens to be cached #1047

Merged
merged 13 commits into from
Apr 5, 2024
2 changes: 1 addition & 1 deletion .github/actions/find-changed-packages/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ runs:
const path = require("path")
const fs = require("fs")
const changedFiles = ${{ steps.filter.outputs.changed_files }}
const changedDirs = changedFiles.map(f => path.dirname(f))
const changedDirs = changedFiles.map(f => path.dirname(f).split('/')[0])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this it looks in oidc_cli/oidc_impl/cache/ and doesn't find a go mod causing it to not include this as a changes package

const changedGoPackages = changedDirs.filter(d => fs.existsSync(path.join(d, "go.mod")))
const uniqueChangedGoPackages = [...new Set(changedGoPackages)];

Expand Down
54 changes: 51 additions & 3 deletions oidc_cli/oidc_impl/cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package cache

import (
"bytes"
"compress/gzip"
"context"
"fmt"
"io"

"github.com/chanzuckerberg/go-misc/oidc_cli/oidc_impl/client"
"github.com/chanzuckerberg/go-misc/oidc_cli/oidc_impl/storage"
Expand Down Expand Up @@ -83,8 +87,14 @@ func (c *Cache) refresh(ctx context.Context) (*client.Token, error) {
if err != nil {
return nil, errors.Wrap(err, "unable to marshall token")
}
// save token to storage
err = c.storage.Set(ctx, strToken)

// gzip encode and save token to storage
compressedToken, err := compressToken(strToken)
if err != nil {
return nil, errors.Wrap(err, "unable to compress token")
}

err = c.storage.Set(ctx, compressedToken)
if err != nil {
return nil, errors.Wrap(err, "Unable to cache the strToken")
}
Expand All @@ -99,7 +109,17 @@ func (c *Cache) readFromStorage(ctx context.Context) (*client.Token, error) {
if err != nil {
return nil, err
}
cachedToken, err := client.TokenFromString(cached)
if cached == nil {
return nil, nil
}

// decode gzip data
decompressedStr, err := decompressToken(*cached)
if err != nil {
return nil, fmt.Errorf("failed to decompress token: %w", err)
}

cachedToken, err := client.TokenFromString(&decompressedStr)
if err != nil {
logrus.WithError(err).Debug("error fetching stored token")
err = c.storage.Delete(ctx) // can't read it, so attempt to purge it
Expand All @@ -109,3 +129,31 @@ func (c *Cache) readFromStorage(ctx context.Context) (*client.Token, error) {
}
return cachedToken, nil
}

func compressToken(token string) (string, error) {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err := gz.Write([]byte(token)); err != nil {
return "", fmt.Errorf("failed to write to gzip: %w", err)
}
if err := gz.Close(); err != nil {
return "", fmt.Errorf("failed to close gzip: %w", err)
}
jakeyheath marked this conversation as resolved.
Show resolved Hide resolved
return buf.String(), nil
}

func decompressToken(token string) (string, error) {
reader := bytes.NewReader([]byte(token))
gzreader, err := gzip.NewReader(reader)
if err != nil {
return "", fmt.Errorf("failed to create gzip reader: %w", err)
}
decompressed, err := io.ReadAll(gzreader)
if err != nil {
return "", fmt.Errorf("failed to read gzip data: %w", err)
}
if err := gzreader.Close(); err != nil {
return "", fmt.Errorf("failed to close gzip: %w", err)
}
return string(decompressed), nil
}
14 changes: 11 additions & 3 deletions oidc_cli/oidc_impl/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ func TestCorruptedCache(t *testing.T) {
r := require.New(t)
s := genStorage()
ctx := context.Background()
err := s.Set(ctx, "garbage token")
compressed, err := compressToken("garbage token")
r.NoError(err)
err = s.Set(ctx, compressed)
r.NoError(err)

u := uuid.New()
Expand All @@ -83,7 +85,10 @@ func TestCorruptedCache(t *testing.T) {
r.NoError(err)
r.NotNil(cachedToken)

tok, err := client.TokenFromString(cachedToken)
decompressedToken, err := decompressToken(*cachedToken)
r.NoError(err)

tok, err := client.TokenFromString(&decompressedToken)
r.NoError(err)
r.NotNil(t)

Expand All @@ -110,7 +115,10 @@ func TestCachedToken(t *testing.T) {
marshalled, err := freshToken.Marshal()
r.NoError(err)

err = s.Set(ctx, marshalled)
compressed, err := compressToken(marshalled)
r.NoError(err)

err = s.Set(ctx, compressed)
r.NoError(err)

refresh := func(ctx context.Context, c *client.Token) (*client.Token, error) {
Expand Down
Loading