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.
This commit is contained in:
Conrad Hoffmann 2022-12-01 14:43:04 +01:00 committed by Simon Ser
parent ac9af45270
commit 0456b28ba3
3 changed files with 11 additions and 1 deletions

View File

@ -12,6 +12,8 @@ import (
"github.com/emersion/go-webdav/internal" "github.com/emersion/go-webdav/internal"
) )
var CapabilityCalendar = webdav.Capability("calendar-access")
func NewCalendarHomeSet(path string) webdav.BackendSuppliedHomeSet { func NewCalendarHomeSet(path string) webdav.BackendSuppliedHomeSet {
return &calendarHomeSet{Href: internal.Href{Path: path}} return &calendarHomeSet{Href: internal.Href{Path: path}}
} }

View File

@ -11,6 +11,8 @@ import (
"github.com/emersion/go-webdav/internal" "github.com/emersion/go-webdav/internal"
) )
var CapabilityAddressBook = webdav.Capability("addressbook")
func NewAddressBookHomeSet(path string) webdav.BackendSuppliedHomeSet { func NewAddressBookHomeSet(path string) webdav.BackendSuppliedHomeSet {
return &addressbookHomeSet{Href: internal.Href{Path: path}} return &addressbookHomeSet{Href: internal.Href{Path: path}}
} }

View File

@ -261,9 +261,12 @@ type UserPrincipalBackend interface {
CurrentUserPrincipal(ctx context.Context) (string, error) CurrentUserPrincipal(ctx context.Context) (string, error)
} }
type Capability string
type ServePrincipalOptions struct { type ServePrincipalOptions struct {
CurrentUserPrincipalPath string CurrentUserPrincipalPath string
HomeSets []BackendSuppliedHomeSet HomeSets []BackendSuppliedHomeSet
Capabilities []Capability
} }
// ServePrincipal replies to requests for a principal URL. // 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 { switch r.Method {
case http.MethodOptions: case http.MethodOptions:
caps := []string{"1", "3"} 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("DAV", strings.Join(caps, ", "))
w.Header().Add("Allow", strings.Join(allow, ", ")) w.Header().Add("Allow", strings.Join(allow, ", "))
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)