~/Projects/webdav-go
git clone https://code.lsong.org/webdav-go
Commit
- Commit
- db966a275c93fd5dd0d63bf7522f52dfba848090
- Author
- Conrad Hoffmann <[email protected]>
- Date
- 2022-05-19 14:26:35 +0200 +0200
- Diffstat
carddav/match.go | 32 +++++++++++++++++++++++++++++--- carddav/match_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++
carddav: do property filtering in match.Filter() With this commit, the list of AddressObjects returned by `Filter()` will always be a correct response to the query argument passed to it, even if the input list contained objects with arbitraty properties present.
diff --git a/carddav/match.go b/carddav/match.go index d0c6450b81d98b7ab1f57103fbadbc735960f12d..dd5b4d8e0d917bb6dcb7a29b75f9bd615e11a336 100644 --- a/carddav/match.go +++ b/carddav/match.go @@ -7,6 +7,34 @@ "github.com/emersion/go-vcard" ) +func filterProperties(req AddressDataRequest, ao AddressObject) AddressObject { + if req.AllProp || len(req.Props) == 0 { + return ao + } + + if len(ao.Card) == 0 { + panic("request to process empty vCard") + } + + result := AddressObject{ + Path: ao.Path, + ModTime: ao.ModTime, + ETag: ao.ETag, + } + + result.Card = make(vcard.Card) + // result would be invalid w/o version + result.Card[vcard.FieldVersion] = ao.Card[vcard.FieldVersion] + for _, prop := range req.Props { + value, ok := ao.Card[prop] + if ok { + result.Card[prop] = value + } + } + + return result +} + // Filter returns the filtered list of address objects matching the provided query. // A nil query will return the full list of address objects. func Filter(query *AddressBookQuery, aos []AddressObject) ([]AddressObject, error) { @@ -29,9 +57,7 @@ if !ok { continue } - // TODO properties are not currently filtered even if requested - - out = append(out, ao) + out = append(out, filterProperties(query.DataRequest, ao)) if len(out) >= n { break } diff --git a/carddav/match_test.go b/carddav/match_test.go index 9451ffeb03f19528c1c46a79af8105d1670a83a1..d0f84038e3a1ac9c9d21791b664dfe44f953bcbd 100644 --- a/carddav/match_test.go +++ b/carddav/match_test.go @@ -46,6 +46,11 @@ N:Gopher;Carla;;; EMAIL;PID=1.1:[email protected] CLIENTPIDMAP:1;urn:uuid:53e374d9-337e-4727-8803-a1e9c14e0553 END:VCARD`) + carlaFiltered := newAO(`BEGIN:VCARD +VERSION:4.0 +UID:urn:uuid:4fbe8971-0bc3-424c-9c26-36c3e1eff6b3 +EMAIL;PID=1.1:[email protected] +END:VCARD`) for _, tc := range []struct { name string @@ -176,6 +181,46 @@ }, }, addrs: []AddressObject{alice, bob, carla}, "github.com/emersion/go-vcard" + "strings" + }, + { + name: "email-match-filter-properties", + query: &AddressBookQuery{ + DataRequest: AddressDataRequest{ + Props: []string{ + vcard.FieldVersion, + vcard.FieldUID, + vcard.FieldEmail, + }, + }, + PropFilters: []PropFilter{ + { + Name: vcard.FieldEmail, + TextMatches: []TextMatch{{Text: "carla"}}, + }, + }, + }, + addrs: []AddressObject{alice, bob, carla}, + want: []AddressObject{carlaFiltered}, + }, + { + name: "email-match-filter-properties-always-returns-version", + query: &AddressBookQuery{ + DataRequest: AddressDataRequest{ + Props: []string{ + vcard.FieldUID, + vcard.FieldEmail, + }, + }, + PropFilters: []PropFilter{ + { + Name: vcard.FieldEmail, + TextMatches: []TextMatch{{Text: "carla"}}, + }, + }, + }, + addrs: []AddressObject{alice, bob, carla}, + return AddressObject{ "strings" }, } {