Files
go-garth/filestorage.go
2025-09-02 06:52:24 -07:00

81 lines
1.7 KiB
Go

package garth
import (
"context"
"encoding/json"
"os"
"path/filepath"
)
// fileStorage implements TokenStorage using a file
type fileStorage struct {
path string
auth Authenticator // Reference to authenticator for token refreshes
}
// NewFileStorage creates a new file-based token storage
func NewFileStorage(path string) TokenStorage {
return &fileStorage{path: path}
}
// SetAuthenticator sets the authenticator for token refreshes
func (s *fileStorage) SetAuthenticator(a Authenticator) {
s.auth = a
}
// GetToken retrieves token from file, refreshing if expired
func (s *fileStorage) GetToken() (*Token, error) {
token, err := s.loadToken()
if err != nil {
return nil, err
}
// Refresh token if expired
if token.IsExpired() {
refreshed, err := s.auth.RefreshToken(context.Background(), token.RefreshToken)
if err != nil {
return nil, err
}
if err := s.SaveToken(refreshed); err != nil {
return nil, err
}
return refreshed, nil
}
return token, nil
}
// loadToken loads token from file without refreshing
func (s *fileStorage) loadToken() (*Token, error) {
data, err := os.ReadFile(s.path)
if err != nil {
return nil, err
}
var token Token
if err := json.Unmarshal(data, &token); err != nil {
return nil, err
}
if token.AccessToken == "" || token.RefreshToken == "" {
return nil, os.ErrNotExist
}
return &token, nil
}
// SaveToken saves token to file
func (s *fileStorage) SaveToken(token *Token) error {
// Create directory if needed
dir := filepath.Dir(s.path)
if err := os.MkdirAll(dir, 0700); err != nil {
return err
}
data, err := json.MarshalIndent(token, "", " ")
if err != nil {
return err
}
return os.WriteFile(s.path, data, 0600)
}