Fix: unable to save office file in root directory of WebDAV
This commit is contained in:
parent
bb27d1d587
commit
cf90ab5a9a
6 changed files with 77 additions and 35 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
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.Use(middleware.WebDAVAuth())
|
||||
|
||||
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.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)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue