Skip to content

Commit

Permalink
add env and config file as default config
Browse files Browse the repository at this point in the history
  • Loading branch information
bachue committed Jan 26, 2024
1 parent 0c1b84a commit d69e25b
Show file tree
Hide file tree
Showing 22 changed files with 513 additions and 31 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
GOPATH=$GITHUB_WORKSPACE go get golang.org/x/sync/singleflight
GOPATH=$GITHUB_WORKSPACE go get github.com/qiniu/dyn
GOPATH=$GITHUB_WORKSPACE go get github.com/gofrs/flock
GOPATH=$GITHUB_WORKSPACE go get github.com/BurntSushi/toml
# FIXME special package
# github.com/go-playground/validator/v10
Expand Down
21 changes: 17 additions & 4 deletions auth/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
api "github.com/qiniu/go-sdk/v7"
"github.com/qiniu/go-sdk/v7/conf"
internal_io "github.com/qiniu/go-sdk/v7/internal/io"
"github.com/qiniu/go-sdk/v7/storagev2/defaults"
)

const (
Expand All @@ -39,11 +40,17 @@ func New(accessKey, secretKey string) *Credentials {

// Sign 对数据进行签名,一般用于私有空间下载用途
func (ath *Credentials) Sign(data []byte) (token string) {
h := hmac.New(sha1.New, ath.SecretKey)
var accessKey, secretKey string
if ath == nil {
accessKey, secretKey, _ = defaults.Credentials()
} else {
accessKey, secretKey = ath.AccessKey, string(ath.SecretKey)
}
h := hmac.New(sha1.New, []byte(secretKey))
h.Write(data)

sign := base64.URLEncoding.EncodeToString(h.Sum(nil))
return fmt.Sprintf("%s:%s", ath.AccessKey, sign)
return fmt.Sprintf("%s:%s", accessKey, sign)
}

// SignToken 根据t的类型对请求进行签名,并把token加入req中
Expand Down Expand Up @@ -74,8 +81,14 @@ func (ath *Credentials) SignWithData(b []byte) (token string) {

// IsIAMKey 判断AccessKey是否为IAM的Key
func (ath *Credentials) IsIAMKey() bool {
return len(ath.AccessKey) == IAMKeyLen*4/3 &&
strings.HasPrefix(ath.AccessKey, IAMKeyPrefix)
var accessKey string
if ath == nil {
accessKey, _, _ = defaults.Credentials()
} else {
accessKey = ath.AccessKey
}
return len(accessKey) == IAMKeyLen*4/3 &&
strings.HasPrefix(accessKey, IAMKeyPrefix)
}

func collectData(req *http.Request) (data []byte, err error) {
Expand Down
6 changes: 6 additions & 0 deletions cdn/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

"github.com/qiniu/go-sdk/v7/auth"
"github.com/qiniu/go-sdk/v7/storagev2/defaults"
)

// Fusion CDN服务域名
Expand All @@ -24,6 +25,11 @@ type CdnManager struct {

// NewCdnManager 用来构建一个新的 CdnManager
func NewCdnManager(mac *auth.Credentials) *CdnManager {
if mac == nil {
if accessKey, secretKey, err := defaults.Credentials(); err == nil && accessKey != "" && secretKey != "" {
mac = auth.New(accessKey, secretKey)
}
}
return &CdnManager{mac: mac}
}

Expand Down
10 changes: 3 additions & 7 deletions conf/conf.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package conf

import (
"os"
"strings"
"github.com/qiniu/go-sdk/v7/internal/env"
)

const Version = "7.19.0"
Expand All @@ -12,12 +11,9 @@ const (
CONTENT_TYPE_FORM = "application/x-www-form-urlencoded"
CONTENT_TYPE_OCTET = "application/octet-stream"
CONTENT_TYPE_MULTIPART = "multipart/form-data"

disableQiniuTimestampSignatureEnvKey = "DISABLE_QINIU_TIMESTAMP_SIGNATURE"
)

func IsDisableQiniuTimestampSignature() bool {
value := os.Getenv(disableQiniuTimestampSignatureEnvKey)
value = strings.ToLower(value)
return value == "true" || value == "yes" || value == "y" || value == "1"
isDisabled, _ := env.DisableQiniuTimestampSignatureFromEnvironment()
return isDisabled
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/qiniu/go-sdk/v7
go 1.14

require (
github.com/BurntSushi/toml v1.3.2
github.com/dave/jennifer v1.6.1
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/dave/jennifer v1.6.1 h1:T4T/67t6RAA5AIV6+NP8Uk/BIsXgDoqEowgycdQQLuk=
github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
Expand Down
99 changes: 99 additions & 0 deletions internal/configfile/config_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package configfile

import (
"errors"
"os"
"path/filepath"
"strings"

"github.com/BurntSushi/toml"
"github.com/qiniu/go-sdk/v7/internal/env"
)

type profileConfig struct {
AccessKey string `toml:"access_key"`
SecretKey string `toml:"secret_key"`
BucketURL interface{} `toml:"bucket_url"`
DisableSecureProtocol bool `toml:"disable_secure_protocol"`
}

var profileConfigs map[string]*profileConfig

var ErrInvalidBucketUrl = errors.New("invalid bucket url")

func CredentialsFromConfigFile() (string, string, error) {
profile, err := getProfile()
if err != nil || profile == nil {
return "", "", err
} else if profile.AccessKey == "" || profile.SecretKey == "" {
return "", "", nil
}
return profile.AccessKey, profile.SecretKey, nil
}

func BucketURLsFromConfigFile() ([]string, error) {
profile, err := getProfile()
if err != nil || profile == nil {
return nil, err
} else if profile.BucketURL == "" {
return nil, nil
}
switch u := profile.BucketURL.(type) {
case string:
return strings.Split(u, ","), nil
case []interface{}:
var bucketUrls []string
for _, v := range u {
if s, ok := v.(string); ok {
bucketUrls = append(bucketUrls, s)
} else {
return nil, ErrInvalidBucketUrl
}
}
return bucketUrls, nil
}
return nil, ErrInvalidBucketUrl
}

func DisableSecureProtocolFromConfigFile() (bool, error) {
profile, err := getProfile()
if err != nil || profile == nil {
return false, err
}
return profile.DisableSecureProtocol, nil
}

func getProfile() (*profileConfig, error) {
if err := load(); err != nil {
return nil, err
}
profileName := env.ProfileFromEnvironment()
if profileName == "" {
profileName = "default"
}
profile, ok := profileConfigs[profileName]
if !ok || profile == nil {
return nil, nil
}
return profile, nil
}

func load() error {
if profileConfigs != nil {
return nil
}
configFilePath := env.ConfigFileFromEnvironment()
if configFilePath == "" {
configFilePath = getDefaultConfigFilePath()
}
_, err := toml.DecodeFile(configFilePath, &profileConfigs)
return err
}

func getDefaultConfigFilePath() string {
homeDir, err := os.UserHomeDir()
if err != nil {
homeDir = ""
}
return filepath.Join(homeDir, ".qiniu", "config.toml")
}
146 changes: 146 additions & 0 deletions internal/configfile/config_file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//go:build unit
// +build unit

package configfile

import (
"os"
"testing"
)

func TestLoad(t *testing.T) {
file, err := os.CreateTemp("", "config.toml")
if err != nil {
t.Fatal(err)
}
defer os.Remove(file.Name())
defer file.Close()

_, err = file.WriteString(`
[default]
access_key = "QINIU_ACCESS_KEY_1"
secret_key = "QINIU_SECRET_KEY_1"
[private-cloud]
access_key = "QINIU_ACCESS_KEY_2"
secret_key = "QINIU_SECRET_KEY_2"
bucket_url = "https://uc.qbox.me"
disable_secure_protocol = true
[private-cloud-2]
access_key = "QINIU_ACCESS_KEY_3"
secret_key = "QINIU_SECRET_KEY_3"
bucket_url = ["https://uc.qbox.me", "https://uc.qiniuapi.com"]
`)
if err != nil {
t.Fatal(err)
}

os.Setenv("QINIU_CONFIG_FILE", file.Name())
defer os.Unsetenv("QINIU_CONFIG_FILE")
if err = load(); err != nil {
t.Fatal(err)
}
defer func() {
profileConfigs = nil
}()
if len(profileConfigs) != 3 {
t.Fatal("Unexpected profile configs")
}
if profileConfigs["default"].AccessKey != "QINIU_ACCESS_KEY_1" {
t.Fatal("Unexpected access key")
}
if profileConfigs["default"].SecretKey != "QINIU_SECRET_KEY_1" {
t.Fatal("Unexpected secret key")
}
if profileConfigs["default"].BucketURL != nil {
t.Fatal("Unexpected bucket url")
}
if profileConfigs["default"].DisableSecureProtocol {
t.Fatal("Unexpected disable secure protocol")
}
if profileConfigs["private-cloud"].AccessKey != "QINIU_ACCESS_KEY_2" {
t.Fatal("Unexpected access key")
}
if profileConfigs["private-cloud"].SecretKey != "QINIU_SECRET_KEY_2" {
t.Fatal("Unexpected secret key")
}
if profileConfigs["private-cloud"].BucketURL.(string) != "https://uc.qbox.me" {
t.Fatal("Unexpected bucket url")
}
if !profileConfigs["private-cloud"].DisableSecureProtocol {
t.Fatal("Unexpected disable secure protocol")
}
if profileConfigs["private-cloud-2"].AccessKey != "QINIU_ACCESS_KEY_3" {
t.Fatal("Unexpected access key")
}
if profileConfigs["private-cloud-2"].SecretKey != "QINIU_SECRET_KEY_3" {
t.Fatal("Unexpected secret key")
}
if bucketUrls, ok := profileConfigs["private-cloud-2"].BucketURL.([]interface{}); !ok {
t.Fatal("Unexpected bucket url")
} else {
if bucketUrls[0].(string) != "https://uc.qbox.me" {
t.Fatal("Unexpected bucket url")
}
if bucketUrls[1].(string) != "https://uc.qiniuapi.com" {
t.Fatal("Unexpected bucket url")
}
}
if profileConfigs["private-cloud-2"].DisableSecureProtocol {
t.Fatal("Unexpected disable secure protocol")
}

os.Setenv("QINIU_PROFILE", "private-cloud")
defer os.Unsetenv("QINIU_PROFILE")

accessKey, secretKey, err := CredentialsFromConfigFile()
if err != nil {
t.Fatal(err)
}
if accessKey != "QINIU_ACCESS_KEY_2" {
t.Fatal("Unexpected access key")
}
if secretKey != "QINIU_SECRET_KEY_2" {
t.Fatal("Unexpected secret key")
}

bucketUrls, err := BucketURLsFromConfigFile()
if err != nil {
t.Fatal(err)
}
if len(bucketUrls) != 1 {
t.Fatal("Unexpected bucket urls")
}
if bucketUrls[0] != "https://uc.qbox.me" {
t.Fatal("Unexpected bucket url")
}

os.Setenv("QINIU_PROFILE", "private-cloud-2")
defer os.Unsetenv("QINIU_PROFILE")

accessKey, secretKey, err = CredentialsFromConfigFile()
if err != nil {
t.Fatal(err)
}
if accessKey != "QINIU_ACCESS_KEY_3" {
t.Fatal("Unexpected access key")
}
if secretKey != "QINIU_SECRET_KEY_3" {
t.Fatal("Unexpected secret key")
}

bucketUrls, err = BucketURLsFromConfigFile()
if err != nil {
t.Fatal(err)
}
if len(bucketUrls) != 2 {
t.Fatal("Unexpected bucket urls")
}
if bucketUrls[0] != "https://uc.qbox.me" {
t.Fatal("Unexpected bucket url")
}
if bucketUrls[1] != "https://uc.qiniuapi.com" {
t.Fatal("Unexpected bucket url")
}
}
Loading

0 comments on commit d69e25b

Please sign in to comment.