mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 08:14:15 +00:00
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.
This commit is contained in:
parent
21aea26c70
commit
db966a275c
@ -7,6 +7,34 @@ import (
|
|||||||
"github.com/emersion/go-vcard"
|
"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.
|
// Filter returns the filtered list of address objects matching the provided query.
|
||||||
// A nil query will return the full list of address objects.
|
// A nil query will return the full list of address objects.
|
||||||
func Filter(query *AddressBookQuery, aos []AddressObject) ([]AddressObject, error) {
|
func Filter(query *AddressBookQuery, aos []AddressObject) ([]AddressObject, error) {
|
||||||
@ -29,9 +57,7 @@ func Filter(query *AddressBookQuery, aos []AddressObject) ([]AddressObject, erro
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO properties are not currently filtered even if requested
|
out = append(out, filterProperties(query.DataRequest, ao))
|
||||||
|
|
||||||
out = append(out, ao)
|
|
||||||
if len(out) >= n {
|
if len(out) >= n {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,11 @@ FN;PID=1.1:Carla Gopher
|
|||||||
N:Gopher;Carla;;;
|
N:Gopher;Carla;;;
|
||||||
EMAIL;PID=1.1:carla@example.com
|
EMAIL;PID=1.1:carla@example.com
|
||||||
CLIENTPIDMAP:1;urn:uuid:53e374d9-337e-4727-8803-a1e9c14e0553
|
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:carla@example.com
|
||||||
END:VCARD`)
|
END:VCARD`)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
@ -177,6 +182,45 @@ END:VCARD`)
|
|||||||
addrs: []AddressObject{alice, bob, carla},
|
addrs: []AddressObject{alice, bob, carla},
|
||||||
want: []AddressObject{},
|
want: []AddressObject{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
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},
|
||||||
|
want: []AddressObject{carlaFiltered},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
got, err := Filter(tc.query, tc.addrs)
|
got, err := Filter(tc.query, tc.addrs)
|
||||||
|
Loading…
Reference in New Issue
Block a user