mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 08:14:15 +00:00
carddav: stop hardcoding address book home set
This commit is contained in:
parent
95a4ae783b
commit
0babf610b0
@ -25,6 +25,7 @@ type PutAddressObjectOptions struct {
|
|||||||
|
|
||||||
// Backend is a CardDAV server backend.
|
// Backend is a CardDAV server backend.
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
|
CurrentUserAddressBookHomeSet(ctx context.Context) (string, error)
|
||||||
AddressBook(ctx context.Context) (*AddressBook, error)
|
AddressBook(ctx context.Context) (*AddressBook, error)
|
||||||
GetAddressObject(ctx context.Context, path string, req *AddressDataRequest) (*AddressObject, error)
|
GetAddressObject(ctx context.Context, path string, req *AddressDataRequest) (*AddressObject, error)
|
||||||
ListAddressObjects(ctx context.Context, req *AddressDataRequest) ([]AddressObject, error)
|
ListAddressObjects(ctx context.Context, req *AddressDataRequest) ([]AddressObject, error)
|
||||||
@ -234,7 +235,12 @@ type backend struct {
|
|||||||
func (b *backend) Options(r *http.Request) (caps []string, allow []string, err error) {
|
func (b *backend) Options(r *http.Request) (caps []string, allow []string, err error) {
|
||||||
caps = []string{"addressbook"}
|
caps = []string{"addressbook"}
|
||||||
|
|
||||||
if r.URL.Path == "/" {
|
homeSet, err := b.Backend.CurrentUserAddressBookHomeSet(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.URL.Path == "" || r.URL.Path == homeSet {
|
||||||
// Note: some clients assume the address book is read-only when
|
// Note: some clients assume the address book is read-only when
|
||||||
// DELETE/MKCOL are missing
|
// DELETE/MKCOL are missing
|
||||||
return caps, []string{http.MethodOptions, "PROPFIND", "REPORT", "DELETE", "MKCOL"}, nil
|
return caps, []string{http.MethodOptions, "PROPFIND", "REPORT", "DELETE", "MKCOL"}, nil
|
||||||
@ -259,16 +265,14 @@ func (b *backend) Options(r *http.Request) (caps []string, allow []string, err e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
|
func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
|
||||||
if r.URL.Path == "/" {
|
|
||||||
return &internal.HTTPError{Code: http.StatusMethodNotAllowed}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dataReq AddressDataRequest
|
var dataReq AddressDataRequest
|
||||||
if r.Method != http.MethodHead {
|
if r.Method != http.MethodHead {
|
||||||
dataReq.AllProp = true
|
dataReq.AllProp = true
|
||||||
}
|
}
|
||||||
ao, err := b.Backend.GetAddressObject(r.Context(), r.URL.Path, &dataReq)
|
ao, err := b.Backend.GetAddressObject(r.Context(), r.URL.Path, &dataReq)
|
||||||
if err != nil {
|
if internal.IsNotFound(err) {
|
||||||
|
return &internal.HTTPError{Code: http.StatusMethodNotAllowed}
|
||||||
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,14 +293,19 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
|
|||||||
func (b *backend) Propfind(r *http.Request, propfind *internal.Propfind, depth internal.Depth) (*internal.Multistatus, error) {
|
func (b *backend) Propfind(r *http.Request, propfind *internal.Propfind, depth internal.Depth) (*internal.Multistatus, error) {
|
||||||
var dataReq AddressDataRequest
|
var dataReq AddressDataRequest
|
||||||
|
|
||||||
|
homeSet, err := b.Backend.CurrentUserAddressBookHomeSet(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var resps []internal.Response
|
var resps []internal.Response
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == homeSet {
|
||||||
ab, err := b.Backend.AddressBook(r.Context())
|
ab, err := b.Backend.AddressBook(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := b.propfindAddressBook(propfind, ab)
|
resp, err := b.propfindAddressBook(r.Context(), propfind, ab)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -332,7 +341,7 @@ func (b *backend) Propfind(r *http.Request, propfind *internal.Propfind, depth i
|
|||||||
return internal.NewMultistatus(resps...), nil
|
return internal.NewMultistatus(resps...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) propfindAddressBook(propfind *internal.Propfind, ab *AddressBook) (*internal.Response, error) {
|
func (b *backend) propfindAddressBook(ctx context.Context, propfind *internal.Propfind, ab *AddressBook) (*internal.Response, error) {
|
||||||
props := map[xml.Name]internal.PropfindFunc{
|
props := map[xml.Name]internal.PropfindFunc{
|
||||||
internal.ResourceTypeName: func(*internal.RawXMLValue) (interface{}, error) {
|
internal.ResourceTypeName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
return internal.NewResourceType(internal.CollectionName, addressBookName), nil
|
return internal.NewResourceType(internal.CollectionName, addressBookName), nil
|
||||||
@ -353,7 +362,11 @@ func (b *backend) propfindAddressBook(propfind *internal.Propfind, ab *AddressBo
|
|||||||
},
|
},
|
||||||
// TODO: this is a principal property
|
// TODO: this is a principal property
|
||||||
addressBookHomeSetName: func(*internal.RawXMLValue) (interface{}, error) {
|
addressBookHomeSetName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
return &addressbookHomeSet{Href: internal.Href{Path: "/"}}, nil
|
homeSet, err := b.Backend.CurrentUserAddressBookHomeSet(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &addressbookHomeSet{Href: internal.Href{Path: homeSet}}, nil
|
||||||
},
|
},
|
||||||
// TODO: this should be set on all resources
|
// TODO: this should be set on all resources
|
||||||
internal.CurrentUserPrincipalName: func(*internal.RawXMLValue) (interface{}, error) {
|
internal.CurrentUserPrincipalName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user