(w http.ResponseWriter, r *http.Request)
| 228 | var errParse = errors.DefineAborted("parse", "request body parsing") |
| 229 | |
| 230 | func (s *server) Token(w http.ResponseWriter, r *http.Request) { |
| 231 | // Convert request through tokenRequest so that we can accept both forms and JSON. |
| 232 | var tokenRequest tokenRequest |
| 233 | switch r.Header.Get("Content-Type") { |
| 234 | case "application/json": |
| 235 | if err := json.NewDecoder(r.Body).Decode(&tokenRequest); err != nil { |
| 236 | webhandlers.Error(w, r, errParse.WithCause(err)) |
| 237 | return |
| 238 | } |
| 239 | default: |
| 240 | if err := r.ParseForm(); err != nil { |
| 241 | webhandlers.Error(w, r, errParse.WithCause(err)) |
| 242 | return |
| 243 | } |
| 244 | if err := s.schemaDecoder.Decode(&tokenRequest, r.Form); err != nil { |
| 245 | webhandlers.Error(w, r, errParse.WithCause(err)) |
| 246 | return |
| 247 | } |
| 248 | } |
| 249 | if username, password, ok := r.BasicAuth(); ok { |
| 250 | tokenRequest.ClientID, tokenRequest.ClientSecret = username, password |
| 251 | } |
| 252 | if err := tokenRequest.ValidateContext(r.Context()); err != nil { |
| 253 | webhandlers.Error(w, r, err) |
| 254 | return |
| 255 | } |
| 256 | |
| 257 | r = r.WithContext( |
| 258 | log.NewContextWithField(r.Context(), "oauth_client_id", tokenRequest.ClientID), |
| 259 | ) |
| 260 | |
| 261 | values := make(url.Values) |
| 262 | if err := schema.NewEncoder().Encode(tokenRequest, values); err != nil { |
| 263 | webhandlers.Error(w, r, err) |
| 264 | return |
| 265 | } |
| 266 | r.Form = values |
| 267 | r.PostForm = values |
| 268 | |
| 269 | oauth2 := s.oauth2(r.Context()) |
| 270 | resp := oauth2.NewResponse() |
| 271 | defer resp.Close() |
| 272 | ar := oauth2.HandleAccessRequest(resp, r) |
| 273 | if ar == nil { |
| 274 | s.output(w, r, resp) |
| 275 | return |
| 276 | } |
| 277 | |
| 278 | client := ar.Client.(osinClient).Client |
| 279 | userIDs := ar.UserData.(userData).UserSessionIdentifiers.GetUserIds() |
| 280 | ar.GenerateRefresh = clientHasGrant(client, ttnpb.GrantType_GRANT_REFRESH_TOKEN) |
| 281 | switch ar.Type { |
| 282 | case osin.AUTHORIZATION_CODE: |
| 283 | ar.Authorized = clientHasGrant(client, ttnpb.GrantType_GRANT_AUTHORIZATION_CODE) |
| 284 | case osin.REFRESH_TOKEN: |
| 285 | ar.Authorized = clientHasGrant(client, ttnpb.GrantType_GRANT_REFRESH_TOKEN) |
| 286 | case osin.PASSWORD: |
| 287 | if clientHasGrant(client, ttnpb.GrantType_GRANT_PASSWORD) { |
nothing calls this directly
no test coverage detected