carddav: expose supported address data in client

This commit is contained in:
Simon Ser 2020-02-27 12:36:14 +01:00
parent 514296664c
commit abadf534f4
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
4 changed files with 49 additions and 16 deletions

View File

@ -9,11 +9,29 @@ import (
"github.com/emersion/go-vcard" "github.com/emersion/go-vcard"
) )
type AddressDataType struct {
ContentType string
Version string
}
type AddressBook struct { type AddressBook struct {
Path string Path string
Name string Name string
Description string Description string
MaxResourceSize int64 MaxResourceSize int64
SupportedAddressData []AddressDataType
}
func (ab *AddressBook) SupportsAddressData(contentType, version string) bool {
if len(ab.SupportedAddressData) == 0 {
return contentType == "text/vcard" && version == "3.0"
}
for _, t := range ab.SupportedAddressData {
if t.ContentType == contentType && t.Version == version {
return true
}
}
return false
} }
type AddressBookQuery struct { type AddressBookQuery struct {

View File

@ -94,12 +94,21 @@ func (c *Client) FindAddressBookHomeSet(principal string) (string, error) {
return prop.Href.Path, nil return prop.Href.Path, nil
} }
func decodeSupportedAddressData(supported *supportedAddressData) []AddressDataType {
l := make([]AddressDataType, len(supported.Types))
for i, t := range supported.Types {
l[i] = AddressDataType{t.ContentType, t.Version}
}
return l
}
func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, error) { func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, error) {
propfind := internal.NewPropNamePropfind( propfind := internal.NewPropNamePropfind(
internal.ResourceTypeName, internal.ResourceTypeName,
internal.DisplayNameName, internal.DisplayNameName,
addressBookDescriptionName, addressBookDescriptionName,
maxResourceSizeName, maxResourceSizeName,
supportedAddressDataName,
) )
ms, err := c.ic.Propfind(addressBookHomeSet, internal.DepthOne, propfind) ms, err := c.ic.Propfind(addressBookHomeSet, internal.DepthOne, propfind)
if err != nil { if err != nil {
@ -139,11 +148,17 @@ func (c *Client) FindAddressBooks(addressBookHomeSet string) ([]AddressBook, err
return nil, fmt.Errorf("carddav: max-resource-size must be a positive integer") return nil, fmt.Errorf("carddav: max-resource-size must be a positive integer")
} }
var supported supportedAddressData
if err := resp.DecodeProp(&supported); err != nil && !internal.IsNotFound(err) {
return nil, err
}
l = append(l, AddressBook{ l = append(l, AddressBook{
Path: path, Path: path,
Name: dispName.Name, Name: dispName.Name,
Description: desc.Description, Description: desc.Description,
MaxResourceSize: maxResSize.Size, MaxResourceSize: maxResSize.Size,
SupportedAddressData: decodeSupportedAddressData(&supported),
}) })
} }

View File

@ -14,7 +14,7 @@ var (
addressBookName = xml.Name{namespace, "addressbook"} addressBookName = xml.Name{namespace, "addressbook"}
addressBookDescriptionName = xml.Name{namespace, "addressbook-description"} addressBookDescriptionName = xml.Name{namespace, "addressbook-description"}
addressBookSupportedAddressData = xml.Name{namespace, "addressbook-supported-address-data"} supportedAddressDataName = xml.Name{namespace, "supported-address-data"}
maxResourceSizeName = xml.Name{namespace, "max-resource-size"} maxResourceSizeName = xml.Name{namespace, "max-resource-size"}
addressBookQueryName = xml.Name{namespace, "addressbook-query"} addressBookQueryName = xml.Name{namespace, "addressbook-query"}
@ -35,8 +35,8 @@ type addressbookDescription struct {
} }
// https://tools.ietf.org/html/rfc6352#section-6.2.2 // https://tools.ietf.org/html/rfc6352#section-6.2.2
type addressbookSupportedAddressData struct { type supportedAddressData struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:carddav addressbook-supported-address-data"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:carddav supported-address-data"`
Types []addressDataType `xml:"address-data-type"` Types []addressDataType `xml:"address-data-type"`
} }

View File

@ -321,8 +321,8 @@ func (b *backend) propfindAddressBook(propfind *internal.Propfind, ab *AddressBo
addressBookDescriptionName: func(*internal.RawXMLValue) (interface{}, error) { addressBookDescriptionName: func(*internal.RawXMLValue) (interface{}, error) {
return &addressbookDescription{Description: ab.Description}, nil return &addressbookDescription{Description: ab.Description}, nil
}, },
addressBookSupportedAddressData: func(*internal.RawXMLValue) (interface{}, error) { supportedAddressDataName: func(*internal.RawXMLValue) (interface{}, error) {
return &addressbookSupportedAddressData{ return &supportedAddressData{
Types: []addressDataType{ Types: []addressDataType{
{ContentType: vcard.MIMEType, Version: "3.0"}, {ContentType: vcard.MIMEType, Version: "3.0"},
{ContentType: vcard.MIMEType, Version: "4.0"}, {ContentType: vcard.MIMEType, Version: "4.0"},