This repository has been archived by the owner on Jan 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile.go
120 lines (95 loc) · 2.25 KB
/
file.go
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package secrets
import (
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"path"
)
// implements file storage for secret config
type GenericConfig struct {
Base64 bool
Base64URLEncoded bool
Base64Raw bool
}
type FileConfig struct {
GenericConfig
Path string
}
type FileSecretProvider struct {
FileConfig
}
func NewFileSecretProviderFromConfig(cfg FileConfig) *FileSecretProvider {
return &FileSecretProvider{
FileConfig: cfg,
}
}
var _ SecretStorage = &FileSecretProvider{}
func (fp *FileSecretProvider) SetSecret(name string, secret []byte) error {
fullPath := name
if len(fp.Path) > 0 {
fullPath = path.Join(fp.Path, name)
}
dir := path.Dir(fullPath)
if len(dir) > 0 {
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir %q: %w", fp.Path, err)
}
}
var b []byte
if fp.Base64 {
b = make([]byte, fp.encoder().EncodedLen(len(secret)))
fp.encoder().Encode(b, secret)
} else {
b = make([]byte, len(secret))
copy(b, secret)
}
f, err := os.Create(fullPath)
if err != nil {
return fmt.Errorf("creating file %q: %w", fullPath, err)
}
if _, err := f.Write(b); err != nil {
return fmt.Errorf("writing file %q: %w", fullPath, err)
}
return nil
}
func (fp *FileSecretProvider) GetSecret(name string) (secret []byte, err error) {
fullPath := path.Join(fp.Path, name)
f, err := os.Open(fullPath)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("%w: missing file %q", ErrNotFound, fullPath)
}
return nil, fmt.Errorf("opening file %q: %w", fullPath, err)
}
b, err := ioutil.ReadAll(f)
if err != nil {
return nil, fmt.Errorf("reading file %q: %w", fullPath, err)
}
var result []byte
if fp.Base64 {
result = make([]byte, fp.encoder().DecodedLen(len(b)))
written, err := fp.encoder().Decode(result, b)
if err != nil {
return nil, fmt.Errorf("base64 decoding file %q: %w", fullPath, err)
}
result = result[:written]
return result, nil
}
return b, nil
}
func (fp *FileSecretProvider) encoder() *base64.Encoding {
if fp.Base64URLEncoded {
if fp.Base64Raw {
return base64.RawURLEncoding
} else {
return base64.URLEncoding
}
} else { // std encoding
if fp.Base64Raw {
return base64.RawStdEncoding
} else {
return base64.StdEncoding
}
}
}