MCPcopy
hub / github.com/larksuite/cli / PollDeviceToken

Function PollDeviceToken

internal/auth/device_flow.go:142–265  ·  view source on GitHub ↗

PollDeviceToken polls the token endpoint until authorization completes or times out.

(ctx context.Context, httpClient *http.Client, appId, appSecret string, brand core.LarkBrand, deviceCode string, interval, expiresIn int, errOut io.Writer)

Source from the content-addressed store, hash-verified

140
141// PollDeviceToken polls the token endpoint until authorization completes or times out.
142func PollDeviceToken(ctx context.Context, httpClient *http.Client, appId, appSecret string, brand core.LarkBrand, deviceCode string, interval, expiresIn int, errOut io.Writer) *DeviceFlowResult {
143 if errOut == nil {
144 errOut = io.Discard
145 }
146
147 if interval < 1 {
148 interval = 5
149 }
150
151 const maxPollInterval = 60
152 const maxPollAttempts = 600
153
154 endpoints := ResolveOAuthEndpoints(brand)
155 deadline := time.Now().Add(time.Duration(expiresIn) * time.Second)
156 currentInterval := interval
157 attempts := 0
158
159 for time.Now().Before(deadline) && attempts < maxPollAttempts {
160 attempts++
161 if ctx.Err() != nil {
162 return &DeviceFlowResult{OK: false, Error: "expired_token", Message: "Polling was cancelled"}
163 }
164
165 select {
166 case <-time.After(time.Duration(currentInterval) * time.Second):
167 case <-ctx.Done():
168 return &DeviceFlowResult{OK: false, Error: "expired_token", Message: "Polling was cancelled"}
169 }
170
171 form := url.Values{}
172 form.Set("grant_type", "urn:ietf:params:oauth:grant-type:device_code")
173 form.Set("device_code", deviceCode)
174 form.Set("client_id", appId)
175 form.Set("client_secret", appSecret)
176
177 req, err := http.NewRequest("POST", endpoints.Token, strings.NewReader(form.Encode()))
178 if err != nil {
179 continue
180 }
181 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
182
183 resp, err := httpClient.Do(req)
184 if err != nil {
185 fmt.Fprintf(errOut, "[lark-cli] [WARN] device-flow: poll network error: %v\n", err)
186 currentInterval = minInt(currentInterval+1, maxPollInterval)
187 continue
188 }
189 logHTTPResponse(resp)
190
191 body, err := io.ReadAll(resp.Body)
192 resp.Body.Close()
193 if err != nil {
194 fmt.Fprintf(errOut, "[lark-cli] [WARN] device-flow: poll read error: %v\n", err)
195 currentInterval = minInt(currentInterval+1, maxPollInterval)
196 continue
197 }
198
199 var data map[string]interface{}

Calls 9

ResolveOAuthEndpointsFunction · 0.85
minIntFunction · 0.85
logHTTPResponseFunction · 0.85
getStrFunction · 0.85
getIntFunction · 0.85
DurationMethod · 0.80
ErrMethod · 0.65
SetMethod · 0.65
CloseMethod · 0.45