diff --git a/middleware/auth.go b/middleware/auth.go index 1540d0a..ca67402 100644 --- a/middleware/auth.go +++ b/middleware/auth.go @@ -1,11 +1,17 @@ package middleware import ( + "bytes" + "context" + "crypto/md5" + "fmt" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem" "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/oss" + "github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/upyun" "github.com/cloudreve/Cloudreve/v3/pkg/mq" "github.com/cloudreve/Cloudreve/v3/pkg/util" "github.com/qiniu/go-sdk/v7/auth/qbox" + "io/ioutil" "net/http" model "github.com/cloudreve/Cloudreve/v3/models" @@ -221,53 +227,47 @@ func OSSCallbackAuth() gin.HandlerFunc { // UpyunCallbackAuth 又拍云回调签名验证 func UpyunCallbackAuth() gin.HandlerFunc { return func(c *gin.Context) { - //// 验证key并查找用户 - //resp, user := uploadCallbackCheck(c) - //if resp.Code != 0 { - // c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: resp.Msg}) - // c.Abort() - // return - //} - // - //// 获取请求正文 - //body, err := ioutil.ReadAll(c.Request.Body) - //c.Request.Body.Close() - //if err != nil { - // c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: err.Error()}) - // c.Abort() - // return - //} - // - //c.Request.Body = ioutil.NopCloser(bytes.NewReader(body)) - // - //// 准备验证Upyun回调签名 - //handler := upyun.Driver{Policy: &user.Policy} - //contentMD5 := c.Request.Header.Get("Content-Md5") - //date := c.Request.Header.Get("Date") - //actualSignature := c.Request.Header.Get("Authorization") - // - //// 计算正文MD5 - //actualContentMD5 := fmt.Sprintf("%x", md5.Sum(body)) - //if actualContentMD5 != contentMD5 { - // c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: "MD5不一致"}) - // c.Abort() - // return - //} - // - //// 计算理论签名 - //signature := handler.Sign(context.Background(), []string{ - // "POST", - // c.Request.URL.Path, - // date, - // contentMD5, - //}) - // - //// 对比签名 - //if signature != actualSignature { - // c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: "鉴权失败"}) - // c.Abort() - // return - //} + session := c.MustGet(filesystem.UploadSessionCtx).(*serializer.UploadSession) + + // 获取请求正文 + body, err := ioutil.ReadAll(c.Request.Body) + c.Request.Body.Close() + if err != nil { + c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: err.Error()}) + c.Abort() + return + } + + c.Request.Body = ioutil.NopCloser(bytes.NewReader(body)) + + // 准备验证Upyun回调签名 + handler := upyun.Driver{Policy: &session.Policy} + contentMD5 := c.Request.Header.Get("Content-Md5") + date := c.Request.Header.Get("Date") + actualSignature := c.Request.Header.Get("Authorization") + + // 计算正文MD5 + actualContentMD5 := fmt.Sprintf("%x", md5.Sum(body)) + if actualContentMD5 != contentMD5 { + c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: "MD5不一致"}) + c.Abort() + return + } + + // 计算理论签名 + signature := handler.Sign(context.Background(), []string{ + "POST", + c.Request.URL.Path, + date, + contentMD5, + }) + + // 对比签名 + if signature != actualSignature { + c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: "鉴权失败"}) + c.Abort() + return + } c.Next() } diff --git a/pkg/filesystem/driver/upyun/handler.go b/pkg/filesystem/driver/upyun/handler.go index ab03396..0357f72 100644 --- a/pkg/filesystem/driver/upyun/handler.go +++ b/pkg/filesystem/driver/upyun/handler.go @@ -311,8 +311,6 @@ func (handler Driver) signURL(ctx context.Context, path *url.URL, TTL int64) (st // Token 获取上传策略和认证Token func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *serializer.UploadSession, file fsctx.FileHeader) (*serializer.UploadCredential, error) { - // 检查文件大小 - // 生成回调地址 siteURL := model.GetSiteURL() apiBaseURI, _ := url.Parse("/api/v3/callback/upyun/" + uploadSession.Key) @@ -332,17 +330,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria } // 生成上传凭证 - return handler.getUploadCredential(ctx, putPolicy) -} - -// 取消上传凭证 -func (handler Driver) CancelToken(ctx context.Context, uploadSession *serializer.UploadSession) error { - return nil -} - -func (handler Driver) getUploadCredential(ctx context.Context, policy UploadPolicy) (*serializer.UploadCredential, error) { - // 生成上传策略 - policyJSON, err := json.Marshal(policy) + policyJSON, err := json.Marshal(putPolicy) if err != nil { return nil, err } @@ -353,11 +341,18 @@ func (handler Driver) getUploadCredential(ctx context.Context, policy UploadPoli signStr := handler.Sign(ctx, elements) return &serializer.UploadCredential{ - Policy: policyEncoded, - Token: signStr, + SessionID: uploadSession.Key, + Policy: policyEncoded, + Credential: signStr, + UploadURLs: []string{"https://v0.api.upyun.com/" + handler.Policy.BucketName}, }, nil } +// 取消上传凭证 +func (handler Driver) CancelToken(ctx context.Context, uploadSession *serializer.UploadSession) error { + return nil +} + // Sign 计算又拍云的签名头 func (handler Driver) Sign(ctx context.Context, elements []string) string { password := fmt.Sprintf("%x", md5.Sum([]byte(handler.Policy.SecretKey))) diff --git a/routers/router.go b/routers/router.go index fae395c..bfaa37e 100644 --- a/routers/router.go +++ b/routers/router.go @@ -258,7 +258,8 @@ func InitMasterRouter() *gin.Engine { ) // 又拍云策略上传回调 callback.POST( - "upyun/:key", + "upyun/:sessionID", + middleware.UseUploadSession("upyun"), middleware.UpyunCallbackAuth(), controllers.UpyunCallback, )