From f3a718c1199640207c6f0a9dd5cb5f09d8af8cf5 Mon Sep 17 00:00:00 2001 From: Oliver Calder Date: Sun, 19 Nov 2023 22:23:28 -0600 Subject: [PATCH] fix(daemon): handle invalid notice types in filter (#329) 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. --- internals/daemon/api_notices.go | 5 ++++ internals/daemon/api_notices_test.go | 40 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/internals/daemon/api_notices.go b/internals/daemon/api_notices.go index 912dd7eb9..2882c5991 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 { + // Caller did provide a types filter, but they're all invalid notice types. + // Return no notices, rather than the default of all notices. + 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..e01d35cb5 100644 --- a/internals/daemon/api_notices_test.go +++ b/internals/daemon/api_notices_test.go @@ -165,6 +165,46 @@ 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) + 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)