From c40bd32084ebbafe92982591e4db834e93574c20 Mon Sep 17 00:00:00 2001 From: Oliver Calder Date: Thu, 16 Nov 2023 13:35:48 -0600 Subject: [PATCH] daemon: fix handling of invalid notice types in filter Invalid notice types are ignored when parsing the API request to construct the notice filter. However, if only invalid notice types are included in the request, discarding all types results in a filter indistinguishable from one which never had any types in the first place, and thus should return notices of any type. This commit fixes this behaviour, so no notices are returned if only invalid notice types are requested. Signed-off-by: Oliver Calder --- internals/daemon/api_notices.go | 5 ++++ internals/daemon/api_notices_test.go | 41 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/internals/daemon/api_notices.go b/internals/daemon/api_notices.go index 47b002df5..daf678ecd 100644 --- a/internals/daemon/api_notices.go +++ b/internals/daemon/api_notices.go @@ -53,6 +53,11 @@ func v1GetNotices(c *Command, r *http.Request, _ *UserState) Response { } types = append(types, noticeType) } + if len(types) == 0 && len(typeStrs) > 0 { + // Only requested invalid notice types. Return no notices, rather than + // all, the latter of which would occur if the types filter was empty. + return SyncResponse([]*state.Notice{}) + } keys := strutil.MultiCommaSeparatedList(query["keys"]) diff --git a/internals/daemon/api_notices_test.go b/internals/daemon/api_notices_test.go index ef760801e..cda49fa48 100644 --- a/internals/daemon/api_notices_test.go +++ b/internals/daemon/api_notices_test.go @@ -165,6 +165,47 @@ func (s *apiSuite) TestNoticesFilterMultipleKeys(c *C) { c.Assert(n["key"], Equals, "danger") } +func (s *apiSuite) TestNoticesFilterInvalidTypes(c *C) { + s.daemon(c) + + st := s.d.Overlord().State() + st.Lock() + addNotice(c, st, state.ChangeUpdateNotice, "123", nil) + time.Sleep(time.Microsecond) + addNotice(c, st, state.WarningNotice, "danger", nil) + st.Unlock() + + // Check that invalid types are discarded, and notices with remaining + // types are requested as expected, without error. + req, err := http.NewRequest("GET", "/v1/notices?types=foo&types=warning&types=bar,baz", nil) + c.Assert(err, IsNil) + noticesCmd := apiCmd("/v1/notices") + rsp, ok := noticesCmd.GET(noticesCmd, req, nil).(*resp) + c.Assert(ok, Equals, true) + + c.Check(rsp.Type, Equals, ResponseTypeSync) + c.Check(rsp.Status, Equals, http.StatusOK) + notices, ok := rsp.Result.([]*state.Notice) + c.Assert(ok, Equals, true) + c.Assert(notices, HasLen, 1) + n := noticeToMap(c, notices[0]) + c.Assert(n["type"], Equals, "warning") + + // Check that if all types are invalid, no notices are returned, and there + // is no error. + req, err = http.NewRequest("GET", "/v1/notices?types=foo&types=bar,baz", nil) + c.Assert(err, IsNil) + noticesCmd = apiCmd("/v1/notices") + rsp, ok = noticesCmd.GET(noticesCmd, req, nil).(*resp) + c.Assert(ok, Equals, true) + + c.Check(rsp.Type, Equals, ResponseTypeSync) + c.Check(rsp.Status, Equals, http.StatusOK) + notices, ok = rsp.Result.([]*state.Notice) + c.Assert(ok, Equals, true) + c.Assert(notices, HasLen, 0) +} + func (s *apiSuite) TestNoticesWait(c *C) { s.daemon(c)