mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-01-03 18:20:53 -06:00
86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
package webdav
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
webdav "codeberg.org/shroff/phylum/server/internal/api/webdav/impl"
|
|
"codeberg.org/shroff/phylum/server/internal/auth"
|
|
"codeberg.org/shroff/phylum/server/internal/core"
|
|
"codeberg.org/shroff/phylum/server/internal/db"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type handler struct {
|
|
prefix string
|
|
lockSystem webdav.LockSystem
|
|
}
|
|
|
|
func SetupHandler(r *gin.RouterGroup) {
|
|
logrus.Debug("Setting up WebDAV access at " + r.BasePath())
|
|
handler := &handler{
|
|
prefix: r.BasePath(),
|
|
lockSystem: webdav.NewMemLS(),
|
|
}
|
|
r.Handle("OPTIONS", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("GET", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("PUT", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("HEAD", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("POST", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("DELETE", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("MOVE", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("COPY", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("MKCOL", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("PROPFIND", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("PROPPATCH", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("LOCK", "/:root/*path", handler.HandleRequest)
|
|
r.Handle("UNLOCK", "/:root/*path", handler.HandleRequest)
|
|
}
|
|
|
|
func (h *handler) HandleRequest(c *gin.Context) {
|
|
authSuccess := false
|
|
var f *core.FileSystem
|
|
if email, pass, ok := c.Request.BasicAuth(); ok {
|
|
ctx := c.Request.Context()
|
|
db := db.Get(ctx)
|
|
if u, err := auth.VerifyUserPassword(db, email, pass); err == nil {
|
|
authSuccess = true
|
|
root := c.Param("root")
|
|
if root[0] == '~' {
|
|
id, err := core.UserHome(db, root[1:])
|
|
if err != nil {
|
|
if errors.Is(err, core.ErrUserNotFound) {
|
|
c.AbortWithStatus(http.StatusNotFound)
|
|
return
|
|
} else {
|
|
panic(err)
|
|
}
|
|
}
|
|
f = core.OpenFileSystem(db, u, id)
|
|
} else if id, err := uuid.Parse(root); err != nil {
|
|
f = core.OpenFileSystem(db, u, pgtype.UUID{Bytes: id, Valid: true})
|
|
} else {
|
|
c.AbortWithStatus(http.StatusNotFound)
|
|
return
|
|
}
|
|
} else if !errors.Is(err, auth.ErrCredentialsInvalid) {
|
|
panic(err)
|
|
}
|
|
}
|
|
if !authSuccess {
|
|
c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"")
|
|
c.AbortWithStatus(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
webdavHandler := webdav.Handler{
|
|
Prefix: h.prefix + "/" + c.Param("root"),
|
|
FileSystem: f,
|
|
LockSystem: h.lockSystem,
|
|
}
|
|
webdavHandler.ServeHTTP(c.Writer, c.Request)
|
|
}
|