middleware.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package management
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. )
  7. type ctxKey int
  8. const (
  9. accessClaimsCtxKey ctxKey = iota
  10. )
  11. const (
  12. connectorIDQuery = "connector_id"
  13. accessTokenQuery = "access_token"
  14. )
  15. var (
  16. errMissingAccessToken = managementError{Code: 1001, Message: "missing access_token query parameter"}
  17. )
  18. // HTTP middleware setting the parsed access_token claims in the request context
  19. func ValidateAccessTokenQueryMiddleware(next http.Handler) http.Handler {
  20. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  21. // Validate access token
  22. accessToken := r.URL.Query().Get("access_token")
  23. if accessToken == "" {
  24. writeHTTPErrorResponse(w, errMissingAccessToken)
  25. return
  26. }
  27. token, err := parseToken(accessToken)
  28. if err != nil {
  29. writeHTTPErrorResponse(w, errMissingAccessToken)
  30. return
  31. }
  32. r = r.WithContext(context.WithValue(r.Context(), accessClaimsCtxKey, token))
  33. next.ServeHTTP(w, r)
  34. })
  35. }
  36. // Middleware validation error struct for returning to the eyeball
  37. type managementError struct {
  38. Code int `json:"code,omitempty"`
  39. Message string `json:"message,omitempty"`
  40. }
  41. func (m *managementError) Error() string {
  42. return m.Message
  43. }
  44. // Middleware validation error HTTP response JSON for returning to the eyeball
  45. type managementErrorResponse struct {
  46. Success bool `json:"success,omitempty"`
  47. Errors []managementError `json:"errors,omitempty"`
  48. }
  49. // writeErrorResponse will respond to the eyeball with basic HTTP JSON payloads with validation failure information
  50. func writeHTTPErrorResponse(w http.ResponseWriter, errResp managementError) {
  51. w.Header().Set("Content-Type", "application/json")
  52. w.WriteHeader(http.StatusBadRequest)
  53. err := json.NewEncoder(w).Encode(managementErrorResponse{
  54. Success: false,
  55. Errors: []managementError{errResp},
  56. })
  57. // we have already written the header, so write a basic error response if unable to encode the error
  58. if err != nil {
  59. // fallback to text message
  60. http.Error(w, fmt.Sprintf(
  61. "%d %s",
  62. http.StatusBadRequest,
  63. http.StatusText(http.StatusBadRequest),
  64. ), http.StatusBadRequest)
  65. }
  66. }