1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
package file
import (
"context"
"errors"
"os"
"path/filepath"
"sync"
"github.com/AzureAD/microsoft-authentication-extensions-for-go/cache/accessor"
)
// Storage stores data in an unencrypted file.
type Storage struct {
m *sync.RWMutex
p string
}
// New is the constructor for Storage. "p" is the path to the file in which to store data.
func New(p string) (*Storage, error) {
return &Storage{m: &sync.RWMutex{}, p: p}, nil
}
// Delete deletes the file, if it exists.
func (s *Storage) Delete(context.Context) error {
s.m.Lock()
defer s.m.Unlock()
err := os.Remove(s.p)
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
// Read returns the file's content or, if the file doesn't exist, a nil slice and error.
func (s *Storage) Read(context.Context) ([]byte, error) {
s.m.RLock()
defer s.m.RUnlock()
b, err := os.ReadFile(s.p)
if errors.Is(err, os.ErrNotExist) {
return nil, nil
}
return b, err
}
// Write stores data in the file, overwriting any content, and creates the file if necessary.
func (s *Storage) Write(ctx context.Context, data []byte) error {
s.m.Lock()
defer s.m.Unlock()
err := os.WriteFile(s.p, data, 0600)
if errors.Is(err, os.ErrNotExist) {
dir := filepath.Dir(s.p)
if err = os.MkdirAll(dir, 0700); err == nil {
err = os.WriteFile(s.p, data, 0600)
}
}
return err
}
var _ accessor.Accessor = (*Storage)(nil)
|