From 7e0ed6c794adb1bbc501c9c04d0b96e96fd7ef3f Mon Sep 17 00:00:00 2001 From: okatu-loli Date: Tue, 9 Sep 2025 22:36:23 +0800 Subject: [PATCH] feat(webdav): Enhanced WebDAV authentication logic - Added logic for generating device keys based on the Client-Id, prioritizing those obtained from the request header. - If the Client-Id is missing, attempts to obtain it from the cookie. If that still doesn't exist, generates a random suffix for the client IP address as an identifier. - Stores the generated Client-Id in a cookie to ensure consistency across subsequent requests. - Use the device.EnsureActiveOnLogin method instead of the original Handle method to reactivate inactive sessions. --- server/webdav.go | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/server/webdav.go b/server/webdav.go index 5928811b..0c9ac526 100644 --- a/server/webdav.go +++ b/server/webdav.go @@ -18,6 +18,7 @@ import ( "github.com/alist-org/alist/v3/internal/op" "github.com/alist-org/alist/v3/internal/setting" "github.com/alist-org/alist/v3/pkg/utils" + "github.com/alist-org/alist/v3/pkg/utils/random" "github.com/alist-org/alist/v3/server/common" "github.com/alist-org/alist/v3/server/webdav" "github.com/gin-gonic/gin" @@ -55,6 +56,10 @@ func ServeWebDAV(c *gin.Context) { handler.ServeHTTP(c.Writer, c.Request.WithContext(ctx)) } +// WebDAVAuth authenticates WebDAV requests and reactivates inactive +// sessions using device.EnsureActiveOnLogin. Device keys are based on +// Client-Id headers when available or the client IP with a random +// suffix to avoid conflicts. func WebDAVAuth(c *gin.Context) { guest, _ := op.GetGuest() username, password, ok := c.Request.BasicAuth() @@ -72,8 +77,17 @@ func WebDAVAuth(c *gin.Context) { c.Abort() return } - key := utils.GetMD5EncodeStr(fmt.Sprintf("%d-%s", admin.ID, c.ClientIP())) - if err := device.Handle(admin, key, c.Request.UserAgent(), c.ClientIP()); err != nil { + clientID := c.GetHeader("Client-Id") + if clientID == "" { + if cookie, err := c.Request.Cookie("Client-Id"); err == nil { + clientID = cookie.Value + } else { + clientID = c.ClientIP() + "-" + random.String(8) + http.SetCookie(c.Writer, &http.Cookie{Name: "Client-Id", Value: clientID, Path: "/"}) + } + } + key := utils.GetMD5EncodeStr(fmt.Sprintf("%d-%s", admin.ID, clientID)) + if err := device.EnsureActiveOnLogin(admin, key, c.Request.UserAgent(), c.ClientIP()); err != nil { c.Status(http.StatusForbidden) c.Abort() return @@ -156,8 +170,17 @@ func WebDAVAuth(c *gin.Context) { c.Abort() return } - key := utils.GetMD5EncodeStr(fmt.Sprintf("%d-%s", user.ID, c.ClientIP())) - if err := device.Handle(user, key, c.Request.UserAgent(), c.ClientIP()); err != nil { + clientID := c.GetHeader("Client-Id") + if clientID == "" { + if cookie, err := c.Request.Cookie("Client-Id"); err == nil { + clientID = cookie.Value + } else { + clientID = c.ClientIP() + "-" + random.String(8) + http.SetCookie(c.Writer, &http.Cookie{Name: "Client-Id", Value: clientID, Path: "/"}) + } + } + key := utils.GetMD5EncodeStr(fmt.Sprintf("%d-%s", user.ID, clientID)) + if err := device.EnsureActiveOnLogin(user, key, c.Request.UserAgent(), c.ClientIP()); err != nil { c.Status(http.StatusForbidden) c.Abort() return