diff --git a/carddav/carddav.go b/carddav/carddav.go index 6779d10..f7dbf8e 100644 --- a/carddav/carddav.go +++ b/carddav/carddav.go @@ -17,12 +17,14 @@ type AddressBook struct { } type AddressBookQuery struct { - Props []string + Props []string + AllProp bool } type AddressBookMultiGet struct { - Paths []string - Props []string + Paths []string + Props []string + AllProp bool } type AddressObject struct { diff --git a/carddav/client.go b/carddav/client.go index 06693a0..0471d72 100644 --- a/carddav/client.go +++ b/carddav/client.go @@ -142,10 +142,14 @@ func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, err return l, nil } -func encodeAddressPropReq(props []string) (*internal.Prop, error) { +func encodeAddressPropReq(props []string, allProp bool) (*internal.Prop, error) { var addrDataReq addressDataReq - for _, name := range props { - addrDataReq.Props = append(addrDataReq.Props, prop{Name: name}) + if allProp { + addrDataReq.Allprop = &struct{}{} + } else { + for _, name := range props { + addrDataReq.Props = append(addrDataReq.Props, prop{Name: name}) + } } getLastModReq := internal.NewRawXMLElement(internal.GetLastModifiedName, nil, nil) @@ -199,11 +203,13 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) { func (c *Client) QueryAddressBook(addressBook string, query *AddressBookQuery) ([]AddressObject, error) { var props []string + var allProp bool if query != nil { props = query.Props + allProp = query.AllProp } - propReq, err := encodeAddressPropReq(props) + propReq, err := encodeAddressPropReq(props, allProp) if err != nil { return nil, err } @@ -227,11 +233,13 @@ func (c *Client) QueryAddressBook(addressBook string, query *AddressBookQuery) ( func (c *Client) MultiGetAddressBook(path string, multiGet *AddressBookMultiGet) ([]AddressObject, error) { var props []string + var allProp bool if multiGet != nil { props = multiGet.Props + allProp = multiGet.AllProp } - propReq, err := encodeAddressPropReq(props) + propReq, err := encodeAddressPropReq(props, allProp) if err != nil { return nil, err } diff --git a/carddav/elements.go b/carddav/elements.go index 799da11..b418abf 100644 --- a/carddav/elements.go +++ b/carddav/elements.go @@ -82,9 +82,9 @@ func newProp(name string, noValue bool) *internal.RawXMLValue { // https://tools.ietf.org/html/rfc6352#section-10.4 type addressDataReq struct { - XMLName xml.Name `xml:"urn:ietf:params:xml:ns:carddav address-data"` - Props []prop `xml:"prop"` - // TODO: allprop + XMLName xml.Name `xml:"urn:ietf:params:xml:ns:carddav address-data"` + Props []prop `xml:"prop"` + Allprop *struct{} `xml:"allprop"` } // https://tools.ietf.org/html/rfc6352#section-10.4.2 diff --git a/carddav/server.go b/carddav/server.go index 6a67283..671d3d4 100644 --- a/carddav/server.go +++ b/carddav/server.go @@ -72,6 +72,10 @@ func (h *Handler) handleQuery(w http.ResponseWriter, query *addressbookQuery) er if err := query.Prop.Decode(&addressData); err != nil && !internal.IsMissingProp(err) { return err } + if addressData.Allprop != nil && len(addressData.Props) > 0 { + return internal.HTTPErrorf(http.StatusBadRequest, "carddav: only one of allprop or prop can be specified in address-data") + } + q.AllProp = addressData.Allprop != nil for _, p := range addressData.Props { q.Props = append(q.Props, p.Name) } @@ -104,6 +108,8 @@ func (h *Handler) handleQuery(w http.ResponseWriter, query *addressbookQuery) er func (h *Handler) handleMultiget(w http.ResponseWriter, multiget *addressbookMultiget) error { var resps []internal.Response for _, href := range multiget.Hrefs { + // TODO: only get a subset of the vCard fields, depending on the + // multiget query ao, err := h.Backend.GetAddressObject(href.Path) if err != nil { return err // TODO: create internal.Response with error