// Handles all OAuth 2.0 grant types (POST /oauth2/api/v1/tokens func handleTokens(w http.ResponseWriter, r *http.Request) { // Parse the form so r.Form becomes available if err := r.ParseForm(); err != nil { json.Error(w, err.Error(), http.StatusInternalServerError) return } // Map of grant types against handler functions grantTypes := map[string]func(w http.ResponseWriter, r *http.Request, client *Client){ "authorization_code": theService.authorizationCodeGrant, "password": theService.passwordGrant, "client_credentials": theService.clientCredentialsGrant, "refresh_token": theService.refreshTokenGrant, } // Check the grant type grantHandler, ok := grantTypes[r.Form.Get("grant_type")] if !ok { json.Error(w, "Invalid grant type", http.StatusBadRequest) return } // Get client credentials from basic auth clientID, secret, ok := r.BasicAuth() if !ok { json.UnauthorizedError(w, "Client authentication required") return } // Authenticate the client client, err := theService.AuthClient(clientID, secret) if err != nil { // For security reasons, return a general error message json.UnauthorizedError(w, "Client authentication required") return } // Execute the correct function based on the grant type grantHandler(w, r, client) }
func (s *Service) passwordGrant(w http.ResponseWriter, r *http.Request, client *Client) { // Get user credentials from form data username := r.Form.Get("username") // usually an email password := r.Form.Get("password") // Authenticate the user user, err := s.AuthUser(username, password) if err != nil { // For security reasons, return a general error message json.UnauthorizedError(w, "User authentication required") return } // Get the scope string scope, err := s.GetScope(r.Form.Get("scope")) if err != nil { json.Error(w, err.Error(), http.StatusBadRequest) return } // Create a new access token accessToken, err := s.GrantAccessToken( client, // client user, // user scope, // scope ) if err != nil { json.Error(w, err.Error(), http.StatusInternalServerError) return } // Create or retrieve a refresh token refreshToken, err := s.GetOrCreateRefreshToken( client, // client user, // user scope, // scope ) if err != nil { json.Error(w, err.Error(), http.StatusInternalServerError) return } // Write the access token to a JSON response writeJSON(w, s.cnf.Oauth.AccessTokenLifetime, accessToken, refreshToken) }