79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
package store
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
type TokenSet struct {
|
|
AccessToken string `json:"access_token"`
|
|
RefreshToken string `json:"refresh_token"`
|
|
TokenType string `json:"token_type"`
|
|
Expiry time.Time `json:"expiry"`
|
|
Scopes []string `json:"scopes,omitempty"`
|
|
Account string `json:"account,omitempty"`
|
|
}
|
|
|
|
func (t *TokenSet) IsExpired() bool {
|
|
if t.Expiry.IsZero() {
|
|
return false
|
|
}
|
|
return time.Now().After(t.Expiry)
|
|
}
|
|
|
|
type TokenStore struct {
|
|
path string
|
|
}
|
|
|
|
func NewTokenStore(path string) *TokenStore {
|
|
return &TokenStore{path: path}
|
|
}
|
|
|
|
func (s *TokenStore) Save(token *TokenSet) error {
|
|
if err := os.MkdirAll(filepath.Dir(s.path), 0700); err != nil {
|
|
return fmt.Errorf("create token dir: %w", err)
|
|
}
|
|
data, err := json.MarshalIndent(token, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("marshal token: %w", err)
|
|
}
|
|
tmp := s.path + ".tmp"
|
|
if err := os.WriteFile(tmp, data, 0600); err != nil {
|
|
return fmt.Errorf("write token file: %w", err)
|
|
}
|
|
if err := os.Rename(tmp, s.path); err != nil {
|
|
return fmt.Errorf("rename token file: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *TokenStore) Load() (*TokenSet, error) {
|
|
data, err := os.ReadFile(s.path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("read token file: %w", err)
|
|
}
|
|
var token TokenSet
|
|
if err := json.Unmarshal(data, &token); err != nil {
|
|
return nil, fmt.Errorf("unmarshal token: %w", err)
|
|
}
|
|
return &token, nil
|
|
}
|
|
|
|
func (s *TokenStore) Delete() error {
|
|
if err := os.Remove(s.path); err != nil && !os.IsNotExist(err) {
|
|
return fmt.Errorf("delete token file: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *TokenStore) Exists() bool {
|
|
_, err := os.Stat(s.path)
|
|
return err == nil
|
|
}
|