diff --git a/routers/controllers/admin.go b/routers/controllers/admin.go index bfd28b8..6fc4e1e 100644 --- a/routers/controllers/admin.go +++ b/routers/controllers/admin.go @@ -205,3 +205,25 @@ func AdminOneDriveOAuth(c *gin.Context) { c.JSON(200, ErrorResponse(err)) } } + +// AdminGetPolicy 获取存储策略详情 +func AdminGetPolicy(c *gin.Context) { + var service admin.PolicyService + if err := c.ShouldBindUri(&service); err == nil { + res := service.Get() + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} + +// AdminDeletePolicy 删除存储策略 +func AdminDeletePolicy(c *gin.Context) { + var service admin.PolicyService + if err := c.ShouldBindUri(&service); err == nil { + res := service.Delete() + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/controllers/callback.go b/routers/controllers/callback.go index 47afad1..340d453 100644 --- a/routers/controllers/callback.go +++ b/routers/controllers/callback.go @@ -5,6 +5,8 @@ import ( "github.com/HFO4/cloudreve/pkg/util" "github.com/HFO4/cloudreve/service/callback" "github.com/gin-gonic/gin" + "net/url" + "strconv" ) // RemoteCallback 远程上传回调 @@ -82,7 +84,13 @@ func OneDriveOAuth(c *gin.Context) { var callbackBody callback.OneDriveOauthService if err := c.ShouldBindQuery(&callbackBody); err == nil { res := callbackBody.Auth(c) - c.JSON(200, res) + redirect, _ := url.Parse("/admin/policy") + queries := redirect.Query() + queries.Add("code", strconv.Itoa(res.Code)) + queries.Add("msg", res.Msg) + queries.Add("err", res.Error) + redirect.RawQuery = queries.Encode() + c.Redirect(301, "/#"+redirect.String()) } else { c.JSON(200, ErrorResponse(err)) } diff --git a/routers/router.go b/routers/router.go index 0259ef2..9f1c1f5 100644 --- a/routers/router.go +++ b/routers/router.go @@ -345,6 +345,10 @@ func InitMasterRouter() *gin.Engine { policy.POST("scf", controllers.AdminAddSCF) // 获取 OneDrive OAuth URL policy.GET(":id/oauth", controllers.AdminOneDriveOAuth) + // 获取 存储策略 + policy.GET(":id", controllers.AdminGetPolicy) + // 删除 存储策略 + policy.DELETE(":id", controllers.AdminDeletePolicy) } } diff --git a/service/admin/policy.go b/service/admin/policy.go index 2708f46..3e36bb8 100644 --- a/service/admin/policy.go +++ b/service/admin/policy.go @@ -21,6 +21,7 @@ import ( "net/url" "os" "path/filepath" + "strings" "time" ) @@ -51,6 +52,52 @@ type PolicyService struct { Region string `json:"region"` } +// Delete 删除存储策略 +func (service *PolicyService) Delete() serializer.Response { + policy, err := model.GetPolicyByID(service.ID) + if err != nil { + return serializer.Err(serializer.CodeNotFound, "存储策略不存在", err) + } + + // 检查是否有文件使用 + total := 0 + row := model.DB.Model(&model.File{}).Where("policy_id = ?", service.ID). + Select("count(id)").Row() + row.Scan(&total) + if total > 0 { + return serializer.ParamErr(fmt.Sprintf("有 %d 个文件仍在使用此存储策略,请先删除这些文件", total), nil) + } + + // 检查用户组使用 + var groups []model.Group + model.DB.Model(&model.Group{}).Where( + "policies like ? OR policies like ? OR policies like ? OR policies like ?", + fmt.Sprintf("[%d,%%", service.ID), + fmt.Sprintf("%%,%d]", service.ID), + fmt.Sprintf("%%,%d,%%", service.ID), + fmt.Sprintf("%%[%d]%%", service.ID), + ).Find(&groups) + + if len(groups) > 0 { + return serializer.ParamErr(fmt.Sprintf("有 %d 个用户组绑定了此存储策略,请先解除绑定", len(groups)), nil) + } + + model.DB.Delete(&policy) + policy.ClearCache() + + return serializer.Response{} +} + +// Get 获取存储策略详情 +func (service *PolicyService) Get() serializer.Response { + policy, err := model.GetPolicyByID(service.ID) + if err != nil { + return serializer.Err(serializer.CodeNotFound, "存储策略不存在", err) + } + + return serializer.Response{Data: policy} +} + // GetOAuth 获取 OneDrive OAuth 地址 func (service *PolicyService) GetOAuth(c *gin.Context) serializer.Response { policy, err := model.GetPolicyByID(service.ID) @@ -195,9 +242,20 @@ func (service *SlaveTestService) Test() serializer.Response { // Add 添加存储策略 func (service *AddPolicyService) Add() serializer.Response { - if err := model.DB.Create(&service.Policy).Error; err != nil { - return serializer.ParamErr("存储策略添加失败", err) + service.Policy.DirNameRule = strings.TrimPrefix(service.Policy.DirNameRule, "/") + + if service.Policy.ID > 0 { + if err := model.DB.Save(&service.Policy).Error; err != nil { + return serializer.ParamErr("存储策略保存失败", err) + } + } else { + if err := model.DB.Create(&service.Policy).Error; err != nil { + return serializer.ParamErr("存储策略添加失败", err) + } } + + service.Policy.ClearCache() + return serializer.Response{Data: service.Policy.ID} } diff --git a/service/callback/oauth.go b/service/callback/oauth.go index aa0c626..3396ce6 100644 --- a/service/callback/oauth.go +++ b/service/callback/oauth.go @@ -3,6 +3,7 @@ package callback import ( "context" model "github.com/HFO4/cloudreve/models" + "github.com/HFO4/cloudreve/pkg/cache" "github.com/HFO4/cloudreve/pkg/filesystem/driver/onedrive" "github.com/HFO4/cloudreve/pkg/serializer" "github.com/HFO4/cloudreve/pkg/util" @@ -11,13 +12,21 @@ import ( // OneDriveOauthService OneDrive 授权回调服务 type OneDriveOauthService struct { - Code string `form:"code" binding:"required"` + Code string `form:"code"` + Error string `form:"error"` + ErrorMsg string `form:"error_description"` } // Auth 更新认证信息 func (service *OneDriveOauthService) Auth(c *gin.Context) serializer.Response { - policyId := util.GetSession(c, "onedrive_oauth_policy").(uint) - policy, err := model.GetPolicyByID(policyId) + if service.Error != "" { + return serializer.ParamErr(service.ErrorMsg, nil) + } + + policyID := util.GetSession(c, "onedrive_oauth_policy").(uint) + util.DeleteSession(c, "onedrive_oauth_policy") + + policy, err := model.GetPolicyByID(policyID) if err != nil { return serializer.Err(serializer.CodeNotFound, "存储策略不存在", nil) } @@ -37,5 +46,7 @@ func (service *OneDriveOauthService) Auth(c *gin.Context) serializer.Response { return serializer.DBErr("无法更新 RefreshToken", err) } + cache.Deletes([]string{client.Policy.AccessKey}, "onedrive_") + return serializer.Response{} }