diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a5f5b5f6a..5093e28515b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ ### Bug Fixes 1. [21345](https://github.com/influxdata/influxdb/pull/21345): Deprecate the unsupported `PostSetupUser` API. -2. [21356](https://github.com/influxdata/influxdb/pull/21356): disable MergeFiltersRule until it is more stable +1. [21356](https://github.com/influxdata/influxdb/pull/21356): disable MergeFiltersRule until it is more stable +1. [21369](https://github.com/influxdata/influxdb/pull/21369): Add limits to the `/api/v2/delete` endpoint for start and stop times with error messages. ## v2.0.6 [2021-04-29] diff --git a/http/delete_handler.go b/http/delete_handler.go index 528466f8411..bcf1569ff51 100644 --- a/http/delete_handler.go +++ b/http/delete_handler.go @@ -9,6 +9,7 @@ import ( "time" "github.com/influxdata/influxdb/v2/kit/platform/errors" + "github.com/influxdata/influxdb/v2/models" "github.com/influxdata/httprouter" "github.com/influxdata/influxdb/v2" @@ -57,6 +58,11 @@ const ( prefixDelete = "/api/v2/delete" ) +var ( + msgStartTooSoon = fmt.Sprintf("invalid start time, start time must not be before %s", time.Unix(0, models.MinNanoTime).UTC().Format(time.RFC3339Nano)) + msgStopTooLate = fmt.Sprintf("invalid stop time, stop time must not be after %s", time.Unix(0, models.MaxNanoTime).UTC().Format(time.RFC3339Nano)) +) + // NewDeleteHandler creates a new handler at /api/v2/delete to receive delete requests. func NewDeleteHandler(log *zap.Logger, b *DeleteBackend) *DeleteHandler { h := &DeleteHandler{ @@ -197,6 +203,13 @@ func (dr *deleteRequest) UnmarshalJSON(b []byte) error { Msg: "invalid RFC3339Nano for field start, please format your time with RFC3339Nano format, example: 2009-01-02T23:00:00Z", } } + if err = models.CheckTime(start); err != nil { + return &errors.Error{ + Code: errors.EInvalid, + Op: "http/Delete", + Msg: msgStartTooSoon, + } + } dr.Start = start.UnixNano() stop, err := time.Parse(time.RFC3339Nano, drd.Stop) @@ -207,6 +220,13 @@ func (dr *deleteRequest) UnmarshalJSON(b []byte) error { Msg: "invalid RFC3339Nano for field stop, please format your time with RFC3339Nano format, example: 2009-01-01T23:00:00Z", } } + if err = models.CheckTime(stop); err != nil { + return &errors.Error{ + Code: errors.EInvalid, + Op: "http/Delete", + Msg: msgStopTooLate, + } + } dr.Stop = stop.UnixNano() node, err := predicate.Parse(drd.Predicate) if err != nil { diff --git a/http/delete_test.go b/http/delete_test.go index 6e4d4af0a00..b12f85547a8 100644 --- a/http/delete_test.go +++ b/http/delete_test.go @@ -3,13 +3,16 @@ package http import ( "bytes" "context" + "fmt" "io/ioutil" "net/http" "net/http/httptest" "testing" + "time" "github.com/influxdata/influxdb/v2/kit/platform" "github.com/influxdata/influxdb/v2/kit/platform/errors" + "github.com/influxdata/influxdb/v2/models" "github.com/influxdata/influxdb/v2" pcontext "github.com/influxdata/influxdb/v2/context" @@ -91,6 +94,40 @@ func TestDelete(t *testing.T) { }`, }, }, + { + name: "start time too soon", + args: args{ + queryParams: map[string][]string{}, + body: []byte(fmt.Sprintf(`{"start":"%s"}`, time.Unix(0, models.MinNanoTime-1).UTC().Format(time.RFC3339Nano))), + authorizer: &influxdb.Authorization{UserID: user1ID}, + }, + fields: fields{}, + wants: wants{ + statusCode: http.StatusBadRequest, + contentType: "application/json; charset=utf-8", + body: fmt.Sprintf(`{ + "code": "invalid", + "message": "invalid request; error parsing request json: %s" + }`, msgStartTooSoon), + }, + }, + { + name: "stop time too late", + args: args{ + queryParams: map[string][]string{}, + body: []byte(fmt.Sprintf(`{"start":"2020-01-01T01:01:01Z", "stop":"%s"}`, time.Unix(0, models.MaxNanoTime+1).UTC().Format(time.RFC3339Nano))), + authorizer: &influxdb.Authorization{UserID: user1ID}, + }, + fields: fields{}, + wants: wants{ + statusCode: http.StatusBadRequest, + contentType: "application/json; charset=utf-8", + body: fmt.Sprintf(`{ + "code": "invalid", + "message": "invalid request; error parsing request json: %s" + }`, msgStopTooLate), + }, + }, { name: "missing org", args: args{