You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
loop/lsat/store.go

101 lines
2.4 KiB
Go

package lsat
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
var (
// ErrNoToken is the error returned when the store doesn't contain a
// token yet.
ErrNoToken = fmt.Errorf("no token in store")
storeFileName = "lsat.token"
)
// Store is an interface that allows users to store and retrieve an LSAT token.
type Store interface {
// HasToken returns true if the store contains a token.
HasToken() bool
// Token returns the token that is contained in the store or an error
// if there is none.
Token() (*Token, error)
// StoreToken saves a token to the store, overwriting any old token if
// there is one.
StoreToken(*Token) error
}
// FileStore is an implementation of the Store interface that uses a single file
// to save the serialized token.
type FileStore struct {
fileName string
}
// A compile-time flag to ensure that FileStore implements the Store interface.
var _ Store = (*FileStore)(nil)
// NewFileStore creates a new file based token store, creating its file in the
// provided directory. If the directory does not exist, it will be created.
func NewFileStore(storeDir string) (*FileStore, error) {
// If the target path for the token store doesn't exist, then we'll
// create it now before we proceed.
if !fileExists(storeDir) {
if err := os.MkdirAll(storeDir, 0700); err != nil {
return nil, err
}
}
return &FileStore{
fileName: filepath.Join(storeDir, storeFileName),
}, nil
}
// HasToken returns true if the store contains a token.
//
// NOTE: This is part of the Store interface.
func (f *FileStore) HasToken() bool {
return fileExists(f.fileName)
}
// Token returns the token that is contained in the store or an error if there
// is none.
//
// NOTE: This is part of the Store interface.
func (f *FileStore) Token() (*Token, error) {
if !f.HasToken() {
return nil, ErrNoToken
}
bytes, err := ioutil.ReadFile(f.fileName)
if err != nil {
return nil, err
}
return deserializeToken(bytes)
}
// StoreToken saves a token to the store, overwriting any old token if there is
// one.
//
// NOTE: This is part of the Store interface.
func (f *FileStore) StoreToken(token *Token) error {
bytes, err := serializeToken(token)
if err != nil {
return err
}
return ioutil.WriteFile(f.fileName, bytes, 0600)
}
// fileExists returns true if the file exists, and false otherwise.
func fileExists(path string) bool {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}