This repository has been archived by the owner on Oct 23, 2023. It is now read-only.
/
atomic_credentials.go
89 lines (71 loc) · 2.98 KB
/
atomic_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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package admin
import (
"context"
"sync/atomic"
"google.golang.org/grpc/credentials"
stdlibAtomic "github.com/flyteorg/flytestdlib/atomic"
)
// atomicPerRPCCredentials provides a convenience on top of atomic.Value and credentials.PerRPCCredentials to be thread-safe.
type atomicPerRPCCredentials struct {
atomic.Value
}
func (t *atomicPerRPCCredentials) Store(properties credentials.PerRPCCredentials) {
t.Value.Store(properties)
}
func (t *atomicPerRPCCredentials) Load() credentials.PerRPCCredentials {
val := t.Value.Load()
if val == nil {
return CustomHeaderTokenSource{}
}
return val.(credentials.PerRPCCredentials)
}
func newAtomicPerPRCCredentials() *atomicPerRPCCredentials {
return &atomicPerRPCCredentials{
Value: atomic.Value{},
}
}
// PerRPCCredentialsFuture is a future wrapper for credentials.PerRPCCredentials that can act as one and also be
// materialized later.
type PerRPCCredentialsFuture struct {
perRPCCredentials *atomicPerRPCCredentials
initialized stdlibAtomic.Bool
}
// GetRequestMetadata gets the authorization metadata as a map using a TokenSource to generate a token
func (ts *PerRPCCredentialsFuture) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
if ts.initialized.Load() {
tp := ts.perRPCCredentials.Load()
return tp.GetRequestMetadata(ctx, uri...)
}
return map[string]string{}, nil
}
// RequireTransportSecurity returns whether this credentials class requires TLS/SSL. OAuth uses Bearer tokens that are
// susceptible to MITM (Man-In-The-Middle) attacks that are mitigated by TLS/SSL. We may return false here to make it
// easier to setup auth. However, in a production environment, TLS for OAuth2 is a requirement.
// see also: https://tools.ietf.org/html/rfc6749#section-3.1
func (ts *PerRPCCredentialsFuture) RequireTransportSecurity() bool {
if ts.initialized.Load() {
return ts.perRPCCredentials.Load().RequireTransportSecurity()
}
return false
}
func (ts *PerRPCCredentialsFuture) Store(tokenSource credentials.PerRPCCredentials) {
ts.perRPCCredentials.Store(tokenSource)
ts.initialized.Store(true)
}
func (ts *PerRPCCredentialsFuture) Get() credentials.PerRPCCredentials {
return ts.perRPCCredentials.Load()
}
func (ts *PerRPCCredentialsFuture) IsInitialized() bool {
return ts.initialized.Load()
}
// NewPerRPCCredentialsFuture initializes a new PerRPCCredentialsFuture that can act as a credentials.PerRPCCredentials
// and can also be resolved in the future. Users of the future can check if it has been initialized before by calling
// PerRPCCredentialsFuture.IsInitialized(). Calling PerRPCCredentialsFuture.Get() multiple times will return
// the same stored object (unless it changed in between calls). Calling PerRPCCredentialsFuture.Store() multiple
// times is supported and will result in overriding the old value atomically.
func NewPerRPCCredentialsFuture() *PerRPCCredentialsFuture {
tokenSource := PerRPCCredentialsFuture{
perRPCCredentials: newAtomicPerPRCCredentials(),
}
return &tokenSource
}