mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 16:24:14 +00:00
webdav: add ServePrincipal
This commit is contained in:
parent
95a4ae783b
commit
4cc86a1225
32
elements.go
Normal file
32
elements.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package webdav
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
|
||||||
|
"github.com/emersion/go-webdav/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
principalName = xml.Name{"DAV:", "principal"}
|
||||||
|
principalAlternateURISetName = xml.Name{"DAV:", "alternate-URI-set"}
|
||||||
|
principalURLName = xml.Name{"DAV:", "principal-URL"}
|
||||||
|
groupMembershipName = xml.Name{"DAV:", "group-membership"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc3744#section-4.1
|
||||||
|
type principalAlternateURISet struct {
|
||||||
|
XMLName xml.Name `xml:"DAV: alternate-URI-set"`
|
||||||
|
Hrefs []internal.Href `xml:"href"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc3744#section-4.2
|
||||||
|
type principalURL struct {
|
||||||
|
XMLName xml.Name `xml:"DAV: principal-URL"`
|
||||||
|
Href internal.Href `xml:"href"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc3744#section-4.4
|
||||||
|
type groupMembership struct {
|
||||||
|
XMLName xml.Name `xml:"DAV: group-membership"`
|
||||||
|
Hrefs []internal.Href `xml:"href"`
|
||||||
|
}
|
62
server.go
62
server.go
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/emersion/go-webdav/internal"
|
"github.com/emersion/go-webdav/internal"
|
||||||
)
|
)
|
||||||
@ -234,3 +235,64 @@ func (b *backend) Move(r *http.Request, dest *internal.Href, overwrite bool) (cr
|
|||||||
}
|
}
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServePrincipal replies to a request on a principal URI.
|
||||||
|
func ServePrincipal(w http.ResponseWriter, r *http.Request, principal *Principal) {
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodOptions:
|
||||||
|
caps := append([]string{"1", "3"})
|
||||||
|
allow := []string{http.MethodOptions, "PROPFIND"}
|
||||||
|
w.Header().Add("DAV", strings.Join(caps, ", "))
|
||||||
|
w.Header().Add("Allow", strings.Join(allow, ", "))
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
case "PROPFIND":
|
||||||
|
if err := servePrincipalPropfind(w, r, principal); err != nil {
|
||||||
|
internal.ServeError(w, err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
http.Error(w, "unsupported method", http.StatusMethodNotAllowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func servePrincipalPropfind(w http.ResponseWriter, r *http.Request, principal *Principal) error {
|
||||||
|
var propfind internal.Propfind
|
||||||
|
if err := internal.DecodeXMLRequest(r, &propfind); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle Depth
|
||||||
|
|
||||||
|
props := map[xml.Name]internal.PropfindFunc{
|
||||||
|
internal.ResourceTypeName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
return internal.NewResourceType(principalName), nil
|
||||||
|
},
|
||||||
|
internal.DisplayNameName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
return &internal.DisplayName{Name: principal.Name}, nil
|
||||||
|
},
|
||||||
|
internal.CurrentUserPrincipalName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
// TODO: allow serving a principal different from the current user's
|
||||||
|
return &internal.CurrentUserPrincipal{Href: internal.Href{Path: principal.Path}}, nil
|
||||||
|
},
|
||||||
|
principalAlternateURISetName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
return &principalAlternateURISet{}, nil // TODO: allow customizing
|
||||||
|
},
|
||||||
|
principalURLName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
return &principalURL{
|
||||||
|
Href: internal.Href{Path: principal.Path},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
groupMembershipName: func(*internal.RawXMLValue) (interface{}, error) {
|
||||||
|
return &groupMembership{}, nil // TODO: allow customizing
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: allow adding more props such as CardDAV/CalDAV home sets
|
||||||
|
|
||||||
|
resp, err := internal.NewPropfindResponse(r.URL.Path, &propfind, props)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ms := internal.NewMultistatus(*resp)
|
||||||
|
return internal.ServeMultistatus(w, ms)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user