1{{> partials.copyHeader }}
2
3package okta
4
5import (
6 "context"
7 "fmt"
8 "io/ioutil"
9 "os/user"
10 "path"
11 "path/filepath"
12 "runtime"
13
14 "github.com/kelseyhightower/envconfig"
15 "github.com/okta/okta-sdk-golang/v2/okta/cache"
16 "gopkg.in/yaml.v3"
17)
18
19const Version = "{{ version }}"
20
21type Client struct {
22 config *config
23 requestExecutor *RequestExecutor
24 resource resource
25 {{getClientTagResources operations}}
26}
27
28type resource struct {
29 client *Client
30}
31
32type clientContextKey struct{}
33
34func NewClient(ctx context.Context, conf ...ConfigSetter) (context.Context, *Client, error) {
35 config := &config{}
36
37 setConfigDefaults(config)
38 config = readConfigFromSystem(*config)
39 config = readConfigFromApplication(*config)
40 config = readConfigFromEnvironment(*config)
41
42 for _, confSetter := range conf {
43 confSetter(config)
44 }
45
46 var oktaCache cache.Cache
47 if !config.Okta.Client.Cache.Enabled {
48 oktaCache = cache.NewNoOpCache()
49 } else {
50 if config.CacheManager == nil {
51 oktaCache = cache.NewGoCache(config.Okta.Client.Cache.DefaultTtl,
52 config.Okta.Client.Cache.DefaultTti)
53 } else {
54 oktaCache = config.CacheManager
55 }
56 }
57
58 config.CacheManager = oktaCache
59
60 config, err := validateConfig(config)
61 if err != nil {
62 return nil, nil, err
63 }
64
65 c := &Client{}
66 c.config = config
67 c.requestExecutor = NewRequestExecutor(config.HttpClient, oktaCache, config)
68
69 c.resource.client = c
70
71 {{{getNewClientTagProps operations}}}
72
73 contextReturn := context.WithValue(ctx, clientContextKey{}, c)
74
75 return contextReturn, c, nil
76}
77
78func ClientFromContext(ctx context.Context) (*Client, bool) {
79 u, ok := ctx.Value(clientContextKey{}).(*Client)
80 return u, ok
81}
82
83func (c *Client) GetConfig() *config {
84 return c.config
85}
86
87func (c *Client) SetConfig(conf ...ConfigSetter) (err error) {
88 config := c.config
89 for _, confSetter := range conf {
90 confSetter(config)
91 }
92 _, err = validateConfig(config)
93 if err != nil {
94 return
95 }
96 c.config = config
97 return
98}
99
100// GetRequestExecutor returns underlying request executor
101// Deprecated: please use CloneRequestExecutor() to avoid race conditions
102func (c *Client) GetRequestExecutor() *RequestExecutor {
103 return c.requestExecutor
104}
105
106// CloneRequestExecutor create a clone of the underlying request executor
107func (c *Client) CloneRequestExecutor() *RequestExecutor {
108 a := *c.requestExecutor
109 return &a
110}
111
112func setConfigDefaults(c *config) {
113 conf := []ConfigSetter{
114 WithConnectionTimeout(60),
115 WithCache(true),
116 WithCacheTtl(300),
117 WithCacheTti(300),
118 WithUserAgentExtra(""),
119 WithTestingDisableHttpsCheck(false),
120 WithRequestTimeout(0),
121 WithRateLimitMaxBackOff(30),
122 WithRateLimitMaxRetries(2),
123 WithAuthorizationMode("SSWS"),
124 }
125 for _, confSetter := range conf {
126 confSetter(c)
127 }
128}
129
130func readConfigFromFile(location string, c config) (*config, error) {
131 yamlConfig, err := ioutil.ReadFile(location)
132 if err != nil {
133 return nil, err
134 }
135 err = yaml.Unmarshal(yamlConfig, &c)
136 if err != nil {
137 return nil, err
138 }
139 return &c, err
140}
141
142func readConfigFromSystem(c config) *config {
143 currUser, err := user.Current()
144 if err != nil {
145 return &c
146 }
147 if currUser.HomeDir == "" {
148 return &c
149 }
150 conf, err := readConfigFromFile(currUser.HomeDir+"/.okta/okta.yaml", c)
151 if err != nil {
152 return &c
153 }
154 return conf
155}
156
157// read config from the project's root directory
158func readConfigFromApplication(c config) *config {
159 _, b, _, _ := runtime.Caller(0)
160 conf, err := readConfigFromFile(filepath.Join(filepath.Dir(path.Join(path.Dir(b))), ".okta.yaml"), c)
161 if err != nil {
162 return &c
163 }
164 return conf
165}
166
167func readConfigFromEnvironment(c config) *config {
168 err := envconfig.Process("okta", &c)
169 if err != nil {
170 fmt.Println("error parsing")
171 return &c
172 }
173 return &c
174}
175
176func boolPtr(b bool) *bool {
177 return &b
178}
179
180func Int64Ptr(i int64) *int64 {
181 return &i
182}
View as plain text