...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package providers
17
18 import (
19 "context"
20 "errors"
21 "fmt"
22 "sync"
23 )
24
25 var (
26 m sync.Mutex
27 providers []providerEntry
28 )
29
30 type providerEntry struct {
31 name string
32 p Interface
33 }
34
35
36 type Interface interface {
37
38 Enabled(ctx context.Context) bool
39
40
41 Provide(ctx context.Context, audience string) (string, error)
42 }
43
44
45 func Register(name string, p Interface) {
46 m.Lock()
47 defer m.Unlock()
48
49 for _, pe := range providers {
50 if pe.name == name {
51 panic(fmt.Sprintf("duplicate provider for name %q, %T and %T", name, pe.p, p))
52 }
53 }
54 providers = append(providers, providerEntry{name: name, p: p})
55 }
56
57
58 func Enabled(ctx context.Context) bool {
59 m.Lock()
60 defer m.Unlock()
61
62 for _, provider := range providers {
63 if provider.p.Enabled(ctx) {
64 return true
65 }
66 }
67 return false
68 }
69
70
71 func Provide(ctx context.Context, audience string) (string, error) {
72 m.Lock()
73 defer m.Unlock()
74
75 var id string
76 var err error
77 for _, provider := range providers {
78 if !provider.p.Enabled(ctx) {
79 continue
80 }
81 id, err = provider.p.Provide(ctx, audience)
82 if err == nil {
83 return id, nil
84 }
85 }
86
87
88 if err == nil {
89 err = errors.New("no providers are enabled, check providers.Enabled() before providers.Provide()")
90 }
91 return id, err
92 }
93
94
95 func ProvideFrom(_ context.Context, provider string) (Interface, error) {
96 m.Lock()
97 defer m.Unlock()
98
99 for _, p := range providers {
100 if p.name == provider {
101 return p.p, nil
102 }
103 }
104 return nil, fmt.Errorf("%s is not a valid provider", provider)
105 }
106
View as plain text