diff --git a/cloudpan/apiutil/utils.go b/cloudpan/apiutil/utils.go index 405345b..68c93e0 100644 --- a/cloudpan/apiutil/utils.go +++ b/cloudpan/apiutil/utils.go @@ -20,12 +20,13 @@ import ( "crypto/sha1" "encoding/hex" "fmt" - uuid "github.com/satori/go.uuid" "math/rand" "net/http" "sort" "strings" "time" + + uuid "github.com/satori/go.uuid" ) const ( @@ -37,7 +38,7 @@ FlhDeqVOG094hFJvZeK4OzA6HVwzwnEW5vIZ7d+u61RV1bsFxmB68+8JXs3ycGcE -----END PUBLIC KEY-----` b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - bi_rm = "0123456789abcdefghijklmnopqrstuvwxyz" + bi_rm = "0123456789abcdefghijklmnopqrstuvwxyz" FileNameSpecialChars = "\\/:*?\"<>|" ) @@ -60,7 +61,7 @@ func B64toHex(b64str string) (hexstr string) { sb := strings.Builder{} e := 0 c := 0 - for _,r := range b64str { + for _, r := range b64str { if r != '=' { v := strings.Index(b64map, string(r)) if 0 == e { @@ -69,7 +70,7 @@ func B64toHex(b64str string) (hexstr string) { c = 3 & v } else if 1 == e { e = 2 - sb.WriteByte(int2char(c << 2 | v >> 4)) + sb.WriteByte(int2char(c<<2 | v>>4)) c = 15 & v } else if 2 == e { e = 3 @@ -78,7 +79,7 @@ func B64toHex(b64str string) (hexstr string) { c = 3 & v } else { e = 0 - sb.WriteByte(int2char(c << 2 | v >> 4)) + sb.WriteByte(int2char(c<<2 | v>>4)) sb.WriteByte(int2char(15 & v)) } } @@ -104,7 +105,7 @@ func Timestamp() int { func SignatureOfMd5(params map[string]string) string { keys := []string{} for k, v := range params { - keys = append(keys, k + "=" + v) + keys = append(keys, k+"="+v) } // sort @@ -135,6 +136,17 @@ func SignatureOfHmac(secretKey, sessionKey, operate, url, dateOfGmt string) stri return strings.ToUpper(hex.EncodeToString(mac.Sum(nil))) } +// 获取缩略图的Signature +func PreviewPhotoSignatureOfHmac(secretKey, sessionKey, fileId, size, timeStamp string) string { + plainStr := &strings.Builder{} + fmt.Fprintf(plainStr, "SessionKey=%s&Operate=GET&FileId=%s&Size=%s&TimeStamp=%s", + sessionKey, fileId, size, timeStamp) + key := []byte(secretKey) + mac := hmac.New(sha1.New, key) + mac.Write([]byte(plainStr.String())) + return strings.ToUpper(hex.EncodeToString(mac.Sum(nil))) +} + func Rand() string { randStr := &strings.Builder{} fmt.Fprintf(randStr, "%d_%d", rand.Int63n(1e5), rand.Int63n(1e10)) @@ -170,4 +182,4 @@ func CheckFileNameValid(name string) bool { return true } return !strings.ContainsAny(name, FileNameSpecialChars) -} \ No newline at end of file +} diff --git a/cloudpan/app_family.go b/cloudpan/app_family.go index eba4ea9..6bc9cda 100644 --- a/cloudpan/app_family.go +++ b/cloudpan/app_family.go @@ -17,29 +17,29 @@ package cloudpan import ( "encoding/xml" "fmt" + "strings" + "github.com/tickstep/cloudpan189-api/cloudpan/apierror" "github.com/tickstep/cloudpan189-api/cloudpan/apiutil" "github.com/tickstep/library-go/logger" - "strings" ) type ( // AppGetFileInfoParam 获取文件信息参数 AppFamilyInfo struct { - Count int `xml:"count" xml:"count"` - Type int `xml:"type" json:"type"` - UserRole int `xml:"userRole" json:"userRole"` + Count int `xml:"count" json:"count"` + Type int `xml:"type" json:"type"` + UserRole int `xml:"userRole" json:"userRole"` CreateTime string `xml:"createTime" json:"createTime"` - FamilyId int64 `xml:"familyId" json:"familyId"` + FamilyId int64 `xml:"familyId" json:"familyId"` RemarkName string `xml:"remarkName" json:"remarkName"` - UseFlag int `xml:"useFlag" json:"useFlag"` + UseFlag int `xml:"useFlag" json:"useFlag"` } AppFamilyInfoListResult struct { - XMLName xml.Name `xml:"familyListResponse"` + XMLName xml.Name `xml:"familyListResponse"` FamilyInfoList []*AppFamilyInfo `xml:"familyInfo" json:"familyInfoList"` } - ) // AppGetFamilyList 获取用户的家庭列表 @@ -50,10 +50,10 @@ func (p *PanClient) AppFamilyGetFamilyList() (*AppFamilyInfoListResult, *apierro httpMethod := "GET" dateOfGmt := apiutil.DateOfGmtStr() appToken := p.appToken - headers := map[string]string { - "Date": dateOfGmt, - "SessionKey": appToken.FamilySessionKey, - "Signature": apiutil.SignatureOfHmac(appToken.SessionSecret, appToken.FamilySessionKey, httpMethod, fullUrl.String(), dateOfGmt), + headers := map[string]string{ + "Date": dateOfGmt, + "SessionKey": appToken.FamilySessionKey, + "Signature": apiutil.SignatureOfHmac(appToken.SessionSecret, appToken.FamilySessionKey, httpMethod, fullUrl.String(), dateOfGmt), "X-Request-ID": apiutil.XRequestId(), } logger.Verboseln("do request url: " + fullUrl.String()) @@ -74,4 +74,4 @@ func (p *PanClient) AppFamilyGetFamilyList() (*AppFamilyInfoListResult, *apierro return nil, apierror.NewApiErrorWithError(err) } return item, nil -} \ No newline at end of file +} diff --git a/cloudpan/app_photo_preview.go b/cloudpan/app_photo_preview.go new file mode 100644 index 0000000..ad94726 --- /dev/null +++ b/cloudpan/app_photo_preview.go @@ -0,0 +1,52 @@ +package cloudpan + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/tickstep/cloudpan189-api/cloudpan/apiutil" +) + +const ( + API_PREVIEW_URL = "https://preview.cloud.189.cn" +) + +// preview picture struct +type PictureSize struct { + Width uint + Height uint +} + +// return the new picturesize struct with the specified size +func NewPictureSize(width, height uint) PictureSize { + return PictureSize{ + Width: width, + Height: height, + } +} + +// return the string +func (p PictureSize) String() string { + return fmt.Sprintf("%d_%d", p.Width, p.Height) +} + +// get file preview picture url +func (p *PanClient) AppGetPhotoPreviewUrl(fileId string, pictureSize PictureSize) string { + timestamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) + fullUrl := new(strings.Builder) + signature := strings.ToLower(apiutil.PreviewPhotoSignatureOfHmac(p.appToken.SessionSecret, + p.appToken.SessionKey, + fileId, pictureSize.String(), + timestamp)) + fmt.Fprintf(fullUrl, "%s/image/clientImageAction?fileId=%s&size=%s&sessionKey=%s&signature=%s&timeStamp=%s", + API_PREVIEW_URL, + fileId, + pictureSize.String(), + p.appToken.SessionKey, + signature, + timestamp, + ) + return fullUrl.String() +} diff --git a/go.sum b/go.sum index fda783a..e50dc10 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,6 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= @@ -20,16 +18,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tickstep/library-go v0.0.1 h1:UbXeGE6ZxnxA6KTjMofEhG3h2aHJ4UGacfh7U2B4zgw= -github.com/tickstep/library-go v0.0.1/go.mod h1:egoK/RvOJ3Qs2tHpkq374CWjhNjI91JSCCG1GrhDYSw= -github.com/tickstep/library-go v0.0.3/go.mod h1:egoK/RvOJ3Qs2tHpkq374CWjhNjI91JSCCG1GrhDYSw= -github.com/tickstep/library-go v0.0.4/go.mod h1:egoK/RvOJ3Qs2tHpkq374CWjhNjI91JSCCG1GrhDYSw= +github.com/tickstep/library-go v0.0.5 h1:MBb1tsvs4Wi67zy0E9eobVWLgsfPRLsqKAEdSEi3LBE= +github.com/tickstep/library-go v0.0.5/go.mod h1:egoK/RvOJ3Qs2tHpkq374CWjhNjI91JSCCG1GrhDYSw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=