提交 cf90ab5a 编写于 作者: H HFO4

Fix: unable to save office file in root directory of WebDAV

上级 bb27d1d5
......@@ -6,6 +6,7 @@ import (
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"net/http"
)
// SignRequired 验证请求签名
......@@ -49,3 +50,47 @@ func AuthRequired() gin.HandlerFunc {
c.Abort()
}
}
// WebDAVAuth 验证WebDAV登录及权限
func WebDAVAuth() gin.HandlerFunc {
return func(c *gin.Context) {
// OPTIONS 请求不需要鉴权,否则Windows10下无法保存文档
if c.Request.Method == "OPTIONS" {
c.Next()
return
}
username, password, ok := c.Request.BasicAuth()
if !ok {
c.Writer.Header()["WWW-Authenticate"] = []string{`Basic realm="cloudreve"`}
c.Status(http.StatusUnauthorized)
c.Abort()
return
}
expectedUser, err := model.GetUserByEmail(username)
if err != nil {
c.Status(http.StatusUnauthorized)
c.Abort()
return
}
// 密码正确?
ok, _ = expectedUser.CheckPassword(password)
if !ok {
c.Status(http.StatusUnauthorized)
c.Abort()
return
}
// 用户组已启用WebDAV?
if !expectedUser.Group.WebDAVEnabled {
c.Status(http.StatusForbidden)
c.Abort()
return
}
c.Set("user", &expectedUser)
c.Next()
}
}
......@@ -47,7 +47,7 @@ func Init() {
// Debug模式下,输出所有 SQL 日志
if conf.SystemConfig.Debug {
db.LogMode(true)
db.LogMode(false)
}
//db.SetLogger(util.Log())
......
......@@ -32,17 +32,17 @@ func moveFiles(ctx context.Context, fs *filesystem.FileSystem, src FileInfo, dst
folderIDs []uint
)
if src.IsDir() {
fileIDs = []uint{src.(*model.Folder).ID}
folderIDs = []uint{src.(*model.Folder).ID}
} else {
folderIDs = []uint{src.(*model.File).ID}
fileIDs = []uint{src.(*model.File).ID}
}
// 判断是否为重命名
if src.GetPosition() == path.Dir(dst) {
err = fs.Rename(
ctx,
fileIDs,
folderIDs,
fileIDs,
path.Base(dst),
)
} else {
......
......@@ -35,8 +35,11 @@ func (h *Handler) stripPrefix(p string, uid uint) (string, int, error) {
if h.Prefix == "" {
return p, http.StatusOK, nil
}
prefix := h.Prefix + strconv.FormatUint(uint64(uid), 10)
prefix := h.Prefix
if r := strings.TrimPrefix(p, prefix); len(r) < len(p) {
if len(r) == 0 {
r = "/"
}
return util.RemoveSlash(r), http.StatusOK, nil
}
return p, http.StatusNotFound, errPrefixMismatch
......@@ -164,9 +167,9 @@ func (h *Handler) confirmLocks(r *http.Request, src, dst string, fs *filesystem.
if err != nil {
continue
}
if u.Host != r.Host {
continue
}
//if u.Host != r.Host {
// continue
//}
lsrc, status, err = h.stripPrefix(u.Path, fs.User.ID)
if err != nil {
return nil, status, err
......@@ -381,9 +384,9 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request, fs *fil
if err != nil {
return http.StatusBadRequest, errInvalidDestination
}
if u.Host != "" && u.Host != r.Host {
return http.StatusBadGateway, errInvalidDestination
}
//if u.Host != "" && u.Host != r.Host {
// return http.StatusBadGateway, errInvalidDestination
//}
src, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
if err != nil {
......@@ -436,7 +439,9 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request, fs *fil
return copyFiles(ctx, fs, target, dst, r.Header.Get("Overwrite") != "F", depth, 0)
}
release, status, err := h.confirmLocks(r, src, dst, fs)
// windows下,某些情况下(网盘根目录下)Office保存文件时附带的锁token只包含源文件,
// 此处暂时去除了对dst锁的检查
release, status, err := h.confirmLocks(r, src, "", fs)
if err != nil {
return status, err
}
......@@ -575,9 +580,6 @@ func (h *Handler) handleUnlock(w http.ResponseWriter, r *http.Request, fs *files
// OK
func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request, fs *filesystem.FileSystem) (status int, err error) {
reqPath, status, err := h.stripPrefix(r.URL.Path, fs.User.ID)
if reqPath == "" {
reqPath = "/"
}
if err != nil {
return status, err
}
......
package controllers
import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/filesystem"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/pkg/webdav"
......@@ -12,18 +11,17 @@ var handler *webdav.Handler
func init() {
handler = &webdav.Handler{
Prefix: "/dav/",
Prefix: "/dav",
LockSystem: make(map[uint]webdav.LockSystem),
}
}
// ServeWebDAV 处理WebDAV相关请求
func ServeWebDAV(c *gin.Context) {
// 测试用user
user, _ := model.GetUserByID(1)
c.Set("user", &user)
fs, err := filesystem.NewFileSystemFromContext(c)
if err != nil {
util.Log().Panic("%s", err)
util.Log().Warning("无法为WebDAV初始化文件系统,%s", err)
return
}
handler.ServeHTTP(c.Writer, c.Request, fs)
......
......@@ -11,21 +11,18 @@ import (
// initWebDAV 初始化WebDAV相关路由
func initWebDAV(group *gin.RouterGroup) {
{
group.Any("", func(context *gin.Context) {
context.Status(403)
context.Abort()
})
group.Any(":uid/*path", controllers.ServeWebDAV)
group.Any(":uid", controllers.ServeWebDAV)
group.Handle("PROPFIND", ":uid/*path", controllers.ServeWebDAV)
group.Handle("PROPFIND", ":uid", controllers.ServeWebDAV)
group.Handle("MKCOL", ":uid/*path", controllers.ServeWebDAV)
group.Handle("LOCK", ":uid/*path", controllers.ServeWebDAV)
group.Handle("UNLOCK", ":uid/*path", controllers.ServeWebDAV)
group.Handle("PROPPATCH", ":uid/*path", controllers.ServeWebDAV)
group.Handle("COPY", ":uid/*path", controllers.ServeWebDAV)
group.Handle("MOVE", ":uid/*path", controllers.ServeWebDAV)
group.Use(middleware.WebDAVAuth())
group.Any("/*path", controllers.ServeWebDAV)
group.Any("", controllers.ServeWebDAV)
group.Handle("PROPFIND", "/*path", controllers.ServeWebDAV)
group.Handle("PROPFIND", "", controllers.ServeWebDAV)
group.Handle("MKCOL", "/*path", controllers.ServeWebDAV)
group.Handle("LOCK", "/*path", controllers.ServeWebDAV)
group.Handle("UNLOCK", "/*path", controllers.ServeWebDAV)
group.Handle("PROPPATCH", "/*path", controllers.ServeWebDAV)
group.Handle("COPY", "/*path", controllers.ServeWebDAV)
group.Handle("MOVE", "/*path", controllers.ServeWebDAV)
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册