From 86889e2fac3c3da7660876152eadca78d9005efe Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Tue, 18 Feb 2020 12:10:28 +0800 Subject: [PATCH] Feat: WebDAV account management --- models/webdav.go | 24 +++++++++++++- pkg/crontab/vas.go | 9 +++--- pkg/filesystem/manage.go | 32 ++++++++++--------- routers/controllers/webdav.go | 34 ++++++++++++++++++++ routers/router.go | 11 +++++++ service/setting/webdav.go | 59 +++++++++++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 service/setting/webdav.go diff --git a/models/webdav.go b/models/webdav.go index 2b58a8f..c1492f3 100644 --- a/models/webdav.go +++ b/models/webdav.go @@ -1,6 +1,8 @@ package model -import "github.com/jinzhu/gorm" +import ( + "github.com/jinzhu/gorm" +) // Webdav 应用账户 type Webdav struct { @@ -11,9 +13,29 @@ type Webdav struct { Root string `gorm:"type:text"` // 根目录 } +// Create 创建账户 +func (webdav *Webdav) Create() (uint, error) { + if err := DB.Create(webdav).Error; err != nil { + return 0, err + } + return webdav.ID, nil +} + // GetWebdavByPassword 根据密码和用户查找Webdav应用 func GetWebdavByPassword(password string, uid uint) (*Webdav, error) { webdav := &Webdav{} res := DB.Where("user_id = ? and password = ?", uid, password).First(webdav) return webdav, res.Error } + +// ListWebDAVAccounts 列出用户的所有账号 +func ListWebDAVAccounts(uid uint) []Webdav { + var accounts []Webdav + DB.Where("user_id = ?", uid).Order("created_at desc").Find(&accounts) + return accounts +} + +// DeleteWebDAVAccountByID 根据账户ID和UID删除账户 +func DeleteWebDAVAccountByID(id, uid uint) { + DB.Where("user_id = ? and id = ?", uid, id).Delete(&Webdav{}) +} diff --git a/pkg/crontab/vas.go b/pkg/crontab/vas.go index cfd1d4c..3414469 100644 --- a/pkg/crontab/vas.go +++ b/pkg/crontab/vas.go @@ -53,11 +53,13 @@ func checkUserGroup() { func checkStoragePack() { packs := model.GetExpiredStoragePack() for _, pack := range packs { + // 删除过期的容量包 + pack.Delete() //找到所属用户 - user, err := model.GetUserByID(pack.ID) + user, err := model.GetUserByID(pack.UserID) if err != nil { - util.Log().Warning("[定时任务] 无法获取用户 [UID=%d] 信息, %s", pack.ID, err) + util.Log().Warning("[定时任务] 无法获取用户 [UID=%d] 信息, %s", pack.UserID, err) continue } @@ -66,9 +68,6 @@ func checkStoragePack() { // 如果超额,则通知用户 sendNotification(&user, "容量包过期") - // 删除过期的容量包 - pack.Delete() - // 更新最后通知日期 user.Notified() diff --git a/pkg/filesystem/manage.go b/pkg/filesystem/manage.go index 716ab43..1f30683 100644 --- a/pkg/filesystem/manage.go +++ b/pkg/filesystem/manage.go @@ -185,38 +185,40 @@ func (fs *FileSystem) Delete(ctx context.Context, dirs, files []uint) error { // TODO 用户自主选择是否强制删除 // 删除文件记录 - err = model.DeleteFileByIDs(allFileIDs) + err = model.DeleteFileByIDs(deletedFileIDs) if err != nil { return ErrDBDeleteObjects.WithError(err) } // 删除文件记录对应的分享记录 - model.DeleteShareBySourceIDs(allFileIDs, false) + model.DeleteShareBySourceIDs(deletedFileIDs, false) // 归还容量 var total uint64 - for _, value := range totalStorage { + for _, value := range deletedStorage { total += value } fs.User.DeductionStorage(total) - // 删除目录 - var allFolderIDs = make([]uint, 0, len(fs.DirTarget)) - for _, value := range fs.DirTarget { - allFolderIDs = append(allFolderIDs, value.ID) - } - err = model.DeleteFolderByIDs(allFolderIDs) - if err != nil { - return ErrDBDeleteObjects.WithError(err) - } + // 如果文件全部删除成功,继续删除目录 + if len(deletedFileIDs) == len(allFileIDs) { + var allFolderIDs = make([]uint, 0, len(fs.DirTarget)) + for _, value := range fs.DirTarget { + allFolderIDs = append(allFolderIDs, value.ID) + } + err = model.DeleteFolderByIDs(allFolderIDs) + if err != nil { + return ErrDBDeleteObjects.WithError(err) + } - // 删除目录记录对应的分享记录 - model.DeleteShareBySourceIDs(allFolderIDs, true) + // 删除目录记录对应的分享记录 + model.DeleteShareBySourceIDs(allFolderIDs, true) + } if notDeleted := len(fs.FileTarget) - len(deletedFileIDs); notDeleted > 0 { return serializer.NewError( serializer.CodeNotFullySuccess, - fmt.Sprintf("有 %d 个文件未能成功删除,已删除它们的文件记录", notDeleted), + fmt.Sprintf("有 %d 个文件未能成功删除", notDeleted), nil, ) } diff --git a/routers/controllers/webdav.go b/routers/controllers/webdav.go index 4f99f4a..48e91c3 100644 --- a/routers/controllers/webdav.go +++ b/routers/controllers/webdav.go @@ -5,6 +5,7 @@ import ( "github.com/HFO4/cloudreve/pkg/filesystem" "github.com/HFO4/cloudreve/pkg/util" "github.com/HFO4/cloudreve/pkg/webdav" + "github.com/HFO4/cloudreve/service/setting" "github.com/gin-gonic/gin" ) @@ -40,3 +41,36 @@ func ServeWebDAV(c *gin.Context) { handler.ServeHTTP(c.Writer, c.Request, fs) } + +// GetWebDAVAccounts 获取webdav账号列表 +func GetWebDAVAccounts(c *gin.Context) { + var service setting.WebDAVListService + if err := c.ShouldBindUri(&service); err == nil { + res := service.Accounts(c, CurrentUser(c)) + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} + +// DeleteWebDAVAccounts 删除WebDAV账户 +func DeleteWebDAVAccounts(c *gin.Context) { + var service setting.WebDAVAccountService + if err := c.ShouldBindUri(&service); err == nil { + res := service.Delete(c, CurrentUser(c)) + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} + +// CreateWebDAVAccounts 创建WebDAV账户 +func CreateWebDAVAccounts(c *gin.Context) { + var service setting.WebDAVAccountCreateService + if err := c.ShouldBindJSON(&service); err == nil { + res := service.Create(c, CurrentUser(c)) + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/router.go b/routers/router.go index 59817f6..eb61fd0 100644 --- a/routers/router.go +++ b/routers/router.go @@ -381,6 +381,17 @@ func InitMasterRouter() *gin.Engine { vas.POST("redeem/:code", controllers.DoRedeem) } + // WebDAV管理相关 + webdav := auth.Group("webdav") + { + // 获取账号信息 + webdav.GET("accounts", controllers.GetWebDAVAccounts) + // 新建账号 + webdav.POST("accounts", controllers.CreateWebDAVAccounts) + // 删除账号 + webdav.DELETE("accounts/:id", controllers.DeleteWebDAVAccounts) + } + } } diff --git a/service/setting/webdav.go b/service/setting/webdav.go new file mode 100644 index 0000000..9ae5a06 --- /dev/null +++ b/service/setting/webdav.go @@ -0,0 +1,59 @@ +package setting + +import ( + model "github.com/HFO4/cloudreve/models" + "github.com/HFO4/cloudreve/pkg/serializer" + "github.com/HFO4/cloudreve/pkg/util" + "github.com/gin-gonic/gin" +) + +// WebDAVListService WebDAV 列表服务 +type WebDAVListService struct { +} + +// WebDAVAccountService WebDAV 账号管理服务 +type WebDAVAccountService struct { + ID uint `uri:"id" binding:"required,min=1"` +} + +// WebDAVAccountCreateService WebDAV 账号创建服务 +type WebDAVAccountCreateService struct { + Path string `json:"path" binding:"required,min=1,max=65535"` + Name string `json:"name" binding:"required,min=1,max=255"` +} + +// Create 创建WebDAV账户 +func (service *WebDAVAccountCreateService) Create(c *gin.Context, user *model.User) serializer.Response { + account := model.Webdav{ + Name: service.Name, + Password: util.RandStringRunes(32), + UserID: user.ID, + Root: service.Path, + } + + if _, err := account.Create(); err != nil { + return serializer.Err(serializer.CodeDBError, "创建失败", err) + } + + return serializer.Response{ + Data: map[string]interface{}{ + "id": account.ID, + "password": account.Password, + "created_at": account.CreatedAt, + }, + } +} + +// Delete 删除WebDAV账户 +func (service *WebDAVAccountService) Delete(c *gin.Context, user *model.User) serializer.Response { + model.DeleteWebDAVAccountByID(service.ID, user.ID) + return serializer.Response{} +} + +// Accounts 列出WebDAV账号 +func (service *WebDAVListService) Accounts(c *gin.Context, user *model.User) serializer.Response { + accounts := model.ListWebDAVAccounts(user.ID) + return serializer.Response{Data: map[string]interface{}{ + "accounts": accounts, + }} +}