package main import ( "path" "strings" "time" "github.com/gin-gonic/gin" "github.com/studio-b12/gowebdav" ) func cleanWebDAVRoot(root string) string { root = strings.TrimSpace(strings.ReplaceAll(root, "\\", "/")) root = path.Clean("/" + root) if root == "/" { return "" } return strings.Trim(root, "/") } func (a *App) getUserWebDAV(c *gin.Context) { user := c.MustGet("user").(*User) var cfg WebDAVConfig if err := a.db.Where("user_id = ?", user.ID).First(&cfg).Error; err != nil { c.JSON(200, gin.H{"enabled": false, "url": "", "username": "", "rootPath": "", "hasPassword": false}) return } c.JSON(200, gin.H{"enabled": cfg.Enabled, "url": cfg.URL, "username": cfg.Username, "rootPath": cfg.RootPath, "hasPassword": cfg.Password != ""}) } func (a *App) putUserWebDAV(c *gin.Context) { user := c.MustGet("user").(*User) var in struct { Enabled bool `json:"enabled"` URL string `json:"url"` Username string `json:"username"` Password string `json:"password"` RootPath string `json:"rootPath"` } if c.BindJSON(&in) != nil { c.Status(400) return } root := cleanWebDAVRoot(in.RootPath) var cfg WebDAVConfig err := a.db.Where("user_id = ?", user.ID).First(&cfg).Error if err != nil { cfg = WebDAVConfig{UserID: user.ID, Enabled: in.Enabled, URL: strings.TrimRight(strings.TrimSpace(in.URL), "/"), Username: strings.TrimSpace(in.Username), Password: in.Password, RootPath: root} } else { cfg.Enabled = in.Enabled cfg.URL = strings.TrimRight(strings.TrimSpace(in.URL), "/") cfg.Username = strings.TrimSpace(in.Username) cfg.RootPath = root if in.Password != "" { cfg.Password = in.Password } } if err := a.db.Save(&cfg).Error; err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(200, gin.H{"ok": true}) } func (a *App) testUserWebDAV(c *gin.Context) { user := c.MustGet("user").(*User) var in struct{ URL, Username, Password, RootPath string } if c.BindJSON(&in) != nil { c.Status(400) return } if in.URL == "" { var cfg WebDAVConfig if a.db.Where("user_id = ?", user.ID).First(&cfg).Error == nil { in.URL, in.Username, in.Password, in.RootPath = cfg.URL, cfg.Username, cfg.Password, cfg.RootPath } } client := gowebdav.NewClient(in.URL, in.Username, in.Password) client.SetTimeout(20 * time.Second) if err := client.Connect(); err != nil { c.JSON(502, gin.H{"ok": false, "error": err.Error()}) return } c.JSON(200, gin.H{"ok": true, "rootPath": cleanWebDAVRoot(in.RootPath)}) } func (a *App) storageForTask(t *Task) (RemoteStorage, string, bool) { var user User if a.db.First(&user, t.UserID).Error != nil { return nil, "", false } if !a.hasPermission(user.ID, PermWebDAV) { return nil, "", false } // Regular users use the system/global WebDAV only. They cannot override // the destination; privileged users may have their own WebDAV config. if user.Role == RoleUser { if a.cfg.WebDAVURL == "" || a.storage == nil { return nil, "", false } return a.storage, a.cfg.WebDAVPath, true } if user.Role == RoleAdmin { if a.cfg.WebDAVURL == "" || a.storage == nil { return nil, "", false } return a.storage, a.cfg.WebDAVPath, true } var cfg WebDAVConfig if a.db.Where("user_id = ? AND enabled = ?", user.ID, true).First(&cfg).Error != nil || cfg.URL == "" { // Privileged users fall back to the global WebDAV until a custom // WebDAV configuration is enabled and tested successfully. if a.cfg.WebDAVURL == "" || a.storage == nil { return nil, "", false } return a.storage, a.cfg.WebDAVPath, true } return NewWebDAVStorage(Config{WebDAVURL: cfg.URL, WebDAVUser: cfg.Username, WebDAVPass: cfg.Password}), cfg.RootPath, true }