diff --git a/drivers/123/123.go b/drivers/123/123.go index 77f1fc2f..027d278e 100644 --- a/drivers/123/123.go +++ b/drivers/123/123.go @@ -1,8 +1,6 @@ package _23 import ( - "crypto/hmac" - "crypto/sha256" "errors" "fmt" "github.com/Xhofe/alist/conf" @@ -12,7 +10,6 @@ import ( "github.com/go-resty/resty/v2" jsoniter "github.com/json-iterator/go" log "github.com/sirupsen/logrus" - "math/rand" "path/filepath" "strconv" "time" @@ -55,6 +52,18 @@ type Pan123DownResp struct { } `json:"data"` } +type UploadResp struct { + BaseResp + Data struct { + AccessKeyId string `json:"AccessKeyId"` + Bucket string `json:"Bucket"` + Key string `json:"Key"` + SecretAccessKey string `json:"SecretAccessKey"` + SessionToken string `json:"SessionToken"` + FileId int64 `json:"FileId"` + } `json:"data"` +} + func (driver Pan123) Login(account *model.Account) error { url := "https://www.123pan.com/api/user/sign_in" if account.APIProxyUrl != "" { @@ -205,27 +214,16 @@ func (driver Pan123) GetFile(path string, account *model.Account) (*Pan123File, return nil, base.ErrPathNotFound } -func RandStr(length int) string { - str := "123456789abcdefghijklmnopqrstuvwxyz" - bytes := []byte(str) - var result []byte - rand.Seed(time.Now().UnixNano() + int64(rand.Intn(100))) - for i := 0; i < length; i++ { - result = append(result, bytes[rand.Intn(len(bytes))]) - } - return string(result) -} - -func HMAC(message string, secret string) string { - key := []byte(secret) - h := hmac.New(sha256.New, key) - h.Write([]byte(message)) - // fmt.Println(h.Sum(nil)) - //sha := hex.EncodeToString(h.Sum(nil)) - // fmt.Println(sha) - //return sha - return string(h.Sum(nil)) -} +//func HMAC(message string, secret string) string { +// key := []byte(secret) +// h := hmac.New(sha256.New, key) +// h.Write([]byte(message)) +// // fmt.Println(h.Sum(nil)) +// //sha := hex.EncodeToString(h.Sum(nil)) +// // fmt.Println(sha) +// //return sha +// return string(h.Sum(nil)) +//} func init() { base.RegisterDriver(&Pan123{}) diff --git a/drivers/123/driver.go b/drivers/123/driver.go index d999d895..4851ae91 100644 --- a/drivers/123/driver.go +++ b/drivers/123/driver.go @@ -1,21 +1,20 @@ package _23 import ( - "encoding/hex" - "encoding/xml" "fmt" "github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/drivers/base" "github.com/Xhofe/alist/model" "github.com/Xhofe/alist/utils" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/gin-gonic/gin" - jsoniter "github.com/json-iterator/go" log "github.com/sirupsen/logrus" "net/url" "path/filepath" "strconv" - "strings" - "time" ) type Pan123 struct{} @@ -280,16 +279,10 @@ func (driver Pan123) Delete(path string, account *model.Account) error { return err } -type UploadResp struct { - XMLName xml.Name `xml:"InitiateMultipartUploadResult"` - Bucket string `xml:"Bucket"` - Key string `xml:"Key"` - UploadId string `xml:"UploadId"` -} - -// TODO unfinished func (driver Pan123) Upload(file *model.FileStream, account *model.Account) error { - return base.ErrNotImplement + if file == nil { + return base.ErrEmptyFile + } parentFile, err := driver.File(file.ParentPath, account) if err != nil { return err @@ -301,47 +294,106 @@ func (driver Pan123) Upload(file *model.FileStream, account *model.Account) erro data := base.Json{ "driveId": 0, "duplicate": true, - "etag": RandStr(32), //maybe file's md5 + "etag": "836aae6cac845e17fce51919594737d0", //maybe file's md5 "fileName": file.GetFileName(), "parentFileId": parentFileId, "size": file.GetSize(), "type": 0, } - res, err := driver.Request("https://www.123pan.com/api/file/upload_request", - base.Post, nil, nil, &data, nil, false, account) + var resp UploadResp + _, err = driver.Request("https://www.123pan.com/api/file/upload_request", + base.Post, nil, nil, &data, &resp, false, account) //res, err := driver.Post("https://www.123pan.com/api/file/upload_request", data, account) if err != nil { return err } - baseUrl := fmt.Sprintf("https://file.123pan.com/%s/%s", jsoniter.Get(res, "data.Bucket").ToString(), jsoniter.Get(res, "data.Key").ToString()) - var resp UploadResp - kSecret := jsoniter.Get(res, "data.SecretAccessKey").ToString() - nowTimeStr := time.Now().String() - Date := strings.ReplaceAll(strings.Split(nowTimeStr, "T")[0], "-", "") - - StringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", - "AWS4-HMAC-SHA256", - nowTimeStr, - fmt.Sprintf("%s/us-east-1/s3/aws4_request", Date), - ) - - kDate := HMAC("AWS4"+kSecret, Date) - kRegion := HMAC(kDate, "us-east-1") - kService := HMAC(kRegion, "s3") - kSigning := HMAC(kService, "aws4_request") - _, err = base.RestyClient.R().SetResult(&resp).SetHeaders(map[string]string{ - "Authorization": fmt.Sprintf("AWS4-HMAC-SHA256 Credential=%s/%s/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=%s", - jsoniter.Get(res, "data.AccessKeyId"), - Date, - hex.EncodeToString([]byte(HMAC(StringToSign, kSigning)))), - "X-Amz-Content-Sha256": "UNSIGNED-PAYLOAD", - "X-Amz-Date": nowTimeStr, - "x-amz-security-token": jsoniter.Get(res, "data.SessionToken").ToString(), - }).Post(fmt.Sprintf("%s?uploads", baseUrl)) + cfg := &aws.Config{ + Credentials: credentials.NewStaticCredentials(resp.Data.AccessKeyId, resp.Data.SecretAccessKey, resp.Data.SessionToken), + Region: aws.String("123pan"), + Endpoint: aws.String("123pan.com/" + resp.Data.Bucket), + } + s, err := session.NewSession(cfg) if err != nil { return err } - return base.ErrNotImplement + uploader := s3manager.NewUploader(s) + input := &s3manager.UploadInput{ + Bucket: aws.String("file"), + Key: &resp.Data.Key, + Body: file, + } + _, err = uploader.Upload(input) + if err != nil { + return err + } + _, err = driver.Request("https://www.123pan.com/api/file/upload_complete", base.Post, nil, nil, &base.Json{ + "fileId": resp.Data.FileId, + }, nil, false, account) + return err } +//type UploadResp struct { +// XMLName xml.Name `xml:"InitiateMultipartUploadResult"` +// Bucket string `xml:"Bucket"` +// Key string `xml:"Key"` +// UploadId string `xml:"UploadId"` +//} + +// TODO unfinished +//func (driver Pan123) Upload(file *model.FileStream, account *model.Account) error { +// return base.ErrNotImplement +// parentFile, err := driver.File(file.ParentPath, account) +// if err != nil { +// return err +// } +// if !parentFile.IsDir() { +// return base.ErrNotFolder +// } +// parentFileId, _ := strconv.Atoi(parentFile.Id) +// data := base.Json{ +// "driveId": 0, +// "duplicate": true, +// "etag": RandStr(32), //maybe file's md5 +// "fileName": file.GetFileName(), +// "parentFileId": parentFileId, +// "size": file.GetSize(), +// "type": 0, +// } +// res, err := driver.Request("https://www.123pan.com/api/file/upload_request", +// base.Post, nil, nil, &data, nil, false, account) +// //res, err := driver.Post("https://www.123pan.com/api/file/upload_request", data, account) +// if err != nil { +// return err +// } +// baseUrl := fmt.Sprintf("https://file.123pan.com/%s/%s", jsoniter.Get(res, "data.Bucket").ToString(), jsoniter.Get(res, "data.Key").ToString()) +// var resp UploadResp +// kSecret := jsoniter.Get(res, "data.SecretAccessKey").ToString() +// nowTimeStr := time.Now().String() +// Date := strings.ReplaceAll(strings.Split(nowTimeStr, "T")[0], "-", "") +// +// StringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", +// "AWS4-HMAC-SHA256", +// nowTimeStr, +// fmt.Sprintf("%s/us-east-1/s3/aws4_request", Date), +// ) +// +// kDate := HMAC("AWS4"+kSecret, Date) +// kRegion := HMAC(kDate, "us-east-1") +// kService := HMAC(kRegion, "s3") +// kSigning := HMAC(kService, "aws4_request") +// _, err = base.RestyClient.R().SetResult(&resp).SetHeaders(map[string]string{ +// "Authorization": fmt.Sprintf("AWS4-HMAC-SHA256 Credential=%s/%s/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=%s", +// jsoniter.Get(res, "data.AccessKeyId"), +// Date, +// hex.EncodeToString([]byte(HMAC(StringToSign, kSigning)))), +// "X-Amz-Content-Sha256": "UNSIGNED-PAYLOAD", +// "X-Amz-Date": nowTimeStr, +// "x-amz-security-token": jsoniter.Get(res, "data.SessionToken").ToString(), +// }).Post(fmt.Sprintf("%s?uploads", baseUrl)) +// if err != nil { +// return err +// } +// return base.ErrNotImplement +//} + var _ base.Driver = (*Pan123)(nil) diff --git a/drivers/pikpak/driver.go b/drivers/pikpak/driver.go index d6bd4051..f759659b 100644 --- a/drivers/pikpak/driver.go +++ b/drivers/pikpak/driver.go @@ -6,7 +6,10 @@ import ( "github.com/Xhofe/alist/drivers/base" "github.com/Xhofe/alist/model" "github.com/Xhofe/alist/utils" - "github.com/aliyun/aliyun-oss-go-sdk/oss" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" log "github.com/sirupsen/logrus" @@ -250,21 +253,71 @@ func (driver PikPak) Upload(file *model.FileStream, account *model.Account) erro accessKeyId := params.Get("access_key_id").ToString() accessKeySecret := params.Get("access_key_secret").ToString() securityToken := params.Get("security_token").ToString() - client, err := oss.New("https://"+endpoint, accessKeyId, - accessKeySecret, oss.SecurityToken(securityToken)) + key := params.Get("key").ToString() + bucket := params.Get("bucket").ToString() + cfg := &aws.Config{ + Credentials: credentials.NewStaticCredentials(accessKeyId, accessKeySecret, securityToken), + Region: aws.String("pikpak"), + Endpoint: &endpoint, + } + s, err := session.NewSession(cfg) if err != nil { return err } - bucket, err := client.Bucket(params.Get("bucket").ToString()) - if err != nil { - return err + uploader := s3manager.NewUploader(s) + input := &s3manager.UploadInput{ + Bucket: &bucket, + Key: &key, + Body: file, } - signedURL, err := bucket.SignURL(params.Get("key").ToString(), oss.HTTPPut, 60) - if err != nil { - return err - } - err = bucket.PutObjectWithURL(signedURL, file) + _, err = uploader.Upload(input) return err } +// use aliyun-oss-sdk +//func (driver PikPak) Upload(file *model.FileStream, account *model.Account) error { +// if file == nil { +// return base.ErrEmptyFile +// } +// parentFile, err := driver.File(file.ParentPath, account) +// if err != nil { +// return err +// } +// data := base.Json{ +// "kind": "drive#file", +// "name": file.GetFileName(), +// "size": file.GetSize(), +// "hash": "1CF254FBC456E1B012CD45C546636AA62CF8350E", +// "upload_type": "UPLOAD_TYPE_RESUMABLE", +// "objProvider": base.Json{"provider": "UPLOAD_TYPE_UNKNOWN"}, +// "parent_id": parentFile.Id, +// } +// res, err := driver.Request("https://api-drive.mypikpak.com/drive/v1/files", base.Post, nil, &data, nil, account) +// if err != nil { +// return err +// } +// params := jsoniter.Get(res, "resumable").Get("params") +// endpoint := params.Get("endpoint").ToString() +// endpointS := strings.Split(endpoint, ".") +// endpoint = strings.Join(endpointS[1:], ".") +// accessKeyId := params.Get("access_key_id").ToString() +// accessKeySecret := params.Get("access_key_secret").ToString() +// securityToken := params.Get("security_token").ToString() +// client, err := oss.New("https://"+endpoint, accessKeyId, +// accessKeySecret, oss.SecurityToken(securityToken)) +// if err != nil { +// return err +// } +// bucket, err := client.Bucket(params.Get("bucket").ToString()) +// if err != nil { +// return err +// } +// signedURL, err := bucket.SignURL(params.Get("key").ToString(), oss.HTTPPut, 60) +// if err != nil { +// return err +// } +// err = bucket.PutObjectWithURL(signedURL, file) +// return err +//} + var _ base.Driver = (*PikPak)(nil) diff --git a/go.mod b/go.mod index fb368368..8895a798 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/robfig/cron/v3 v3.0.0 github.com/sirupsen/logrus v1.8.1 + github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f golang.org/x/text v0.3.7 gorm.io/driver/mysql v1.1.2 gorm.io/driver/postgres v1.1.2 @@ -22,7 +23,6 @@ require ( require ( github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2 // indirect - github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect github.com/cenkalti/backoff/v4 v4.1.0 // indirect @@ -58,7 +58,6 @@ require ( github.com/prometheus/common v0.18.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/spf13/cast v1.3.1 // indirect - github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f // indirect github.com/ugorji/go/codec v1.2.6 // indirect go.opentelemetry.io/otel v0.20.0 // indirect go.opentelemetry.io/otel/metric v0.20.0 // indirect @@ -66,7 +65,6 @@ require ( golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70 // indirect - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 // indirect diff --git a/go.sum b/go.sum index d3923fc7..ec296457 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible h1:ht2+VfbXtNLGhCsnTMc6/N26nSTBK6qdhktjYyjJQkk= -github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/allegro/bigcache/v2 v2.2.5 h1:mRc8r6GQjuJsmSKQNPsR5jQVXc8IJ1xsW5YXUYMLfqI= github.com/allegro/bigcache/v2 v2.2.5/go.mod h1:FppZsIO+IZk7gCuj5FiIDHGygD9xvWQcqg1uIPMb6tY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -640,7 +638,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=