-
Notifications
You must be signed in to change notification settings - Fork 0
/
keys.go
executable file
·140 lines (121 loc) · 3.06 KB
/
keys.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package websocketproxy
import (
"encoding/json"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"io/ioutil"
"os"
)
const (
KeyManagerEnv = "env"
KeyManagerFile = "file"
KeyManagerSecretsManager = "aws_sm"
)
// Keys type is the representation of how keys are stored in the manager
type Keys []string
// KeyManager is a generic interface for implementing a specific backend
// for managing API keys
type KeyManager interface {
ValidateKey(string) bool
FetchKeys() error
setIdentifier(string)
}
// NewKeyManager returns a pointer of an KeyManager implementation based
// on the type of KeyManager that was provided
func NewKeyManager(keyManagerType string, id string) KeyManager {
var k KeyManager
switch keyManagerType {
case KeyManagerEnv:
k = &Env{}
break
case KeyManagerFile:
k = &File{}
break
case KeyManagerSecretsManager:
k = &SecretsManager{}
}
if k != nil {
k.setIdentifier(id)
}
return k
}
// Env takes a comma separated env var and uses the content as keys
type Env struct {
id string
keys []string
}
// ValidateKey returns a boolean to whether a key given is present
func (e *Env) ValidateKey(key string) bool {
return validateKey(key, e.keys)
}
// FetchKeys sets the keys from the env var
func (e *Env) FetchKeys() error {
return json.Unmarshal([]byte(os.Getenv(e.id)), &e.keys)
}
func (e *Env) setIdentifier(id string) {
e.id = id
}
// File manages keys on the local disk
type File struct {
id string
keys []string
}
// ValidateKey returns a boolean to whether a key given is present in the file
func (f *File) ValidateKey(key string) bool {
return validateKey(key, f.keys)
}
// FetchKeys sets the keys from the file on local disk
func (f *File) FetchKeys() error {
if file, err := os.Open(f.id); err != nil {
return err
} else if b, err := ioutil.ReadAll(file); err != nil {
return err
} else if err := json.Unmarshal(b, &f.keys); err != nil {
return err
}
return nil
}
func (f *File) setIdentifier(id string) {
f.id = id
}
// SecretsManager is the KeyManager implementation for AWS Secrets Manager
type SecretsManager struct {
id string
keys []string
}
// ValidateKey returns a boolean to whether a key given is present in the manager
func (sm *SecretsManager) ValidateKey(key string) bool {
for _, k := range sm.keys {
if k == key {
return true
}
}
return false
}
// FetchKeys sets the keys from the manager backend into memory for use on client auth
func (sm *SecretsManager) FetchKeys() error {
svc := secretsmanager.New(session.Must(session.NewSession(aws.NewConfig())))
if svo, err := svc.GetSecretValue(&secretsmanager.GetSecretValueInput{
SecretId: aws.String(sm.id),
}); err != nil {
return err
} else {
b := []byte(*svo.SecretString)
if err := json.Unmarshal(b, &sm.keys); err != nil {
return err
}
}
return nil
}
func (sm *SecretsManager) setIdentifier(id string) {
sm.id = id
}
func validateKey(key string, keys []string) bool {
for _, k := range keys {
if k == key {
return true
}
}
return false
}