Feat: auth for remote callback / Modify: use map to store hooks in filesystem
This commit is contained in:
parent
ca9f44c06c
commit
d29b7ef6f8
15 changed files with 158 additions and 59 deletions
|
@ -3,6 +3,7 @@ package middleware
|
||||||
import (
|
import (
|
||||||
"github.com/HFO4/cloudreve/models"
|
"github.com/HFO4/cloudreve/models"
|
||||||
"github.com/HFO4/cloudreve/pkg/auth"
|
"github.com/HFO4/cloudreve/pkg/auth"
|
||||||
|
"github.com/HFO4/cloudreve/pkg/cache"
|
||||||
"github.com/HFO4/cloudreve/pkg/serializer"
|
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -25,6 +26,7 @@ func SignRequired() gin.HandlerFunc {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(200, serializer.Err(serializer.CodeCheckLogin, err.Error(), err))
|
c.JSON(200, serializer.Err(serializer.CodeCheckLogin, err.Error(), err))
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
@ -103,3 +105,55 @@ func WebDAVAuth() gin.HandlerFunc {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoteCallbackAuth 远程回调签名验证
|
||||||
|
// TODO 测试
|
||||||
|
func RemoteCallbackAuth() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
// 验证 Callback Key
|
||||||
|
callbackKey := c.Param("key")
|
||||||
|
if callbackKey == "" {
|
||||||
|
c.JSON(200, serializer.ParamErr("Callback Key 不能为空", nil))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callbackSessionRaw, exist := cache.Get("callback_" + callbackKey)
|
||||||
|
if !exist {
|
||||||
|
c.JSON(200, serializer.ParamErr("回调会话不存在或已过期", nil))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callbackSession := callbackSessionRaw.(serializer.UploadSession)
|
||||||
|
c.Set("callbackSession", &callbackSession)
|
||||||
|
|
||||||
|
// 清理回调会话
|
||||||
|
_ = cache.Deletes([]string{callbackKey}, "callback_")
|
||||||
|
|
||||||
|
// 查找用户
|
||||||
|
user, err := model.GetUserByID(callbackSession.UID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, serializer.Err(serializer.CodeCheckLogin, "找不到用户", err))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Set("user", &user)
|
||||||
|
|
||||||
|
// 检查存储策略是否一致
|
||||||
|
if user.GetPolicyID() != callbackSession.PolicyID {
|
||||||
|
c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, "存储策略已变更,请重新上传", nil))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证签名
|
||||||
|
authInstance := auth.HMACAuth{SecretKey: []byte(user.Policy.SecretKey)}
|
||||||
|
if err := auth.CheckRequest(authInstance, c.Request); err != nil {
|
||||||
|
c.JSON(200, serializer.Err(serializer.CodeCheckLogin, err.Error(), err))
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Next()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ func (fs *FileSystem) GetDownloadContent(ctx context.Context, path string) (resp
|
||||||
// GetContent 获取文件内容,path为虚拟路径
|
// GetContent 获取文件内容,path为虚拟路径
|
||||||
func (fs *FileSystem) GetContent(ctx context.Context, path string) (response.RSCloser, error) {
|
func (fs *FileSystem) GetContent(ctx context.Context, path string) (response.RSCloser, error) {
|
||||||
// 触发`下载前`钩子
|
// 触发`下载前`钩子
|
||||||
err := fs.Trigger(ctx, fs.BeforeFileDownload)
|
err := fs.Trigger(ctx, "BeforeFileDownload")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.Log().Debug("BeforeFileDownload 钩子执行失败,%s", err)
|
util.Log().Debug("BeforeFileDownload 钩子执行失败,%s", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -68,16 +68,7 @@ type FileSystem struct {
|
||||||
/*
|
/*
|
||||||
钩子函数
|
钩子函数
|
||||||
*/
|
*/
|
||||||
// 上传文件前
|
Hooks map[string][]Hook
|
||||||
BeforeUpload []Hook
|
|
||||||
// 上传文件后
|
|
||||||
AfterUpload []Hook
|
|
||||||
// 文件保存成功,插入数据库验证失败后
|
|
||||||
AfterValidateFailed []Hook
|
|
||||||
// 用户取消上传后
|
|
||||||
AfterUploadCanceled []Hook
|
|
||||||
// 文件下载前
|
|
||||||
BeforeFileDownload []Hook
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
文件系统处理适配器
|
文件系统处理适配器
|
||||||
|
@ -102,11 +93,7 @@ func (fs *FileSystem) reset() {
|
||||||
fs.User = nil
|
fs.User = nil
|
||||||
fs.CleanTargets()
|
fs.CleanTargets()
|
||||||
fs.Policy = nil
|
fs.Policy = nil
|
||||||
fs.BeforeUpload = fs.BeforeUpload[:0]
|
fs.Hooks = nil
|
||||||
fs.AfterUpload = fs.AfterUpload[:0]
|
|
||||||
fs.AfterValidateFailed = fs.AfterValidateFailed[:0]
|
|
||||||
fs.AfterUploadCanceled = fs.AfterUploadCanceled[:0]
|
|
||||||
fs.BeforeFileDownload = fs.BeforeFileDownload[:0]
|
|
||||||
fs.Handler = nil
|
fs.Handler = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,11 +136,11 @@ func TestNewAnonymousFileSystem(t *testing.T) {
|
||||||
|
|
||||||
func TestFileSystem_Recycle(t *testing.T) {
|
func TestFileSystem_Recycle(t *testing.T) {
|
||||||
fs := &FileSystem{
|
fs := &FileSystem{
|
||||||
User: &model.User{},
|
User: &model.User{},
|
||||||
Policy: &model.Policy{},
|
Policy: &model.Policy{},
|
||||||
FileTarget: []model.File{model.File{}},
|
FileTarget: []model.File{model.File{}},
|
||||||
DirTarget: []model.Folder{model.Folder{}},
|
DirTarget: []model.Folder{model.Folder{}},
|
||||||
AfterUpload: []Hook{GenericAfterUpdate},
|
Hooks: map[string][]Hook{"AfterUpload": []Hook{GenericAfterUpdate}},
|
||||||
}
|
}
|
||||||
fs.Recycle()
|
fs.Recycle()
|
||||||
newFS := getEmptyFS()
|
newFS := getEmptyFS()
|
||||||
|
|
|
@ -18,28 +18,26 @@ type Hook func(ctx context.Context, fs *FileSystem) error
|
||||||
|
|
||||||
// Use 注入钩子
|
// Use 注入钩子
|
||||||
func (fs *FileSystem) Use(name string, hook Hook) {
|
func (fs *FileSystem) Use(name string, hook Hook) {
|
||||||
switch name {
|
if fs.Hooks == nil {
|
||||||
case "BeforeUpload":
|
fs.Hooks = make(map[string][]Hook)
|
||||||
fs.BeforeUpload = append(fs.BeforeUpload, hook)
|
|
||||||
case "AfterUpload":
|
|
||||||
fs.AfterUpload = append(fs.AfterUpload, hook)
|
|
||||||
case "AfterValidateFailed":
|
|
||||||
fs.AfterValidateFailed = append(fs.AfterValidateFailed, hook)
|
|
||||||
case "AfterUploadCanceled":
|
|
||||||
fs.AfterUploadCanceled = append(fs.AfterUploadCanceled, hook)
|
|
||||||
case "BeforeFileDownload":
|
|
||||||
fs.BeforeFileDownload = append(fs.BeforeFileDownload, hook)
|
|
||||||
}
|
}
|
||||||
|
if _, ok := fs.Hooks[name]; ok {
|
||||||
|
fs.Hooks[name] = append(fs.Hooks[name], hook)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fs.Hooks[name] = []Hook{hook}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger 触发钩子,遇到第一个错误时
|
// Trigger 触发钩子,遇到第一个错误时
|
||||||
// 返回错误,后续钩子不会继续执行
|
// 返回错误,后续钩子不会继续执行
|
||||||
func (fs *FileSystem) Trigger(ctx context.Context, hooks []Hook) error {
|
func (fs *FileSystem) Trigger(ctx context.Context, name string) error {
|
||||||
for _, hook := range hooks {
|
if hooks, ok := fs.Hooks[name]; ok {
|
||||||
err := hook(ctx, fs)
|
for _, hook := range hooks {
|
||||||
if err != nil {
|
err := hook(ctx, fs)
|
||||||
util.Log().Warning("钩子执行失败:%s", err)
|
if err != nil {
|
||||||
return err
|
util.Log().Warning("钩子执行失败:%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -223,7 +221,7 @@ func SlaveAfterUpload(ctx context.Context, fs *FileSystem) error {
|
||||||
fs.GenerateThumbnail(ctx, &file)
|
fs.GenerateThumbnail(ctx, &file)
|
||||||
|
|
||||||
// 发送回调请求
|
// 发送回调请求
|
||||||
callbackBody := serializer.UploadCallback{
|
callbackBody := serializer.RemoteUploadCallback{
|
||||||
Name: file.Name,
|
Name: file.Name,
|
||||||
SourceName: file.SourceName,
|
SourceName: file.SourceName,
|
||||||
PicInfo: file.PicInfo,
|
PicInfo: file.PicInfo,
|
||||||
|
|
|
@ -183,11 +183,11 @@ func TestFileSystem_Use(t *testing.T) {
|
||||||
|
|
||||||
// 添加一个
|
// 添加一个
|
||||||
fs.Use("BeforeUpload", hook)
|
fs.Use("BeforeUpload", hook)
|
||||||
asserts.Len(fs.BeforeUpload, 1)
|
asserts.Len(fs.Hooks["BeforeUpload"], 1)
|
||||||
|
|
||||||
// 添加一个
|
// 添加一个
|
||||||
fs.Use("BeforeUpload", hook)
|
fs.Use("BeforeUpload", hook)
|
||||||
asserts.Len(fs.BeforeUpload, 2)
|
asserts.Len(fs.Hooks["BeforeUpload"], 2)
|
||||||
|
|
||||||
// 不存在
|
// 不存在
|
||||||
fs.Use("BeforeUpload2333", hook)
|
fs.Use("BeforeUpload2333", hook)
|
||||||
|
@ -219,14 +219,14 @@ func TestFileSystem_Trigger(t *testing.T) {
|
||||||
|
|
||||||
// 一个
|
// 一个
|
||||||
fs.Use("BeforeUpload", hook)
|
fs.Use("BeforeUpload", hook)
|
||||||
err := fs.Trigger(ctx, fs.BeforeUpload)
|
err := fs.Trigger(ctx, "BeforeUpload")
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
asserts.Equal(uint64(1), fs.User.Storage)
|
asserts.Equal(uint64(1), fs.User.Storage)
|
||||||
|
|
||||||
// 多个
|
// 多个
|
||||||
fs.Use("BeforeUpload", hook)
|
fs.Use("BeforeUpload", hook)
|
||||||
fs.Use("BeforeUpload", hook)
|
fs.Use("BeforeUpload", hook)
|
||||||
err = fs.Trigger(ctx, fs.BeforeUpload)
|
err = fs.Trigger(ctx, "BeforeUpload")
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
asserts.Equal(uint64(4), fs.User.Storage)
|
asserts.Equal(uint64(4), fs.User.Storage)
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func (handler Handler) Source(
|
||||||
func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||||
// 生成回调地址
|
// 生成回调地址
|
||||||
siteURL := model.GetSiteURL()
|
siteURL := model.GetSiteURL()
|
||||||
apiBaseURI, _ := url.Parse("/api/v3/callback/upload/" + key)
|
apiBaseURI, _ := url.Parse("/api/v3/callback/remote/" + key)
|
||||||
apiURL := siteURL.ResolveReference(apiBaseURI)
|
apiURL := siteURL.ResolveReference(apiBaseURI)
|
||||||
|
|
||||||
// 生成上传策略
|
// 生成上传策略
|
||||||
|
|
|
@ -22,7 +22,7 @@ func (fs *FileSystem) Upload(ctx context.Context, file FileHeader) (err error) {
|
||||||
ctx = context.WithValue(ctx, fsctx.FileHeaderCtx, file)
|
ctx = context.WithValue(ctx, fsctx.FileHeaderCtx, file)
|
||||||
|
|
||||||
// 上传前的钩子
|
// 上传前的钩子
|
||||||
err = fs.Trigger(ctx, fs.BeforeUpload)
|
err = fs.Trigger(ctx, "BeforeUpload")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,11 @@ func (fs *FileSystem) Upload(ctx context.Context, file FileHeader) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传完成后的钩子
|
// 上传完成后的钩子
|
||||||
err = fs.Trigger(ctx, fs.AfterUpload)
|
err = fs.Trigger(ctx, "AfterUpload")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// 上传完成后续处理失败
|
// 上传完成后续处理失败
|
||||||
followUpErr := fs.Trigger(ctx, fs.AfterValidateFailed)
|
followUpErr := fs.Trigger(ctx, "AfterValidateFailed")
|
||||||
// 失败后再失败...
|
// 失败后再失败...
|
||||||
if followUpErr != nil {
|
if followUpErr != nil {
|
||||||
util.Log().Debug("AfterValidateFailed 钩子执行失败,%s", followUpErr)
|
util.Log().Debug("AfterValidateFailed 钩子执行失败,%s", followUpErr)
|
||||||
|
@ -125,11 +125,11 @@ func (fs *FileSystem) CancelUpload(ctx context.Context, path string, file FileHe
|
||||||
default:
|
default:
|
||||||
// 客户端取消上传,删除临时文件
|
// 客户端取消上传,删除临时文件
|
||||||
util.Log().Debug("客户端取消上传")
|
util.Log().Debug("客户端取消上传")
|
||||||
if fs.AfterUploadCanceled == nil {
|
if fs.Hooks["AfterUploadCanceled"] == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx = context.WithValue(ctx, fsctx.SavePathCtx, path)
|
ctx = context.WithValue(ctx, fsctx.SavePathCtx, path)
|
||||||
err := fs.Trigger(ctx, fs.AfterUploadCanceled)
|
err := fs.Trigger(ctx, "AfterUploadCanceled")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.Log().Debug("执行 AfterUploadCanceled 钩子出错,%s", err)
|
util.Log().Debug("执行 AfterUploadCanceled 钩子出错,%s", err)
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ func (fs *FileSystem) GetUploadToken(ctx context.Context, path string, size uint
|
||||||
"callback_"+callbackKey,
|
"callback_"+callbackKey,
|
||||||
serializer.UploadSession{
|
serializer.UploadSession{
|
||||||
UID: fs.User.ID,
|
UID: fs.User.ID,
|
||||||
|
PolicyID: fs.User.GetPolicyID(),
|
||||||
VirtualPath: path,
|
VirtualPath: path,
|
||||||
},
|
},
|
||||||
int(callBackSessionTTL),
|
int(callBackSessionTTL),
|
||||||
|
|
|
@ -120,7 +120,7 @@ func TestFileSystem_Upload(t *testing.T) {
|
||||||
})
|
})
|
||||||
err = fs.Upload(ctx, file)
|
err = fs.Upload(ctx, file)
|
||||||
asserts.Error(err)
|
asserts.Error(err)
|
||||||
fs.BeforeUpload = nil
|
fs.Hooks["BeforeUpload"] = nil
|
||||||
testHandller.AssertExpectations(t)
|
testHandller.AssertExpectations(t)
|
||||||
|
|
||||||
// 上传文件失败
|
// 上传文件失败
|
||||||
|
|
|
@ -13,8 +13,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// RemoteCallback 发送远程存储策略上传回调请求
|
// RemoteCallback 发送远程存储策略上传回调请求
|
||||||
func RemoteCallback(url string, body serializer.UploadCallback) error {
|
func RemoteCallback(url string, body serializer.RemoteUploadCallback) error {
|
||||||
callbackBody, err := json.Marshal(body)
|
callbackBody, err := json.Marshal(struct {
|
||||||
|
Data serializer.RemoteUploadCallback `json:"data"`
|
||||||
|
}{
|
||||||
|
Data: body,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return serializer.NewError(serializer.CodeCallbackError, "无法编码回调正文", err)
|
return serializer.NewError(serializer.CodeCallbackError, "无法编码回调正文", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestRemoteCallback(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
GeneralClient = clientMock
|
GeneralClient = clientMock
|
||||||
resp := RemoteCallback("http://test/test/url", serializer.UploadCallback{
|
resp := RemoteCallback("http://test/test/url", serializer.RemoteUploadCallback{
|
||||||
SourceName: "source",
|
SourceName: "source",
|
||||||
})
|
})
|
||||||
asserts.NoError(resp)
|
asserts.NoError(resp)
|
||||||
|
@ -59,7 +59,7 @@ func TestRemoteCallback(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
GeneralClient = clientMock
|
GeneralClient = clientMock
|
||||||
resp := RemoteCallback("http://test/test/url", serializer.UploadCallback{
|
resp := RemoteCallback("http://test/test/url", serializer.RemoteUploadCallback{
|
||||||
SourceName: "source",
|
SourceName: "source",
|
||||||
})
|
})
|
||||||
asserts.EqualValues(401, resp.(serializer.AppError).Code)
|
asserts.EqualValues(401, resp.(serializer.AppError).Code)
|
||||||
|
@ -83,7 +83,7 @@ func TestRemoteCallback(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
GeneralClient = clientMock
|
GeneralClient = clientMock
|
||||||
resp := RemoteCallback("http://test/test/url", serializer.UploadCallback{
|
resp := RemoteCallback("http://test/test/url", serializer.RemoteUploadCallback{
|
||||||
SourceName: "source",
|
SourceName: "source",
|
||||||
})
|
})
|
||||||
asserts.Error(resp)
|
asserts.Error(resp)
|
||||||
|
@ -107,7 +107,7 @@ func TestRemoteCallback(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
GeneralClient = clientMock
|
GeneralClient = clientMock
|
||||||
resp := RemoteCallback("http://test/test/url", serializer.UploadCallback{
|
resp := RemoteCallback("http://test/test/url", serializer.RemoteUploadCallback{
|
||||||
SourceName: "source",
|
SourceName: "source",
|
||||||
})
|
})
|
||||||
asserts.Error(resp)
|
asserts.Error(resp)
|
||||||
|
@ -127,7 +127,7 @@ func TestRemoteCallback(t *testing.T) {
|
||||||
Err: errors.New("error"),
|
Err: errors.New("error"),
|
||||||
})
|
})
|
||||||
GeneralClient = clientMock
|
GeneralClient = clientMock
|
||||||
resp := RemoteCallback("http://test/test/url", serializer.UploadCallback{
|
resp := RemoteCallback("http://test/test/url", serializer.RemoteUploadCallback{
|
||||||
SourceName: "source",
|
SourceName: "source",
|
||||||
})
|
})
|
||||||
asserts.Error(resp)
|
asserts.Error(resp)
|
||||||
|
|
|
@ -25,11 +25,12 @@ type UploadCredential struct {
|
||||||
// UploadSession 上传会话
|
// UploadSession 上传会话
|
||||||
type UploadSession struct {
|
type UploadSession struct {
|
||||||
UID uint
|
UID uint
|
||||||
|
PolicyID uint
|
||||||
VirtualPath string
|
VirtualPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadCallback 远程存储策略上传回调正文
|
// RemoteUploadCallback 远程存储策略上传回调正文
|
||||||
type UploadCallback struct {
|
type RemoteUploadCallback struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
SourceName string `json:"source_name"`
|
SourceName string `json:"source_name"`
|
||||||
PicInfo string `json:"pic_info"`
|
PicInfo string `json:"pic_info"`
|
||||||
|
|
17
routers/controllers/callback.go
Normal file
17
routers/controllers/callback.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/HFO4/cloudreve/service/callback"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoteCallback 远程上传回调
|
||||||
|
func RemoteCallback(c *gin.Context) {
|
||||||
|
var callbackBody callback.RemoteUploadCallbackService
|
||||||
|
if err := c.ShouldBindJSON(&callbackBody); err == nil {
|
||||||
|
res := callbackBody.Process(c)
|
||||||
|
c.JSON(200, res)
|
||||||
|
} else {
|
||||||
|
c.JSON(200, ErrorResponse(err))
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,6 +114,17 @@ func InitMasterRouter() *gin.Engine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 回调接口
|
||||||
|
callback := v3.Group("callback")
|
||||||
|
{
|
||||||
|
// 远程上传回调
|
||||||
|
callback.POST(
|
||||||
|
"remote/:key",
|
||||||
|
middleware.RemoteCallbackAuth(),
|
||||||
|
controllers.RemoteCallback,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// 需要登录保护的
|
// 需要登录保护的
|
||||||
auth := v3.Group("")
|
auth := v3.Group("")
|
||||||
auth.Use(middleware.AuthRequired())
|
auth.Use(middleware.AuthRequired())
|
||||||
|
|
26
service/callback/upload.go
Normal file
26
service/callback/upload.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package callback
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/HFO4/cloudreve/pkg/filesystem"
|
||||||
|
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoteUploadCallbackService 远程存储上传回调请求服务
|
||||||
|
type RemoteUploadCallbackService struct {
|
||||||
|
Data serializer.RemoteUploadCallback `json:"data" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process 处理远程策略上传结果回调
|
||||||
|
func (service *RemoteUploadCallbackService) Process(c *gin.Context) serializer.Response {
|
||||||
|
// 创建文件系统
|
||||||
|
fs, err := filesystem.NewFileSystemFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err)
|
||||||
|
}
|
||||||
|
defer fs.Recycle()
|
||||||
|
|
||||||
|
return serializer.Response{
|
||||||
|
Code: 0,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue