MCPcopy Index your code
hub / github.com/rilldata/rill / getAccessTokenForDeviceCode

Method getAccessTokenForDeviceCode

admin/server/auth/device_code.go:164–256  ·  view source on GitHub ↗

getAccessTokenForDeviceCode verifies the device code and returns an access token if the request is approved

(w http.ResponseWriter, r *http.Request, values url.Values)

Source from the content-addressed store, hash-verified

162
163// getAccessTokenForDeviceCode verifies the device code and returns an access token if the request is approved
164func (a *Authenticator) getAccessTokenForDeviceCode(w http.ResponseWriter, r *http.Request, values url.Values) {
165 deviceCode := values.Get("device_code")
166 if deviceCode == "" {
167 http.Error(w, "device_code is required", http.StatusBadRequest)
168 return
169 }
170 grantType := values.Get("grant_type")
171 if grantType != deviceCodeGrantType {
172 http.Error(w, "invalid grant_type", http.StatusBadRequest)
173 return
174 }
175 responseVersion := values.Get("token_response_version")
176
177 authCode, err := a.admin.DB.FindDeviceAuthCodeByDeviceCode(r.Context(), deviceCode)
178 if err != nil {
179 if errors.Is(err, database.ErrNotFound) {
180 http.Error(w, fmt.Sprintf("no such device code: %s found", deviceCode), http.StatusBadRequest)
181 return
182 }
183 internalServerError(w, fmt.Errorf("failed to get auth code for deviceCode: %s, %w", deviceCode, err))
184 return
185 }
186 clientID := values.Get("client_id")
187 if clientID != authCode.ClientID {
188 http.Error(w, "invalid client_id", http.StatusBadRequest)
189 return
190 }
191
192 if authCode.Expiry.Before(time.Now()) {
193 http.Error(w, "expired_token", http.StatusUnauthorized)
194 return
195 }
196 if authCode.ApprovalState == database.DeviceAuthCodeStateRejected {
197 err = a.admin.DB.DeleteDeviceAuthCode(r.Context(), deviceCode)
198 if err != nil {
199 internalServerError(w, fmt.Errorf("failed to clean up rejected code: %s, %w", deviceCode, err))
200 return
201 }
202 http.Error(w, "rejected", http.StatusUnauthorized)
203 return
204 }
205 if authCode.ApprovalState == database.DeviceAuthCodeStatePending {
206 http.Error(w, "authorization_pending", http.StatusUnauthorized)
207 return
208 }
209 if authCode.ApprovalState != database.DeviceAuthCodeStateApproved || authCode.UserID == nil {
210 internalServerError(w, fmt.Errorf("inconsistent state, %w", errors.New("server error")))
211 return
212 }
213 // TODO handle too many requests
214
215 authToken, err := a.admin.IssueUserAuthToken(r.Context(), *authCode.UserID, authCode.ClientID, "", nil, nil, false)
216 if err != nil {
217 internalServerError(w, fmt.Errorf("failed to issue access token, %w", err))
218 return
219 }
220
221 err = a.admin.DB.DeleteDeviceAuthCode(r.Context(), deviceCode)

Callers 1

getAccessTokenMethod · 0.95

Implementers 1

DeviceAuthenticatorcli/pkg/deviceauth/authenticator.go

Calls 12

internalServerErrorFunction · 0.85
GetMethod · 0.65
ContextMethod · 0.65
ErrorfMethod · 0.65
DeleteDeviceAuthCodeMethod · 0.65
IssueUserAuthTokenMethod · 0.65
StringMethod · 0.65
TokenMethod · 0.65
ErrorMethod · 0.45
SetMethod · 0.45
WriteMethod · 0.45

Tested by

no test coverage detected