From c2b2f073ccbd156f9bb7edb38af5ca25d52f6de5 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 3 May 2022 18:33:44 +0200 Subject: [PATCH] webdav: allow serving extra props in ServePrincipal --- caldav/server.go | 9 +++++++++ carddav/server.go | 9 +++++++++ server.go | 20 ++++++++++++++++---- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/caldav/server.go b/caldav/server.go index ee92d66..89a6a63 100644 --- a/caldav/server.go +++ b/caldav/server.go @@ -14,6 +14,15 @@ import ( // TODO: add support for multiple calendars +// CalendarHomeSetXML returns the XML name and marshalable value for a +// principal's calendar home set. It's designed to be used with +// webdav.ServePrincipal. +func CalendarHomeSetXML(path string) (xml.Name, xml.Marshaler) { + homeSet := &calendarHomeSet{Href: internal.Href{Path: path}} + v, _ := internal.EncodeRawXMLElement(homeSet) + return calendarHomeSetName, v +} + // Backend is a CalDAV server backend. type Backend interface { Calendar(ctx context.Context) (*Calendar, error) diff --git a/carddav/server.go b/carddav/server.go index d695e90..f298c22 100644 --- a/carddav/server.go +++ b/carddav/server.go @@ -14,6 +14,15 @@ import ( // TODO: add support for multiple address books +// AddressBookHomeSetXML returns the XML name and marshalable value for a +// principal's address book home set. It's designed to be used with +// webdav.ServePrincipal. +func AddressBookHomeSetXML(path string) (xml.Name, xml.Marshaler) { + homeSet := &addressbookHomeSet{Href: internal.Href{Path: path}} + v, _ := internal.EncodeRawXMLElement(homeSet) + return addressBookHomeSetName, v +} + type PutAddressObjectOptions struct { // IfNoneMatch indicates that the client does not want to overwrite // an existing resource. diff --git a/server.go b/server.go index 9342863..fc4e994 100644 --- a/server.go +++ b/server.go @@ -236,8 +236,13 @@ func (b *backend) Move(r *http.Request, dest *internal.Href, overwrite bool) (cr return created, err } +type ServePrincipalOptions struct { + Principal *Principal + Props map[xml.Name]xml.Marshaler +} + // ServePrincipal replies to a request on a principal URI. -func ServePrincipal(w http.ResponseWriter, r *http.Request, principal *Principal) { +func ServePrincipal(w http.ResponseWriter, r *http.Request, options *ServePrincipalOptions) { switch r.Method { case http.MethodOptions: caps := append([]string{"1", "3"}) @@ -246,7 +251,7 @@ func ServePrincipal(w http.ResponseWriter, r *http.Request, principal *Principal w.Header().Add("Allow", strings.Join(allow, ", ")) w.WriteHeader(http.StatusNoContent) case "PROPFIND": - if err := servePrincipalPropfind(w, r, principal); err != nil { + if err := servePrincipalPropfind(w, r, options); err != nil { internal.ServeError(w, err) } default: @@ -254,7 +259,9 @@ func ServePrincipal(w http.ResponseWriter, r *http.Request, principal *Principal } } -func servePrincipalPropfind(w http.ResponseWriter, r *http.Request, principal *Principal) error { +func servePrincipalPropfind(w http.ResponseWriter, r *http.Request, options *ServePrincipalOptions) error { + principal := options.Principal + var propfind internal.Propfind if err := internal.DecodeXMLRequest(r, &propfind); err != nil { return err @@ -286,7 +293,12 @@ func servePrincipalPropfind(w http.ResponseWriter, r *http.Request, principal *P }, } - // TODO: allow adding more props such as CardDAV/CalDAV home sets + for name, v := range options.Props { + v := v // capture variable + props[name] = func(*internal.RawXMLValue) (interface{}, error) { + return v, nil + } + } resp, err := internal.NewPropfindResponse(r.URL.Path, &propfind, props) if err != nil {