aboutsummaryrefslogtreecommitdiff
path: root/internal/cached_token_source.go
diff options
context:
space:
mode:
authorXe Iaso <me@christine.website>2023-09-30 10:36:37 -0400
committerGitHub <noreply@github.com>2023-09-30 10:36:37 -0400
commitac6a3df0d18cc73524c0096d954a57d24cad5669 (patch)
tree81474177d730440657f490ae29892d62392251ea /internal/cached_token_source.go
parentcbdea8ba3fca9a663778af71f8df5965aeb6c090 (diff)
downloadxesite-ac6a3df0d18cc73524c0096d954a57d24cad5669.tar.xz
xesite-ac6a3df0d18cc73524c0096d954a57d24cad5669.zip
Xesite V4 (#723)
* scripts/ditherify: fix quoting Signed-off-by: Xe Iaso <me@xeiaso.net> * clean up some old files Signed-off-by: Xe Iaso <me@xeiaso.net> * import site into lume Signed-off-by: Xe Iaso <me@xeiaso.net> * initial go code Signed-off-by: Xe Iaso <me@xeiaso.net> * move vods index to top level Signed-off-by: Xe Iaso <me@xeiaso.net> * remove the ads Signed-off-by: Xe Iaso <me@xeiaso.net> * internal/lume: metrics Signed-off-by: Xe Iaso <me@xeiaso.net> * delete old code Signed-off-by: Xe Iaso <me@xeiaso.net> * load config into memory Signed-off-by: Xe Iaso <me@xeiaso.net> * autogenerate data from dhall config Signed-off-by: Xe Iaso <me@xeiaso.net> * various cleanups, import clackset logic Signed-off-by: Xe Iaso <me@xeiaso.net> * Update signalboost.dhall (#722) Added myself, and also fixed someone’s typo * Add Connor Edwards to signal boost (#721) * add cache headers Signed-off-by: Xe Iaso <me@xeiaso.net> * move command to xesite folder Signed-off-by: Xe Iaso <me@xeiaso.net> * xesite: listen for GitHub webhook push events Signed-off-by: Xe Iaso <me@xeiaso.net> * xesite: 5 minute timeout for rebuilding the site Signed-off-by: Xe Iaso <me@xeiaso.net> * xesite: add rebuild metrics Signed-off-by: Xe Iaso <me@xeiaso.net> * xesite: update default variables Signed-off-by: Xe Iaso <me@xeiaso.net> * don't commit binaries oops lol Signed-off-by: Xe Iaso <me@xeiaso.net> * lume: make search have a light background Signed-off-by: Xe Iaso <me@xeiaso.net> * add a notfound page Signed-off-by: Xe Iaso <me@xeiaso.net> * fetch info from patreon API Signed-off-by: Xe Iaso <me@xeiaso.net> * create contact page Signed-off-by: Xe Iaso <me@xeiaso.net> * Toot embedding Signed-off-by: Xe Iaso <me@xeiaso.net> * attempt a docker image Signed-off-by: Xe Iaso <me@xeiaso.net> * lume: fix deno lock Signed-off-by: Xe Iaso <me@xeiaso.net> * add gokrazy post Signed-off-by: Xe Iaso <me@xeiaso.net> * cmd/xesite: go up before trying to connect to the saas proxy Signed-off-by: Xe Iaso <me@xeiaso.net> * blog: add Sine post/demo Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Co-authored-by: bri <284789+b-@users.noreply.github.com> Co-authored-by: Connor Edwards <38229097+cedws@users.noreply.github.com>
Diffstat (limited to 'internal/cached_token_source.go')
-rw-r--r--internal/cached_token_source.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/cached_token_source.go b/internal/cached_token_source.go
new file mode 100644
index 0000000..22bad75
--- /dev/null
+++ b/internal/cached_token_source.go
@@ -0,0 +1,86 @@
+package internal
+
+import (
+ "context"
+ "encoding/json"
+ "expvar"
+ "fmt"
+ "os"
+ "time"
+
+ "golang.org/x/oauth2"
+)
+
+var (
+ tokenRefreshCount = expvar.NewInt("gauge_xesite_token_refresh_count")
+)
+
+type cachingTokenSource struct {
+ base oauth2.TokenSource
+ filename string
+}
+
+func (c *cachingTokenSource) saveToken(tok *oauth2.Token) error {
+ fout, err := os.Create(c.filename)
+ if err != nil {
+ return fmt.Errorf("error creating %s: %w", c.filename, err)
+ }
+ defer fout.Close()
+
+ return json.NewEncoder(fout).Encode(tok)
+}
+
+func ReadToken(fname string) (*oauth2.Token, error) {
+ fin, err := os.Open(fname)
+ if err != nil {
+ return nil, fmt.Errorf("error opening %s: %w", fname, err)
+ }
+ defer fin.Close()
+
+ var tok oauth2.Token
+ if err := json.NewDecoder(fin).Decode(&tok); err != nil {
+ return nil, fmt.Errorf("error decoding %s: %w", fname, err)
+ }
+
+ return &tok, nil
+}
+
+func FileExists(filename string) bool {
+ _, err := os.Stat(filename)
+ return !os.IsNotExist(err)
+}
+
+func (c *cachingTokenSource) loadToken() (*oauth2.Token, error) {
+ if !FileExists(c.filename) {
+ return nil, nil
+ }
+
+ return ReadToken(c.filename)
+}
+
+func (c *cachingTokenSource) Token() (tok *oauth2.Token, err error) {
+ tok, _ = c.loadToken()
+ if tok != nil && tok.Expiry.Before(time.Now()) {
+ return tok, nil
+ }
+
+ if tok, err = c.base.Token(); err != nil {
+ return nil, err
+ }
+
+ tokenRefreshCount.Add(1)
+
+ if err := c.saveToken(tok); err != nil {
+ return nil, err
+ }
+
+ return tok, err
+}
+
+func CachingTokenSource(filename string, config *oauth2.Config, tok *oauth2.Token) oauth2.TokenSource {
+ orig := config.TokenSource(context.Background(), tok)
+ return oauth2.ReuseTokenSource(nil, &cachingTokenSource{
+ filename: filename,
+ base: orig,
+ })
+}