swagger:route PUT /admin/oauth2/auth/requests/device/accept oAuth2 acceptUserCodeRequest # Accepts a device grant user_code request Accepts a device grant user_code request Consumes: - application/json Produces: - application/json Schemes: http, https Responses: 200: oAuth2RedirectTo
(w http.ResponseWriter, r *http.Request)
| 1046 | // Extensions: |
| 1047 | // x-ory-ratelimit-bucket: hydra-admin-low |
| 1048 | func (h *Handler) acceptUserCodeRequest(w http.ResponseWriter, r *http.Request) { |
| 1049 | ctx := r.Context() |
| 1050 | |
| 1051 | challenge := r.URL.Query().Get("device_challenge") |
| 1052 | if challenge == "" { |
| 1053 | h.r.Writer().WriteError(w, r, errors.WithStack(fosite.ErrInvalidRequest.WithHint(`Query parameter 'device_challenge' is not defined but should have been.`))) |
| 1054 | return |
| 1055 | } |
| 1056 | |
| 1057 | var reqBody flow.AcceptDeviceUserCodeRequest |
| 1058 | if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil { |
| 1059 | h.r.Writer().WriteError(w, r, errors.WithStack(fosite.ErrInvalidRequest.WithWrap(err).WithHintf("Unable to decode request body: %s", err.Error()))) |
| 1060 | return |
| 1061 | } |
| 1062 | |
| 1063 | if reqBody.UserCode == "" { |
| 1064 | h.r.Writer().WriteError(w, r, errors.WithStack(fosite.ErrInvalidRequest.WithHint("Field 'user_code' must not be empty."))) |
| 1065 | return |
| 1066 | } |
| 1067 | |
| 1068 | f, err := flow.DecodeFromDeviceChallenge(ctx, h.r, challenge) |
| 1069 | if err != nil { |
| 1070 | h.r.Writer().WriteError(w, r, err) |
| 1071 | return |
| 1072 | } |
| 1073 | |
| 1074 | userCodeSignature, err := h.r.UserCodeStrategy().UserCodeSignature(r.Context(), reqBody.UserCode) |
| 1075 | if err != nil { |
| 1076 | h.r.Writer().WriteError(w, r, fosite.ErrServerError.WithWrap(err).WithHint(`The 'user_code' signature could not be computed.`)) |
| 1077 | return |
| 1078 | } |
| 1079 | |
| 1080 | userCodeRequest, err := h.r.OAuth2Storage().GetUserCodeSession(r.Context(), userCodeSignature, nil) |
| 1081 | if err != nil { |
| 1082 | h.r.Writer().WriteError(w, r, fosite.ErrInvalidRequest.WithWrap(err).WithHint(`The 'user_code' session could not be found or has expired or is otherwise malformed.`)) |
| 1083 | return |
| 1084 | } |
| 1085 | |
| 1086 | if err := h.r.UserCodeStrategy().ValidateUserCode(ctx, userCodeRequest, reqBody.UserCode); err != nil { |
| 1087 | h.r.Writer().WriteError(w, r, fosite.ErrInvalidRequest.WithWrap(err).WithHint(`The 'user_code' session could not be found or has expired or is otherwise malformed.`)) |
| 1088 | return |
| 1089 | } |
| 1090 | |
| 1091 | p := flow.HandledDeviceUserAuthRequest{ |
| 1092 | Client: userCodeRequest.GetClient().(*client.Client), |
| 1093 | DeviceCodeRequestID: userCodeRequest.GetID(), |
| 1094 | RequestedScope: []string(userCodeRequest.GetRequestedScopes()), |
| 1095 | RequestedAudience: []string(userCodeRequest.GetRequestedAudience()), |
| 1096 | } |
| 1097 | |
| 1098 | // Append the client_id to the original RequestURL, as it is needed for the login flow |
| 1099 | reqURL, err := url.Parse(f.RequestURL) |
| 1100 | if err != nil { |
| 1101 | h.r.Writer().WriteError(w, r, errors.WithStack(err)) |
| 1102 | return |
| 1103 | } |
| 1104 | |
| 1105 | if reqURL.Query().Get("client_id") == "" { |
nothing calls this directly
no test coverage detected