-
Notifications
You must be signed in to change notification settings - Fork 7
/
credentials.go
74 lines (63 loc) · 1.99 KB
/
credentials.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
package credentials
import (
"crypto/ecdsa"
"sync"
"github.com/nerdalize/nerd/nerd/payload"
"github.com/pkg/errors"
)
//NerdAPI holds a reference to a nerdalize auth token. A credentials provider is needed to provide this value.
type NerdAPI struct {
value *NerdAPIValue
PublicKey *ecdsa.PublicKey
provider Provider
forceRefresh bool
m sync.Mutex
}
//NerdAPIValue is the value struct that contains credential values.
type NerdAPIValue struct {
NerdToken string
}
//Provider is a credential provider that gives a NerdAPIValue when Retrieve is called.
//A provider can define it's own logic of where to fetch this NerdAPIValue from.
type Provider interface {
IsExpired() bool
Retrieve(*ecdsa.PublicKey) (*NerdAPIValue, error)
}
//NewNerdAPI creates a new credentials.NerdAPI struct.
func NewNerdAPI(pub *ecdsa.PublicKey, provider Provider) *NerdAPI {
return &NerdAPI{
PublicKey: pub,
provider: provider,
m: sync.Mutex{},
}
}
//Get the nerd token. This function checks with the provider whether the token is expired and if so retrieves a new token from the provider.
func (n *NerdAPI) Get() (*NerdAPIValue, error) {
n.m.Lock()
defer n.m.Unlock()
if n.isExpired() {
value, err := n.provider.Retrieve(n.PublicKey)
if err != nil {
return nil, errors.Wrap(err, "failed to retreive nerd api credentials")
}
n.value = value
n.forceRefresh = false
}
return n.value, nil
}
//GetClaims calls Get() and decodes the token string into a NerdClaims object.
func (n *NerdAPI) GetClaims() (*payload.NerdClaims, error) {
val, err := n.Get()
if err != nil {
return nil, errors.Wrap(err, "failed to retreive token")
}
claims, err := DecodeTokenWithKey(val.NerdToken, n.PublicKey)
if err != nil {
return nil, errors.Wrap(err, "failed to decode token")
}
return claims, nil
}
//isExpired checks if the provider is expired or if it's the first time to call the IsExpired function.
func (n *NerdAPI) isExpired() bool {
return n.forceRefresh || n.provider.IsExpired()
}