webdav: allow serving extra props in ServePrincipal

This commit is contained in:
Simon Ser 2022-05-03 18:33:44 +02:00
parent 6ae4814028
commit c2b2f073cc
3 changed files with 34 additions and 4 deletions

View File

@ -14,6 +14,15 @@ import (
// TODO: add support for multiple calendars // 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. // Backend is a CalDAV server backend.
type Backend interface { type Backend interface {
Calendar(ctx context.Context) (*Calendar, error) Calendar(ctx context.Context) (*Calendar, error)

View File

@ -14,6 +14,15 @@ import (
// TODO: add support for multiple address books // 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 { type PutAddressObjectOptions struct {
// IfNoneMatch indicates that the client does not want to overwrite // IfNoneMatch indicates that the client does not want to overwrite
// an existing resource. // an existing resource.

View File

@ -236,8 +236,13 @@ func (b *backend) Move(r *http.Request, dest *internal.Href, overwrite bool) (cr
return created, err return created, err
} }
type ServePrincipalOptions struct {
Principal *Principal
Props map[xml.Name]xml.Marshaler
}
// ServePrincipal replies to a request on a principal URI. // 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 { switch r.Method {
case http.MethodOptions: case http.MethodOptions:
caps := append([]string{"1", "3"}) 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.Header().Add("Allow", strings.Join(allow, ", "))
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
case "PROPFIND": case "PROPFIND":
if err := servePrincipalPropfind(w, r, principal); err != nil { if err := servePrincipalPropfind(w, r, options); err != nil {
internal.ServeError(w, err) internal.ServeError(w, err)
} }
default: 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 var propfind internal.Propfind
if err := internal.DecodeXMLRequest(r, &propfind); err != nil { if err := internal.DecodeXMLRequest(r, &propfind); err != nil {
return err 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) resp, err := internal.NewPropfindResponse(r.URL.Path, &propfind, props)
if err != nil { if err != nil {