From 0456b28ba351c1ead0cb11efaab20a2fdb0f0f5c Mon Sep 17 00:00:00 2001 From: Conrad Hoffmann Date: Thu, 1 Dec 2022 14:43:04 +0100 Subject: [PATCH] Support setting capabilities in ServePrincipal() This is done properly in the carddav and caldav packages, but the custom function does not know what the user intends to serve, so it must be passed in from the user. Without this, certain clients (e.g. DAVx5) will be unable to discover endpoints served this way. Also slightly extend the supported methods returned on OPTIONS requests. REPORT is properly supported, the others are mostly for not giving clients the impression that the resources are read-only. --- caldav/caldav.go | 2 ++ carddav/carddav.go | 2 ++ server.go | 8 +++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/caldav/caldav.go b/caldav/caldav.go index 75aa256..02705ef 100644 --- a/caldav/caldav.go +++ b/caldav/caldav.go @@ -12,6 +12,8 @@ import ( "github.com/emersion/go-webdav/internal" ) +var CapabilityCalendar = webdav.Capability("calendar-access") + func NewCalendarHomeSet(path string) webdav.BackendSuppliedHomeSet { return &calendarHomeSet{Href: internal.Href{Path: path}} } diff --git a/carddav/carddav.go b/carddav/carddav.go index 664727c..ebfd66d 100644 --- a/carddav/carddav.go +++ b/carddav/carddav.go @@ -11,6 +11,8 @@ import ( "github.com/emersion/go-webdav/internal" ) +var CapabilityAddressBook = webdav.Capability("addressbook") + func NewAddressBookHomeSet(path string) webdav.BackendSuppliedHomeSet { return &addressbookHomeSet{Href: internal.Href{Path: path}} } diff --git a/server.go b/server.go index 7eaadde..f7d6ce0 100644 --- a/server.go +++ b/server.go @@ -261,9 +261,12 @@ type UserPrincipalBackend interface { CurrentUserPrincipal(ctx context.Context) (string, error) } +type Capability string + type ServePrincipalOptions struct { CurrentUserPrincipalPath string HomeSets []BackendSuppliedHomeSet + Capabilities []Capability } // ServePrincipal replies to requests for a principal URL. @@ -271,7 +274,10 @@ func ServePrincipal(w http.ResponseWriter, r *http.Request, options *ServePrinci switch r.Method { case http.MethodOptions: caps := []string{"1", "3"} - allow := []string{http.MethodOptions, "PROPFIND"} + for _, c := range options.Capabilities { + caps = append(caps, string(c)) + } + allow := []string{http.MethodOptions, "PROPFIND", "REPORT", "DELETE", "MKCOL"} w.Header().Add("DAV", strings.Join(caps, ", ")) w.Header().Add("Allow", strings.Join(allow, ", ")) w.WriteHeader(http.StatusNoContent)