MCPcopy Index your code
hub / github.com/docker/cli / WaitForDeviceToken

Method WaitForDeviceToken

internal/oauth/api/api.go:98–141  ·  view source on GitHub ↗

WaitForDeviceToken polls the tenant to get access/refresh tokens for the user. This should be called after GetDeviceCode, and will block until the user has authenticated or we have reached the time limit for authenticating (based on the response from GetDeviceCode).

(ctx context.Context, state State)

Source from the content-addressed store, hash-verified

96// authenticated or we have reached the time limit for authenticating (based on
97// the response from GetDeviceCode).
98func (a API) WaitForDeviceToken(ctx context.Context, state State) (TokenResponse, error) {
99 // Ticker for polling tenant for login – based on the interval
100 // specified by the tenant response.
101 ticker := time.NewTimer(state.IntervalDuration())
102 defer ticker.Stop()
103 // The tenant tells us for as long as we can poll it for credentials
104 // while the user logs in through their browser. Timeout if we don't get
105 // credentials within this period.
106 timeout := time.NewTimer(state.ExpiryDuration())
107 defer timeout.Stop()
108
109 for {
110 resetTimer(ticker, state.IntervalDuration())
111 select {
112 case <-ctx.Done():
113 // user canceled login
114 return TokenResponse{}, ctx.Err()
115 case <-ticker.C:
116 // tick, check for user login
117 res, err := a.getDeviceToken(ctx, state)
118 if err != nil {
119 if errors.Is(err, context.Canceled) {
120 // if the caller canceled the context, continue
121 // and let the select hit the ctx.Done() branch
122 continue
123 }
124 return TokenResponse{}, err
125 }
126
127 if res.Error != nil {
128 if *res.Error == "authorization_pending" {
129 continue
130 }
131
132 return res, errors.New(res.ErrorDescription)
133 }
134
135 return res, nil
136 case <-timeout.C:
137 // login timed out
138 return TokenResponse{}, ErrTimeout
139 }
140 }
141}
142
143// resetTimer is a helper function thatstops, drains and resets the timer.
144// This is necessary in go versions <1.23, since the timer isn't stopped +

Callers 1

TestWaitForDeviceTokenFunction · 0.95

Calls 5

getDeviceTokenMethod · 0.95
resetTimerFunction · 0.85
IntervalDurationMethod · 0.80
ExpiryDurationMethod · 0.80
ErrMethod · 0.65

Tested by 1

TestWaitForDeviceTokenFunction · 0.76