Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions cmd/api/src/api/middleware/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"net/http"
"slices"

"github.com/gorilla/mux"

Expand All @@ -31,18 +32,26 @@ import (

// FilterMiddleware parses query parameter filters from the request, validates them against the supplied
// params.Filterable definition, and enriches the BloodHound context with the resulting params.Filters map.
// Query parameters named in additionalIgnoredParameters are skipped during filter parsing but remain
// available on the request.
//
// When filterable is nil the middleware performs no parsing and passes the request through unchanged. If
// the filters are malformed, reference a column that cannot be filtered, or use an operator the column
// does not support, the middleware writes a 400 response and halts the chain.
func FilterMiddleware(filterable params.Filterable) mux.MiddlewareFunc {
func FilterMiddleware(filterable params.Filterable, additionalIgnoredParameters ...string) mux.MiddlewareFunc {
if filterable == nil {
return func(next http.Handler) http.Handler {
return next
}
}

parser := params.NewQueryParameterFilterParser(append(model.IgnoreFilters(), model.AllPaginationQueryParameters()...)...)
ignoredParameters := slices.Concat(
model.IgnoreFilters(),
model.AllPaginationQueryParameters(),
additionalIgnoredParameters,
)

parser := params.NewQueryParameterFilterParser(ignoredParameters...)

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
Expand Down
5 changes: 3 additions & 2 deletions cmd/api/src/api/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ func (s *Route) CheckFeatureFlag(ff featureFlag, flagKey string) *Route {

// WithFilters wires the query parameter filter middleware onto the route, validating any filters against
// the supplied params.Filterable definition and enriching the request context with the parsed filters.
func (s *Route) WithFilters(filterable params.Filterable) *Route {
s.handler.Use(middleware.FilterMiddleware(filterable))
// Query parameters named in additionalIgnoredParameters are skipped during filter parsing.
func (s *Route) WithFilters(filterable params.Filterable, additionalIgnoredParameters ...string) *Route {
s.handler.Use(middleware.FilterMiddleware(filterable, additionalIgnoredParameters...))
return s
}

Expand Down
Loading