caldav, carddav: redirect on wrong path

it is much more user-friendly to redirect to the correct
principalPath/homeSetPath when possible
This commit is contained in:
oliverpool
2024-10-04 21:12:08 +02:00
committed by Filip Góra
parent e4babc2798
commit 9c900b1c66
6 changed files with 119 additions and 43 deletions

View File

@@ -366,7 +366,7 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
return nil
}
func (b *backend) PropFind(r *http.Request, propfind *internal.PropFind, depth internal.Depth) (*internal.MultiStatus, error) {
func (b *backend) PropFind(w http.ResponseWriter, r *http.Request, propfind *internal.PropFind, depth internal.Depth) error {
resType := b.resourceTypeAtPath(r.URL.Path)
var dataReq CalendarCompRequest
@@ -376,86 +376,92 @@ func (b *backend) PropFind(r *http.Request, propfind *internal.PropFind, depth i
case resourceTypeRoot:
resp, err := b.propFindRoot(r.Context(), propfind)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
case resourceTypeUserPrincipal:
principalPath, err := b.Backend.CurrentUserPrincipal(r.Context())
if err != nil {
return nil, err
return err
}
if r.URL.Path == principalPath {
resp, err := b.propFindUserPrincipal(r.Context(), propfind)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
if depth != internal.DepthZero {
resp, err := b.propFindHomeSet(r.Context(), propfind)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
if depth == internal.DepthInfinity {
resps_, err := b.propFindAllCalendars(r.Context(), propfind, true)
if err != nil {
return nil, err
return err
}
resps = append(resps, resps_...)
}
}
} else {
http.Redirect(w, r, principalPath, http.StatusPermanentRedirect) // keep http method
return nil
}
case resourceTypeCalendarHomeSet:
homeSetPath, err := b.Backend.CalendarHomeSetPath(r.Context())
if err != nil {
return nil, err
return err
}
if r.URL.Path == homeSetPath {
resp, err := b.propFindHomeSet(r.Context(), propfind)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
if depth != internal.DepthZero {
recurse := depth == internal.DepthInfinity
resps_, err := b.propFindAllCalendars(r.Context(), propfind, recurse)
if err != nil {
return nil, err
return err
}
resps = append(resps, resps_...)
}
} else {
http.Redirect(w, r, homeSetPath, http.StatusPermanentRedirect) // keep http method
return nil
}
case resourceTypeCalendar:
ab, err := b.Backend.GetCalendar(r.Context(), r.URL.Path)
if err != nil {
return nil, err
return err
}
resp, err := b.propFindCalendar(r.Context(), propfind, ab)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
if depth != internal.DepthZero {
resps_, err := b.propFindAllCalendarObjects(r.Context(), propfind, ab)
if err != nil {
return nil, err
return err
}
resps = append(resps, resps_...)
}
case resourceTypeCalendarObject:
ao, err := b.Backend.GetCalendarObject(r.Context(), r.URL.Path, &dataReq)
if err != nil {
return nil, err
return err
}
resp, err := b.propFindCalendarObject(r.Context(), propfind, ao)
if err != nil {
return nil, err
return err
}
resps = append(resps, *resp)
}
return internal.NewMultiStatus(resps...), nil
return internal.ServeMultiStatus(w, internal.NewMultiStatus(resps...))
}
func (b *backend) propFindRoot(ctx context.Context, propfind *internal.PropFind) (*internal.Response, error) {