packer-cn/vendor/github.com/ufilesdk-dev/ufile-gosdk/auth.go

140 lines
4.3 KiB
Go
Raw Normal View History

2019-10-12 04:46:21 -04:00
package ufsdk
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strings"
)
//Auth 构造签名的工具,使用本 SDK 你不需要关心 Auth 这一整个模块,以及它暴露出来的签名算法。
//如果你希望自己封装 API 可以使用这里面的暴露出来的接口来填充 http authorization。
type Auth struct {
publicKey string
privateKey string
}
//NewAuth 构造一个新的签名工具,传入你的公钥匙和私钥。
func NewAuth(publicKey, privateKey string) Auth {
return Auth{
publicKey: publicKey,
privateKey: privateKey,
}
}
//Authorization 构造一个主要用于上传文件的签名,返回 HMAC-Sh1 的签名字符串,可以直接填充到 HTTP authorization header 里面。
//key 是传到 ufile 所使用的文件名bucekt 是文件上传后存放的 bucket。
//method 就是你当前这个 HTTP 请求的 Method。
2019-10-30 13:48:41 -04:00
//header 就是你当前这个 HTTP 的 header。
2019-10-12 04:46:21 -04:00
func (A Auth) Authorization(method, bucket, key string, header http.Header) string {
var sigData string
method = strings.ToUpper(method)
md5 := header.Get("Content-MD5")
contentType := header.Get("Content-Type")
date := header.Get("Date")
sigData = method + "\n" + md5 + "\n" + contentType + "\n" + date + "\n"
2019-10-30 13:48:41 -04:00
sigData += A.CanonicalizedUcloudHeaders(header)
2019-10-12 04:46:21 -04:00
resource := "/" + bucket + "/" + key
sigData += resource
signature := A.signature(sigData)
return "UCloud " + A.publicKey + ":" + signature
}
//AuthorizationPrivateURL 构造私有空间文件下载链接的签名,其中 expires 是当前的时间加上一个过期的时间,再转为字符串。格式是 unix time second.
//其他的参数含义和 Authoriazation 函数一样。
//有时我们需要把签名后的 URL 直接拿来用header 参数可以直接构造一个空的 http.Header{} 传入即可。
func (A Auth) AuthorizationPrivateURL(method, bucket, key, expires string, header http.Header) (string, string) {
var sigData string
method = strings.ToUpper(method)
md5 := header.Get("Content-MD5")
contentType := header.Get("Content-Type")
sigData = method + "\n" + md5 + "\n" + contentType + "\n" + expires + "\n"
resource := "/" + bucket + "/" + key
sigData += resource
signature := A.signature(sigData)
return signature, A.publicKey
}
//AuthorizationPolicy 构造支持回调策略的签名policy 是经过 base64 编码后的 json string。
//本签名函数就是多了一个 policy 字段,其他的参数和 Authoriazation 一样。
func (A Auth) AuthorizationPolicy(method, bucket, key, policy string, header http.Header) string {
var sigData string
method = strings.ToUpper(method)
md5 := header.Get("Content-MD5")
contentType := header.Get("Content-Type")
date := header.Get("Date")
sigData = method + "\n" + md5 + "\n" + contentType + "\n" + date + "\n"
resource := "/" + bucket + "/" + key
sigData += resource
sigData += policy
signature := A.signature(sigData)
return "UCloud " + A.publicKey + ":" + signature + ":" + policy
}
func (A Auth) signature(data string) string {
mac := hmac.New(sha1.New, []byte(A.privateKey))
mac.Write([]byte(data))
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}
//AuthorizationBucketMgr 生成用于管理 bucket 的签名。
func (A Auth) AuthorizationBucketMgr(query url.Values) string {
query.Add("PublicKey", A.publicKey)
var signstring string
var keys []string
for k := range query {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
signstring += k + query.Get(k) //Get first value
}
signstring += A.privateKey
h := sha1.New()
io.WriteString(h, signstring)
query.Add("Signature", fmt.Sprintf("%x", h.Sum(nil)))
return query.Encode()
}
2019-10-30 13:48:41 -04:00
//CanonicalizedUcloudHeaders 用于将自定义请求报头规范化为string
//ucloudHeader 支持自定义请求头
func (A Auth) CanonicalizedUcloudHeaders(ucloudHeader http.Header) string {
keys := make([]string, 0)
headers := make(map[string]string, 0)
for k := range ucloudHeader {
newkey := strings.ToLower(k)
if strings.HasPrefix(newkey, "x-ufile-") || strings.HasPrefix(newkey, "x-ucloud-") {
headers[newkey] = strings.TrimSpace(ucloudHeader[k][0])
keys = append(keys, newkey)
}
}
sort.Strings(keys)
s := ""
for _, k := range keys {
v := headers[k]
s += k + ":" + v + "\n"
}
return s
}