Sfoglia il codice sorgente

fork from gaore-common-sdk-go

tags/v1.0.0.1
余 欣怀 1 anno fa
commit
1bd1a66cfe
50 ha cambiato i file con 2928 aggiunte e 0 eliminazioni
  1. +9
    -0
      .gitignore
  2. +179
    -0
      README.md
  3. +1
    -0
      go.mod
  4. +21
    -0
      sdk/auth/credentials/access_key_credential.go
  5. +13
    -0
      sdk/auth/credentials/ali_appcode_credential.go
  6. +15
    -0
      sdk/auth/credentials/sts_token_credential.go
  7. +12
    -0
      sdk/auth/crediantial.go
  8. +160
    -0
      sdk/auth/rali_signature_composer.go
  9. +128
    -0
      sdk/auth/roa_signature_composer.go
  10. +126
    -0
      sdk/auth/rpc_signature_composer.go
  11. +56
    -0
      sdk/auth/signer.go
  12. +44
    -0
      sdk/auth/signers/access_key_siginer.go
  13. +43
    -0
      sdk/auth/signers/ali_appcode_signer.go
  14. +41
    -0
      sdk/auth/signers/sts_token_signer.go
  15. +357
    -0
      sdk/client.go
  16. +24
    -0
      sdk/config.go
  17. +36
    -0
      sdk/requests/common_request.go
  18. +314
    -0
      sdk/requests/request.go
  19. +63
    -0
      sdk/requests/rpc_request.go
  20. +10
    -0
      sdk/requests/types.go
  21. +117
    -0
      sdk/responses/response.go
  22. +36
    -0
      sdk/utils/debug.go
  23. +111
    -0
      sdk/utils/utils.go
  24. +25
    -0
      sdk/utils/utils_test.go
  25. +37
    -0
      services/apk/add_apk.go
  26. +36
    -0
      services/apk/add_top.go
  27. +66
    -0
      services/apk/client.go
  28. +21
    -0
      services/apk/client_test.go
  29. +36
    -0
      services/apk/refresh_apk.go
  30. +74
    -0
      services/apk/search_apk.go
  31. +48
    -0
      services/callback/client.go
  32. +49
    -0
      services/callback/send_action.go
  33. +29
    -0
      services/jedi/README.md
  34. +48
    -0
      services/jedi/client.go
  35. +40
    -0
      services/jedi/send_sms.go
  36. +50
    -0
      services/mail/client.go
  37. +22
    -0
      services/mail/client_test.go
  38. +36
    -0
      services/mail/end_email.go
  39. +31
    -0
      services/mkt/client.go
  40. +36
    -0
      services/mkt/pkg_notice.go
  41. +48
    -0
      services/sso/client.go
  42. +39
    -0
      services/sso/code_auth.go
  43. +35
    -0
      services/sso/get_user.go
  44. +37
    -0
      services/sso/refresh_token.go
  45. +34
    -0
      services/sso/search_user.go
  46. +27
    -0
      services/sso/struct.go
  47. +44
    -0
      services/www/client.go
  48. +25
    -0
      services/www/client_test.go
  49. +38
    -0
      services/www/get_pwd.go
  50. +1
    -0
      services/www/get_token.go

+ 9
- 0
.gitignore Vedi File

@@ -0,0 +1,9 @@
# Created by .ignore support plugin (hsz.mobi)
### Example user template template
### Example user template

# IntelliJ project files
.idea
*.iml
out
gen

+ 179
- 0
README.md Vedi File

@@ -0,0 +1,179 @@
# gaore-common-sdk-go

### 1.目录架构
```
├── README.md
├── sdk
│   ├── auth `认证类`
│   ├── client.go `客户端主入口类`
│   ├── config.go
│   ├── requests `请求类`
│   ├── responses `响应类`
│   └── utils `工具类`
└── services
└── jedi
```
### 2.引入
```go
go get -u golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk
```
或 Go Module
```go
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
```

### 3.服务端认证及返回处理

调用 `auth.UnSign` 方法,提供`*http.Request`请求实例,以及`signer.Signer` 签名器(签名器需要包括凭据)
即可完成整个验签过程

这里以`beego`为例 :
```go
package applications

import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/signers"
"golib.gaore.com/GaoreGo/grlogs"
)

func init() {
// 过滤器
beego.InsertFilter("/api/*", beego.BeforeRouter, func(context *context.Context) {
httpRequest := context.Request
err := auth.UnSign(httpRequest, signers.NewAccessKeySigner(&credentials.AccessKeyCredential{
AccessKeyId: "aaaaaa",
AccessKeySecret: "bbbbbb",
AccessKeyFrom: context.Input.Param("access_from"),
}))

if err != nil {
resp := response.NewJsonByDefaultFailed()
resp.Msg = err.Error()
resp.Code = 10086

var (
hasIndent = beego.BConfig.RunMode != beego.PROD
)
context.Output.Status = 500
context.Output.JSON(resp, hasIndent, false)
}
})
}
```
服务端返回的响应体为以下结构的json字符流, `code`,`status`,`msg` 这三个字段*最好*要包含且数据类型要一致 , `data` 部分为业务内容,自行定义
```json
{
"code": 1001,
"msg": "不能为空",
"status": false,
"data": {
...
}
}
```

### 4.sdk编写

在`services`目录下以服务归类新建文件夹, 如`jedi`为短信服务,以 `RpcRequest` 和 `BaseResponse` 以基类写好请求子类和响应子类。一个请求接口对应一对请求和响应类。

```go
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"

const (
HOST = "jedi" // 如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
VERSION = "2020-08-04"
)


type Client struct {
sdk.Client
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAccessKey(accesskey, secrect, source)
return
}

func (c *Client) Test(req *DemoTestRequest) (response *DemoTestResponse, err error) {
response = CreateDemoTestResponse()
err = c.DoAction(req, response)
return
}
```

请求类,对参数用标签解释, 如 `position:"Query" field:"param_1" default:""` , 有三个字段 `position` , `field`, `default`

- `position` 为标志该参数为请求体对应的位置, `Query` query参数, `Body` post请求体参数, `Head`请求头参数

- `field` 解释成参数实际名称

- `default` 默认值

```go
type DemoTestRequest struct {
*requests.RpcRequest
Param1 string `position:"Query" field:"param_1" default:"" `
Param2 int `position:"Query" field:"param_2" default:"10086" `
Param3 bool `position:"Query" field:"param_3" default:"false" `
}
```
对应解释成http请求为:
```go
GET param_1=111&param_2=10086&param_3=false
```

完整示例:
```go
package jedi

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

// 定义请求体
type DemoTestRequest struct {
*requests.RpcRequest
Param1 string `position:"Query" field:"param_1" default:"" `
Param2 int `position:"Query" field:"param_2" default:"10086" `
Param3 bool `position:"Query" field:"param_3" default:"false" `
}

func CreateDemoTestRequest() (req *DemoTestRequest) {
req = &DemoTestRequest{RpcRequest: &requests.RpcRequest{}}
// InitWithApiInfo 初始化请求,有三个参数,域名,版本,和路径
// 域名参数如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
req.InitWithApiInfo(HOST, VERSION, "/api/sms/Index")
// 定义 请求方法 POST 或 GET
req.Method = requests.GET
return
}

// 定义响应体
type DemoTestResponse struct {
*responses.BaseResponse
Data DemoTestResponseData `json:"data"`
}

type DemoTestResponseData struct {
Account string `json:"account"`
Total int `json:"total"`
}

func CreateDemoTestResponse() *DemoTestResponse {
return &DemoTestResponse{
BaseResponse: &responses.BaseResponse{},
}
}

```

终端调试打开方式, 需要在系统环境变量上加入(三选一):
```
DEBUG=sdk,signer,request
```

+ 1
- 0
go.mod Vedi File

@@ -0,0 +1 @@
module golib.gaore.com/GaoreGo/haiwai-common-sdk-go

+ 21
- 0
sdk/auth/credentials/access_key_credential.go Vedi File

@@ -0,0 +1,21 @@
package credentials

type BaseCredential struct {
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
}

type AccessKeyCredential struct {
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
}

func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential {
return &AccessKeyCredential{
AccessKeyId: baseCred.AccessKeyId,
AccessKeySecret: baseCred.AccessKeySecret,
AccessKeyFrom: baseCred.AccessKeyFrom,
}
}

+ 13
- 0
sdk/auth/credentials/ali_appcode_credential.go Vedi File

@@ -0,0 +1,13 @@
package credentials

type AliAppcodeCredential struct {
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
}

func NewAliAppcodeCredential(accessKeyId, accessKeySecret string) *AliAppcodeCredential {
return &AliAppcodeCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
}
}

+ 15
- 0
sdk/auth/credentials/sts_token_credential.go Vedi File

@@ -0,0 +1,15 @@
package credentials

type StdTokenCredential struct {
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
}

func NewStsTokenCredential(accessKeyId, accessKeySecret, accessFrom string) *StdTokenCredential {
return &StdTokenCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
AccessKeyFrom: accessFrom,
}
}

+ 12
- 0
sdk/auth/crediantial.go Vedi File

@@ -0,0 +1,12 @@
package auth

import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"

var debug utils.Debug

func init() {
debug = utils.Init("signer")
}

type Credential interface {
}

+ 160
- 0
sdk/auth/rali_signature_composer.go Vedi File

@@ -0,0 +1,160 @@
package auth

import (
"bytes"
"errors"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
)

func signRaliRequest(request requests.AcsRequest, signer Signer) (err error) {
err = completeRaliSignParams(request, signer)
if err != nil {
return
}

stringToSign := buildRaliStringToSign(request)
request.SetStringToSign(stringToSign)
signature := signer.Sign(stringToSign, "")
request.GetHeaders()["X-Ca-Signature"] = signature

debug("GrSdk sign: %s", signature)
debug("GrSdk sign string: %s", strings.ReplaceAll(stringToSign, "\n", "#"))
debug("GrSdk sign: \r\n")
return
}

func completeRaliSignParams(request requests.AcsRequest, signer Signer) (err error) {

request.GetHeaders()["X-Ca-Timestamp"] = fmt.Sprintf("%d", time.Now().Unix()*1000)
request.GetHeaders()["X-Ca-Signature-Method"] = signer.GetName()
request.GetHeaders()["X-Ca-Nonce"] = utils.GetUUID()
request.GetHeaders()["X-Ca-Key"], err = signer.GetAccessKeyId()

if request.GetEnv() != "" {
request.GetHeaders()["X-Ca-Stage"] = request.GetEnv()
}

if request.GetMethod() == requests.POST {
request.GetHeaders()["Content-type"] = requests.Form
}

formString := utils.GetUrlFormedMap(request.GetFormParams())
request.SetContent(bytes.NewBufferString(formString).Bytes())
return
}

func buildRaliSignHeader(request requests.AcsRequest) (str1, str2 string) {

headParams := make(map[string]string)
signatureHeaders := make([]string, 0)

for key, val := range request.GetHeaders() {
headParams[key] = val
}

delete(headParams, "X-Ca-Signature")
delete(headParams, "X-Ca-Signature-Headers")
delete(headParams, "Accept")
delete(headParams, "Content-MD5")
delete(headParams, "Content-Type")
delete(headParams, "Date")

for key, _ := range headParams {
signatureHeaders = append(signatureHeaders, key)
}

sort.Strings(signatureHeaders)

for _, key := range signatureHeaders {
str1 += fmt.Sprintf("%s:%s\n", key, headParams[key])
}

return strings.TrimRight(str1, "\n"), strings.Join(signatureHeaders, ",")
}

func buildRaliStringToSign(request requests.AcsRequest) (stringToSign string) {
signParams := make(map[string]string)
for key, value := range request.GetQueryParams() {
signParams[key] = value
}

if strings.ToUpper(request.GetMethod()) == requests.POST {
for key, value := range request.GetFormParams() {
signParams[key] = value
}
}

str1, str2 := buildRaliSignHeader(request)

stringToSign = request.GetMethod() + "\n"
stringToSign += request.GetHeaders()["Accept"] + "\n\n"
stringToSign += request.GetHeaders()["Content-type"] + "\n\n"
stringToSign += str1 + "\n"
stringToSign += request.GetActionName() + "?" + utils.GetUrlByKeySort(signParams)
request.GetHeaders()["X-Ca-Signature-Headers"] = str2

//stringToSign = utils.GetUrlFormedMap(signParams)
//stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
//stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
//stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
//stringToSign = url.QueryEscape(stringToSign)
//stringToSign = request.GetMethod() + "&%2F&" + stringToSign
return
}

func unsignRaliRequest(request *http.Request, signer Signer) (err error) {
signParams := make(map[string]string)
for key, value := range request.URL.Query() {
signParams[key] = value[0]
}

if strings.ToUpper(request.Method) == requests.POST {
for key, value := range request.Form {
signParams[key] = value[0]
}
}

if accessKey, err := signer.GetAccessKeyId(); err != nil {
return err
} else if accessKey == "" {
return errors.New("access key is not allow empty")
} else if accessKey != signParams["access_key"] {
return errors.New("illegal access key")
}

signValue, ok := signParams["sign"]
if !ok {
return errors.New("sign value is not exists")
} else {
delete(signParams, "sign")
}

stringToSign := utils.GetUrlFormedMap(signParams)
stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
stringToSign = url.QueryEscape(stringToSign)
stringToSign = request.Method + "&%2F&" + stringToSign
debug("GrSdk sign: %s", stringToSign)

if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
return err
} else {
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
err = errors.New("sign timeout 5 minute")
}
}

if signer.Sign(stringToSign, "&") != signValue {
return errors.New("sign string is not correct")
}
return
}

+ 128
- 0
sdk/auth/roa_signature_composer.go Vedi File

@@ -0,0 +1,128 @@
package auth

import (
"bytes"
"errors"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)

func signRoaRequest(request requests.AcsRequest, signer Signer) (err error) {
err = completeRoaSignParams(request, signer)
if err != nil {
return
}
if _, isContainsSign := request.GetQueryParams()["sign"]; isContainsSign {
delete(request.GetQueryParams(), "sign")
}

stringToSign := buildRoaStringToSign(request)
request.SetStringToSign(stringToSign)
signature := signer.Sign(stringToSign, "&")
request.GetQueryParams()["sign"] = signature
debug("GrSdk sign: %s", signature)
debug("GrSdk sign string: %s", stringToSign)
debug("GrSdk sign: \r\n")
return
}

func completeRoaSignParams(request requests.AcsRequest, signer Signer) (err error) {

var accessKeyFrom string
if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil {
return
}

queryParams := request.GetQueryParams()
queryParams["access_time"] = fmt.Sprintf("%d", time.Now().Unix())
queryParams["access_key"], err = signer.GetAccessKeyId()
queryParams["access_from"] = accessKeyFrom

if err != nil {
return
}

if request.GetMethod() == requests.POST {
request.GetHeaders()["Content-type"] = requests.Form
}
request.GetHeaders()["Gr-Sdk-From"] = accessKeyFrom
formString := utils.GetUrlFormedMap(request.GetFormParams())
request.SetContent(bytes.NewBufferString(formString).Bytes())
return
}

func buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) {
signParams := make(map[string]string)
for key, value := range request.GetQueryParams() {
signParams[key] = value
}

if strings.ToUpper(request.GetMethod()) == requests.POST {
for key, value := range request.GetFormParams() {
signParams[key] = value
}
}

stringToSign = utils.GetUrlFormedMap(signParams)
stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
stringToSign = url.QueryEscape(stringToSign)
stringToSign = request.GetMethod() + "&%2F&" + stringToSign
return
}

func unsignRoaRequest(request *http.Request, signer Signer) (err error) {
signParams := make(map[string]string)
for key, value := range request.URL.Query() {
signParams[key] = value[0]
}

if strings.ToUpper(request.Method) == requests.POST {
for key, value := range request.Form {
signParams[key] = value[0]
}
}

if accessKey, err := signer.GetAccessKeyId(); err != nil {
return err
} else if accessKey == "" {
return errors.New("access key is not allow empty")
} else if accessKey != signParams["access_key"] {
return errors.New("illegal access key")
}

signValue, ok := signParams["sign"]
if !ok {
return errors.New("sign value is not exists")
} else {
delete(signParams, "sign")
}

stringToSign := utils.GetUrlFormedMap(signParams)
stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
stringToSign = url.QueryEscape(stringToSign)
stringToSign = request.Method + "&%2F&" + stringToSign
debug("GrSdk sign: %s", stringToSign)

if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
return err
} else {
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
err = errors.New("sign timeout 5 minute")
}
}

if signer.Sign(stringToSign, "&") != signValue {
return errors.New("sign string is not correct")
}
return
}

+ 126
- 0
sdk/auth/rpc_signature_composer.go Vedi File

@@ -0,0 +1,126 @@
package auth

import (
"bytes"
"errors"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)

func signRpcRequest(request requests.AcsRequest, signer Signer) (err error) {
err = completeRpcSignParams(request, signer)
if err != nil {
return
}
if _, isContainsSign := request.GetQueryParams()["sign"]; isContainsSign {
delete(request.GetQueryParams(), "sign")
}

stringToSign := buildRpcStringToSign(request)
request.SetStringToSign(stringToSign)
signature := signer.Sign(stringToSign, "&")
request.GetQueryParams()["sign"] = signature
debug("GrSdk sign: %s", signature)
debug("GrSdk sign string: %s", stringToSign)
debug("GrSdk sign: \r\n")
return
}

func completeRpcSignParams(request requests.AcsRequest, signer Signer) (err error) {

var accessKeyFrom string
if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil {
return
}

queryParams := request.GetQueryParams()
queryParams["access_time"] = fmt.Sprintf("%d", time.Now().Unix())
queryParams["access_key"], err = signer.GetAccessKeyId()
queryParams["access_from"] = accessKeyFrom

if err != nil {
return
}

request.GetHeaders()["Content-type"] = requests.Form
request.GetHeaders()["Gr-Sdk-From"] = accessKeyFrom
formString := utils.GetUrlFormedMap(request.GetFormParams())
request.SetContent(bytes.NewBufferString(formString).Bytes())
return
}

func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) {
signParams := make(map[string]string)
for key, value := range request.GetQueryParams() {
signParams[key] = value
}

if strings.ToUpper(request.GetMethod()) == requests.POST {
for key, value := range request.GetFormParams() {
signParams[key] = value
}
}

stringToSign = utils.GetUrlFormedMap(signParams)
stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
stringToSign = url.QueryEscape(stringToSign)
stringToSign = request.GetMethod() + "&%2F&" + stringToSign
return
}

func unsignRpcRequest(request *http.Request, signer Signer) (err error) {
signParams := make(map[string]string)
for key, value := range request.URL.Query() {
signParams[key] = value[0]
}

if strings.ToUpper(request.Method) == requests.POST {
for key, value := range request.Form {
signParams[key] = value[0]
}
}

if accessKey, err := signer.GetAccessKeyId(); err != nil {
return err
} else if accessKey == "" {
return errors.New("access key is not allow empty")
} else if accessKey != signParams["access_key"] {
return errors.New("illegal access key")
}

signValue, ok := signParams["sign"]
if !ok {
return errors.New("sign value is not exists")
} else {
delete(signParams, "sign")
}

stringToSign := utils.GetUrlFormedMap(signParams)
stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
stringToSign = url.QueryEscape(stringToSign)
stringToSign = request.Method + "&%2F&" + stringToSign
debug("GrSdk sign: %s", stringToSign)

if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
return err
} else {
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
err = errors.New("sign timeout 5 minute")
}
}

if signer.Sign(stringToSign, "&") != signValue {
return errors.New("sign string is not correct")
}
return
}

+ 56
- 0
sdk/auth/signer.go Vedi File

@@ -0,0 +1,56 @@
package auth

import (
"errors"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/signers"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
"net/http"
)

type Signer interface {
GetName() string
GetAccessKeyId() (string, error)
GetAccessKeyFrom() (string, error)
Sign(stringToSign, secretSuffix string) string
}

func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) {
switch instance := credential.(type) {
case *credentials.AccessKeyCredential:
signer = signers.NewAccessKeySigner(instance)
case *credentials.BaseCredential:
signer = signers.NewAccessKeySigner(instance.ToAccessKeyCredential())
case *credentials.StdTokenCredential:
signer = signers.NewStsTokenSigner(instance)
case *credentials.AliAppcodeCredential:
signer = signers.NewAliAppcodeSigner(instance)
default:
err = errors.New("UnsupportedCredentialErrorCode = SDK.UnsupportedCredential")
}
return
}

func Sign(request requests.AcsRequest, signer Signer) (err error) {
switch signer.(type) {
case *signers.AliAppcodeSigner:
err = signRaliRequest(request, signer)
return
}

//TODO 根据rpc和roa两种风格签名,自行选择
switch request.GetStyle() {
case requests.RPC:
err = signRpcRequest(request, signer)
case requests.ROA:
err = signRoaRequest(request, signer)
}
return
}

func UnSign(request *http.Request, signer Signer) (err error) {
//TODO 根据rpc和roa两种风格签名,自行选择
err = unsignRpcRequest(request, signer)
return
}

+ 44
- 0
sdk/auth/signers/access_key_siginer.go Vedi File

@@ -0,0 +1,44 @@
package signers

import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
)

type AccessKeySigner struct {
credential *credentials.AccessKeyCredential
}

func (signer *AccessKeySigner) GetAccessKeyId() (string, error) {
return signer.credential.AccessKeyId, nil
}

func (signer *AccessKeySigner) GetAccessKeyFrom() (string, error) {
return signer.credential.AccessKeyFrom, nil
}

func (*AccessKeySigner) GetName() string {
return "HMAC-SHA1"
}

func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.credential.AccessKeySecret + secretSuffix
return ShaHmac1(stringToSign, secret)
}

func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner {
return &AccessKeySigner{
credential: credential,
}
}

func ShaHmac1(source, secret string) string {
key := []byte(secret)
hmac := hmac.New(sha1.New, key)
hmac.Write([]byte(source))
signedBytes := hmac.Sum(nil)
signedString := base64.StdEncoding.EncodeToString(signedBytes)
return signedString
}

+ 43
- 0
sdk/auth/signers/ali_appcode_signer.go Vedi File

@@ -0,0 +1,43 @@
package signers

import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
)

type AliAppcodeSigner struct {
credential *credentials.AliAppcodeCredential
}

func (signer *AliAppcodeSigner) GetName() string {
return "HmacSHA256"
}

func (signer *AliAppcodeSigner) GetAccessKeyId() (string, error) {
return signer.credential.AccessKeyId, nil
}

func (signer *AliAppcodeSigner) GetAccessKeyFrom() (string, error) {
return "", nil
}

func (signer *AliAppcodeSigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.credential.AccessKeySecret + secretSuffix
return ShaHmac256(stringToSign, secret)
}

func NewAliAppcodeSigner(credential *credentials.AliAppcodeCredential) *AliAppcodeSigner {
return &AliAppcodeSigner{
credential: credential,
}
}

func ShaHmac256(source, secret string) string {
key := []byte(secret)
hmac1 := hmac.New(sha256.New, key)
hmac1.Write([]byte(source))
signedString := base64.StdEncoding.EncodeToString(hmac1.Sum(nil))
return signedString
}

+ 41
- 0
sdk/auth/signers/sts_token_signer.go Vedi File

@@ -0,0 +1,41 @@
package signers

import (
"crypto/md5"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
)

type StsTokenSigner struct {
credential *credentials.StdTokenCredential
}

func (signer *StsTokenSigner) GetAccessKeyId() (string, error) {
return signer.credential.AccessKeyId, nil
}

func (signer *StsTokenSigner) GetAccessKeyFrom() (string, error) {
return signer.credential.AccessKeyFrom, nil
}

func (*StsTokenSigner) GetName() string {
return "MD5"
}

func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string {
secret := signer.credential.AccessKeySecret + secretSuffix
return Md5(stringToSign, secret)
}

func NewStsTokenSigner(credential *credentials.StdTokenCredential) *StsTokenSigner {
return &StsTokenSigner{
credential: credential,
}
}

func Md5(source, secret string) string {
data := []byte(fmt.Sprintf("%s##%s", secret, source))
has := md5.Sum(data)
md5str := fmt.Sprintf("%x", has)
return md5str
}

+ 357
- 0
sdk/client.go Vedi File

@@ -0,0 +1,357 @@
package sdk

import (
"bytes"
"context"
"crypto/tls"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"regexp"
"runtime"
"strings"
"time"
)

var Version = "0.0.1"
var defaultConnectTimeout = 5 * time.Second
var defaultReadTimeout = 10 * time.Second
var defaultDomain = ".gaore.com"
var DefaultUserAgent = fmt.Sprintf("GaoreGoSdk (%s;%s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)

var debug utils.Debug

func init() {
debug = utils.Init("sdk")
}

type Client struct {
Host string
httpClient *http.Client
isInsecure bool
signer auth.Signer
readTimeout time.Duration
connectTimeout time.Duration
config *Config
httpProxy string
httpsProxy string
noProxy string
}

func (client *Client) GetNoProxy() string {
return client.noProxy
}

func (client *Client) SetNoProxy(noProxy string) {
client.noProxy = noProxy
}

func (client *Client) GetHttpsProxy() string {
return client.httpsProxy
}

func (client *Client) SetHttpsProxy(httpsProxy string) {
client.httpsProxy = httpsProxy
}

func (client *Client) SetHttpProxy(httpProxy string) {
client.httpProxy = httpProxy
}

func (client *Client) GetHttpProxy() string {
return client.httpProxy
}

func (client *Client) GetHTTPSInsecure() bool {
return client.isInsecure
}

func (client *Client) InitClientConfig() (config *Config) {
if client.config != nil {
return client.config
} else {
return NewConfig()
}

}

func (client *Client) InitWithAccessKey(accessKeyId, accessKeySecret, accessKeyFrom string) (err error) {
config := client.InitWithConfig()
credential := &credentials.BaseCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
AccessKeyFrom: accessKeyFrom,
}
return client.InitWithOptions(config, credential)
}

func (client *Client) InitWithAliAppcode(accessKeyId, accessKeySecret string, env ...string) (err error) {
config := client.InitWithConfig()
credential := credentials.NewAliAppcodeCredential(accessKeyId, accessKeySecret)

if len(env) > 0 {
config.Env = env[0]
}

return client.InitWithOptions(config, credential)
}

func (client *Client) InitWithStsToken(accessKeyId, accessKeySecret, accessKeyFrom string) (err error) {
config := client.InitWithConfig()
credential := &credentials.StdTokenCredential{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
AccessKeyFrom: accessKeyFrom,
}
return client.InitWithOptions(config, credential)
}

func (client *Client) InitWithOptions(config *Config, credential auth.Credential) (err error) {
client.httpClient = &http.Client{}
client.config = config

if config.Transport != nil {
client.httpClient.Transport = config.Transport
} else if config.HttpTransport != nil {
client.httpClient.Transport = config.HttpTransport
}

if config.Timeout > 0 {
client.httpClient.Timeout = config.Timeout
}

client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner)
return
}

func (client *Client) InitWithConfig() (config *Config) {
if client.config != nil {
return client.config
} else {
return NewConfig()
}
}

func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonRequest, signerInterface interface{}) (response *responses.CommonResponse, err error) {
if signer, isSigner := signerInterface.(auth.Signer); isSigner {
response = responses.NewCommonResponse()
err = client.DoActionWithSigner(request, response, signer)
return
}
panic("should not be here")
}

func Timeout(connectTimeout time.Duration) func(ctx context.Context, net, addr string) (c net.Conn, err error) {
return func(ctx context.Context, network, address string) (c net.Conn, err error) {
return (&net.Dialer{
Timeout: connectTimeout,
DualStack: true,
}).DialContext(ctx, network, address)
}
}

func (client *Client) setTimeOut(request requests.AcsRequest) {
readTimeout, connectTimeout := client.getTimeOut(request)
client.httpClient.Timeout = readTimeout
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
trans.DialContext = Timeout(connectTimeout)
client.httpClient.Transport = trans
} else if client.httpClient.Transport == nil {
client.httpClient.Transport = &http.Transport{
DialContext: Timeout(connectTimeout),
}
}
}

func (client *Client) getTimeOut(request requests.AcsRequest) (time.Duration, time.Duration) {
readTimeOut := defaultReadTimeout
connectTimeOut := defaultConnectTimeout

reqReadTimeout := request.GetReadTimeout()
reqConnectTimeout := request.GetConnectTimeout()
if reqReadTimeout != 0*time.Millisecond {
readTimeOut = reqReadTimeout
} else if client.readTimeout != 0*time.Microsecond {
readTimeOut = client.readTimeout
} else if client.httpClient.Timeout != 0 {
readTimeOut = client.httpClient.Timeout
}

if reqConnectTimeout != 0*time.Microsecond {
connectTimeOut = reqConnectTimeout
} else if client.connectTimeout != 0*time.Millisecond {
connectTimeOut = client.connectTimeout
}
return readTimeOut, connectTimeOut
}

func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) {
if request.GetHTTPSInsecure() != nil {
insecure = *request.GetHTTPSInsecure()
} else {
insecure = client.GetHTTPSInsecure()
}
return
}

func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) {
return client.DoActionWithSigner(request, response, nil)
}

func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {

httpRequest, err := client.buildRequestWithSigner(request, signer)
if err != nil {
return err
}

client.setTimeOut(request)
proxy, err := client.getHttpProxy(httpRequest.URL.Scheme)
if err != nil {
return err
}
noProxy := client.getNoProxy(httpRequest.URL.Scheme)
var flag bool
for _, value := range noProxy {
if strings.HasPrefix(value, "*") {
value = fmt.Sprint(".%s", value)
}
noProxyReg, err := regexp.Compile(value)
if err != nil {
return err
}
if noProxyReg.MatchString(httpRequest.Host) {
flag = true
break
}
}

if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
if trans.TLSClientConfig != nil {
trans.TLSClientConfig.InsecureSkipVerify = client.getHTTPSInsecure(request)
} else {
trans.TLSClientConfig = &tls.Config{
InsecureSkipVerify: client.getHTTPSInsecure(request),
}
}

if proxy != nil && !flag {
trans.Proxy = http.ProxyURL(proxy)
}

client.httpClient.Transport = trans
}

dump, err := httputil.DumpRequest(httpRequest, true)
debug("client %s", bytes.NewBuffer(dump).String())

var httpResponse *http.Response
httpResponse, err = hookDo(client.httpClient.Do)(httpRequest)
if err != nil {
return
}

err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
return
}

func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (httpRequest *http.Request, err error) {
// init param
domain := request.GetDomain()
if strings.Index(domain.Default, ".") < 0 {
domain.Default += defaultDomain
request.SetDomain(domain)
}

if request.GetScheme() == "" {
request.SetScheme(client.config.Scheme)
}

if request.GetEnv() == "" && client.config.Env != "" {
request.SetEnv(client.config.Env)
}

err = requests.InitParam(request)
if err != nil {
return
}
// build signature
var finalSigner auth.Signer
if signer != nil {
finalSigner = signer
} else {
finalSigner = client.signer
}
err = auth.Sign(request, finalSigner)
if err != nil {
return
}

// build request
requestMethod := request.GetMethod()
requestUrl := request.BuildUrl()
body := request.GetBodyReader()
httpRequest, err = http.NewRequest(requestMethod, requestUrl, body)
if err != nil {
return
}

for key, val := range request.GetHeaders() {
httpRequest.Header[key] = []string{val}
}

if host, isContainsHost := request.GetHeaders()["host"]; isContainsHost {
httpRequest.Host = host
}

userAgent := DefaultUserAgent
httpRequest.Header.Set("User-Agent", userAgent)

return
}

func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) {
switch scheme {
case "https":
if client.GetHttpsProxy() != "" {
proxy, err = url.Parse(client.httpsProxy)
} else if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" {
proxy, err = url.Parse(rawurl)
} else if rawurl := os.Getenv("https_proxy"); rawurl != "" {
proxy, err = url.Parse(rawurl)
}
default:
if client.GetHttpProxy() != "" {
proxy, err = url.Parse(client.httpProxy)
} else if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" {
proxy, err = url.Parse(rawurl)
} else if rawurl := os.Getenv("http_proxy"); rawurl != "" {
proxy, err = url.Parse(rawurl)
}
}
return
}

func (client *Client) getNoProxy(scheme string) []string {
var urls []string
if client.GetNoProxy() != "" {
urls = strings.Split(client.noProxy, ",")
} else if rawurl := os.Getenv("NO_PROXY"); rawurl != "" {
urls = strings.Split(rawurl, ",")
} else if rawurl := os.Getenv("no_proxy"); rawurl != "" {
urls = strings.Split(rawurl, ",")
}
return urls
}

func hookDo(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
return fn
}

+ 24
- 0
sdk/config.go Vedi File

@@ -0,0 +1,24 @@
package sdk

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"net/http"
"time"
)

type Config struct {
Debug bool `default:"false"`
HttpTransport *http.Transport `default:""`
Transport http.RoundTripper `default:""`
GoRoutinePoolSize int `default:"0"`
UserAgent string `default:""`
Scheme string `default:"HTTP"`
Timeout time.Duration `default:"5"`
Env string `default:""`
}

func NewConfig() *Config {
config := &Config{}
utils.InitStructWithDefaultTag(config)
return config
}

+ 36
- 0
sdk/requests/common_request.go Vedi File

@@ -0,0 +1,36 @@
package requests

import "io"

type CommonRequest struct {
*baseRequest
Product string
Ontology AcsRequest
}

func (request *CommonRequest) TransToAscRequest() {
rpcRequest := &RpcRequest{}
rpcRequest.baseRequest = request.baseRequest
rpcRequest.product = request.Product
request.Ontology = rpcRequest
}

func (request *CommonRequest) BuildUrl() string {
return request.Ontology.BuildUrl()
}

func (request *CommonRequest) BuildQueries() string {
return request.Ontology.BuildQueries()
}

func (request *CommonRequest) GetBodyReader() io.Reader {
return request.Ontology.GetBodyReader()
}

func (request *CommonRequest) GetStyle() string {
return request.Ontology.GetStyle()
}

func (request *CommonRequest) InitWithApiInfo(domain Host, version, urlPath string) {
request.Ontology.InitWithApiInfo(domain, version, urlPath)
}

+ 314
- 0
sdk/requests/request.go Vedi File

@@ -0,0 +1,314 @@
package requests

import (
"errors"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"io"
"math/cmplx"
"reflect"
"strconv"
"time"
)

const (
RPC = "RPC"
ROA = "ROA"

HTTP = "HTTP"
HTTPS = "HTTPS"

JSON = "JSON"
XML = "XML"

DefaultHttpPort = "80"

GET = "GET"
PUT = "PUT"
POST = "POST"
DELETE = "DELETE"
PATCH = "PATCH"
HEAD = "HEAD"
OPTIONS = "OPTIONS"

Json = "application/json"
Xml = "application/xml"
Raw = "application/octet-stream"
Form = "application/x-www-form-urlencoded"

Header = "Header"
Query = "Query"
Body = "Body"
Path = "Path"

TEST = "TEST"
PRE = "PRE"
RELEASE = "RELEASE"

HeaderSeparator = "\n"
)

type Host struct {
Default string
Func func(string) string
}

var debug utils.Debug

func init() {
debug = utils.Init("request")
}

type AcsRequest interface {
GetReadTimeout() time.Duration
GetConnectTimeout() time.Duration
SetReadTimeout(readTimeOut time.Duration)
SetConnectTimeout(connectTimeOut time.Duration)
SetHTTPSInsecure(isInsecure bool)
GetHTTPSInsecure() *bool
GetQueryParams() map[string]string
GetFormParams() map[string]string
GetMethod() string
GetScheme() string
GetDomain() Host
SetDomain(host Host)
GetActionName() string
GetAcceptFormat() string
GetAccept() string
GetHeaders() map[string]string
GetStyle() string
InitWithApiInfo(domain Host, version, urlPath string)
GetEnv() string
SetEnv(string)

BuildUrl() string
BuildQueries() string

SetScheme(scheme string)
SetContent(content []byte)

SetStringToSign(stringToSign string)
GetStringToSign() string
GetBodyReader() io.Reader

AddHeaderParam(key, value string)
addQueryParam(key, value string)
addFormParam(key, value string)
}

type baseRequest struct {
Scheme string
Method string
Port string
Domain Host
From string
ReadTimeout time.Duration
ConnectTimeout time.Duration
isInsecure *bool
Env string

AcceptFormat string
actionName string

userAgent map[string]string
product string
version string

QueryParams map[string]string
Headers map[string]string
FormParams map[string]string
Content []byte

queries string
stringToSign string
}

func (request *baseRequest) GetEnv() string {
return request.Env
}

func (request *baseRequest) SetEnv(e string) {
request.Env = e
}

func (request *baseRequest) GetStringToSign() string {
return request.stringToSign
}

func (request *baseRequest) SetContent(content []byte) {
request.Content = content
}

func (request *baseRequest) GetAcceptFormat() string {
return request.AcceptFormat
}

func (request *baseRequest) GetAccept() string {
switch request.GetAcceptFormat() {
case JSON:
return Json
case XML:
return Xml
}
return ""
}

func (request *baseRequest) GetHeaders() map[string]string {
return request.Headers
}

func (request *baseRequest) GetActionName() string {
return request.actionName
}

func (request *baseRequest) SetScheme(scheme string) {
request.Scheme = scheme
}

func (request *baseRequest) SetDomain(host Host) {
request.Domain = host
}

func (request *baseRequest) GetScheme() string {
return request.Scheme
}

func (request *baseRequest) GetDomain() Host {
return request.Domain
}

func (request *baseRequest) GetMethod() string {
return request.Method
}

func (request *baseRequest) GetFormParams() map[string]string {
return request.FormParams
}

func (request *baseRequest) GetQueryParams() map[string]string {
return request.QueryParams
}

func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) {
request.isInsecure = &isInsecure
}

func (request *baseRequest) GetHTTPSInsecure() *bool {
return request.isInsecure
}

func (request *baseRequest) GetReadTimeout() time.Duration {
return request.ReadTimeout
}

func (request *baseRequest) GetConnectTimeout() time.Duration {
return request.ConnectTimeout
}

func (request *baseRequest) SetReadTimeout(readTimeOut time.Duration) {
request.ReadTimeout = readTimeOut
}

func (request *baseRequest) SetConnectTimeout(connectTimeOut time.Duration) {
request.ConnectTimeout = connectTimeOut
}

func (request *baseRequest) SetStringToSign(stringToSign string) {
request.stringToSign = stringToSign
}

func (request *baseRequest) AddHeaderParam(key, val string) {
request.Headers[key] = val
}

func (request *baseRequest) addQueryParam(key, val string) {
request.QueryParams[key] = val
}

func (request *baseRequest) addFormParam(key, val string) {
request.FormParams[key] = val
}

func defaultBaseRequest() (request *baseRequest) {
request = &baseRequest{
Scheme: HTTP,
AcceptFormat: JSON,
Method: GET,
QueryParams: make(map[string]string),
Headers: map[string]string{
"Gr-Sdk-Client": "golang/1.14",
"Gr-Sdk-Invoke-Type": "normal",
"Accept-Encoding": Json,
},
FormParams: make(map[string]string),
}
return
}

func InitParam(request AcsRequest) (err error) {
reflectValue := reflect.ValueOf(request).Elem()
err = flatRepeatedList(reflectValue, request, "")
return nil
}

func flatRepeatedList(reflectValue reflect.Value, request AcsRequest, position string) (err error) {
reflectType := reflectValue.Type()
for i := 0; i < reflectType.NumField(); i++ {
field := reflectType.Field(i)
name, isContiansNameTag := field.Tag.Lookup("field")

fieldPosition := position
if fieldPosition == "" {
fieldPosition, _ = field.Tag.Lookup("position")
}

fieldDefault, _ := field.Tag.Lookup("default")
debug("%s %s %s", name, fieldPosition, fieldDefault)
if isContiansNameTag {
var value string
switch field.Type.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
value = strconv.FormatInt(reflectValue.Field(i).Int(), 10)
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
value = strconv.FormatUint(reflectValue.Field(i).Uint(), 10)
case reflect.Float32, reflect.Float64:
value = strconv.FormatFloat(reflectValue.Field(i).Float(), 'E', -1, 64)
case reflect.Bool:
value = strconv.FormatBool(reflectValue.Field(i).Bool())
case reflect.Complex64, reflect.Complex128:
value = fmt.Sprint(cmplx.Sqrt(reflectValue.Field(i).Complex()))
default:
value = reflectValue.Field(i).String()
}

if len(value) == 0 {
value = fieldDefault
}

if value == "0" && fieldDefault != "" && fieldDefault != "0" {
value = fieldDefault
}

err = addParam(request, fieldPosition, name, value)
}
}

return
}

func addParam(request AcsRequest, position, key, value string) (err error) {
if len(value) > 0 {
switch position {
case Header:
request.AddHeaderParam(key, value)
case Query:
request.addQueryParam(key, value)
case Body:
request.addFormParam(key, value)
default:
errmsg := fmt.Sprintf("unsupport positions add param `%s`", position)
err = errors.New(errmsg)
}
}
return
}

+ 63
- 0
sdk/requests/rpc_request.go Vedi File

@@ -0,0 +1,63 @@
package requests

import (
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
"io"
"strings"
)

type RpcRequest struct {
*baseRequest
}

func (request *RpcRequest) init() {
request.baseRequest = defaultBaseRequest()
request.Method = POST
}

func (request *RpcRequest) BuildUrl() string {

var hostname string
if request.Domain.Func == nil {
hostname = request.Domain.Default
} else if hostname = request.Domain.Func(request.GetEnv()); hostname == "" {
hostname = request.Domain.Default
}

url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), hostname)
if len(request.Port) > 0 {
url = fmt.Sprintf("%s:%s", url, request.Port)
}
return url + request.BuildQueries()
}

func (request *RpcRequest) GetStyle() string {
return RPC
}

func (request *RpcRequest) BuildQueries() string {
path := strings.TrimLeft(strings.TrimSpace(request.GetActionName()), "/")
request.queries = "/" + path + "?" + utils.GetUrlFormedMap(request.QueryParams)
return request.queries
}

func (request *RpcRequest) GetActionName() string {
return request.actionName
}

func (request *RpcRequest) InitWithApiInfo(domain Host, version, urlPath string) {
request.init()
request.SetDomain(domain)
request.version = version
request.actionName = urlPath
}

func (request *RpcRequest) GetBodyReader() io.Reader {
if request.FormParams != nil && len(request.FormParams) > 0 {
formString := utils.GetUrlFormedMap(request.FormParams)
return strings.NewReader(formString)
} else {
return strings.NewReader("")
}
}

+ 10
- 0
sdk/requests/types.go Vedi File

@@ -0,0 +1,10 @@
package requests

import "strconv"

type Interger string

func (i Interger) ToInt() int {
a, _ := strconv.ParseInt(string(i), 10, 64)
return int(a)
}

+ 117
- 0
sdk/responses/response.go Vedi File

@@ -0,0 +1,117 @@
package responses

import (
"encoding/json"
"errors"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"io/ioutil"
"net/http"
"strings"
)

type AcsResponse interface {
IsSuccess() bool
GetHttpStatus() int
GetHttpHeaders() map[string][]string
GetHttpContentString() string
GetHttpContentBytes() []byte
GetOriginHttpResponse() *http.Response
parseFromHttpResponse(httpResponse *http.Response) error
}

type BaseResponse struct {
httpStatus int
httpHeaders map[string][]string
httpContentString string
httpContentBytes []byte
originHttpResponse *http.Response

Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
}

func (baseResponse *BaseResponse) GetHttpStatus() int {
return baseResponse.httpStatus
}

func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string {
return baseResponse.httpHeaders
}

func (baseResponse *BaseResponse) GetHttpContentString() string {
return baseResponse.httpContentString
}

func (baseResponse *BaseResponse) GetHttpContentBytes() []byte {
return baseResponse.httpContentBytes
}

func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response {
return baseResponse.originHttpResponse
}

func (baseResponse *BaseResponse) IsSuccess() bool {
if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 {
return true
}
return false
}

func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) {
defer httpResponse.Body.Close()
body, err := ioutil.ReadAll(httpResponse.Body)
if err != nil {
return
}
baseResponse.httpStatus = httpResponse.StatusCode
baseResponse.httpHeaders = httpResponse.Header
baseResponse.httpContentBytes = body
baseResponse.httpContentString = string(body)
baseResponse.originHttpResponse = httpResponse
return
}

type CommonResponse struct {
*BaseResponse
}

func NewCommonResponse() (response *CommonResponse) {
return &CommonResponse{
BaseResponse: &BaseResponse{},
}
}

func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
err = response.parseFromHttpResponse(httpResponse)
if err != nil {
return
}

if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
return
}

if !response.IsSuccess() {
if contentType, ok := response.GetHttpHeaders()["Content-Type"]; ok {
for _, v := range contentType {
if strings.Contains(v, requests.Json) {
json.Unmarshal(response.GetHttpContentBytes(), response)
break
}
}
}

err = errors.New(fmt.Sprintf("%d %s", response.GetHttpStatus(), response.GetHttpContentString()))
return
}

if format != "xml" {
err = json.Unmarshal(response.GetHttpContentBytes(), response)
if err != nil {
return errors.New("json Unmarshal:" + err.Error())
}
}
return
}

+ 36
- 0
sdk/utils/debug.go Vedi File

@@ -0,0 +1,36 @@
package utils

import (
"fmt"
"os"
"strings"
)

type Debug func(format string, v ...interface{})

var hookPrint = func(input string) {
fmt.Println(input)
}

var hookGetEnv = func() string {
return os.Getenv("DEBUG")
}

func Init(flag string) Debug {

enable := false
env := hookGetEnv()
parts := strings.Split(env, ",")
for _, part := range parts {
if part == flag {
enable = true
break
}
}

return func(format string, v ...interface{}) {
if enable {
hookPrint(fmt.Sprintf(format, v...))
}
}
}

+ 111
- 0
sdk/utils/utils.go Vedi File

@@ -0,0 +1,111 @@
package utils

import (
"crypto/md5"
"crypto/rand"
"encoding/hex"
"fmt"
"hash"
rand2 "math/rand"
"net/url"
"reflect"
"sort"
"strconv"
"strings"
"time"
)

type UUID [16]byte

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

func GetUUID() (uuidHex string) {
uuid := NewUUID()
uuidHex = hex.EncodeToString(uuid[:])
return
}

func NewUUID() UUID {
ns := UUID{}
safeRandom(ns[:])
u := newFromHash(md5.New(), ns, RandStringBytes(16))
u[6] = (u[6] & 0x0f) | (byte(2) << 4)
u[8] = (u[8]&(0xff>>2) | (0x02 << 6))

return u
}

func RandStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand2.Intn(len(letterBytes))]
}
return string(b)
}

func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))

return u
}

func safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}

func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
urlEncoder := url.Values{}
for key, value := range source {
urlEncoder.Add(key, value)
}
urlEncoded = urlEncoder.Encode()
return
}

func GetUrlByKeySort(source map[string]string) (url string) {
keys := make([]string, 0, len(source))
for k := range source {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
url += fmt.Sprintf("%s=%s&", key, source[key])
}
return strings.TrimRight(url, "&")
}

func InitStructWithDefaultTag(bean interface{}) {
beantype := reflect.TypeOf(bean)
for i := 0; i < beantype.Elem().NumField(); i++ {
field := beantype.Elem().Field(i)
defaultValue := strings.TrimSpace(field.Tag.Get("default"))
if defaultValue == "" || defaultValue == "-" {
continue
}
setter := reflect.ValueOf(bean).Elem().Field(i)
fieldTypeName := field.Type.String()
switch fieldTypeName {
case "int", "int64", "int32", "int8", "int16":
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intval)
case "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
uintval, _ := strconv.ParseUint(defaultValue, 10, 64)
setter.SetUint(uintval)
case "string":
setter.SetString(defaultValue)
case "time.Duration":
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
setter.SetInt(intval * int64(time.Second))
case "bool":
boolval, _ := strconv.ParseBool(defaultValue)
setter.SetBool(boolval)
default:
fmt.Println(field.Type.String(), field.Name)
}
}
}

+ 25
- 0
sdk/utils/utils_test.go Vedi File

@@ -0,0 +1,25 @@
package utils

import (
"fmt"
"net/http"
"testing"
"time"
)

type TestCase struct {
Debug bool `default:"false"`
HttpTransport *http.Transport `default:""`
Transport http.RoundTripper `default:""`
GoRoutinePoolSize int `default:"5"`
UserAgent string `default:""`
Scheme string `default:"HTTP"`
Haha uintptr `default:"232"`
Timeout time.Duration `default:"5"`
}

func TestInitStructWithDefaultTag(t *testing.T) {
testcase := &TestCase{}
InitStructWithDefaultTag(testcase)
fmt.Printf("%+v", testcase)
}

+ 37
- 0
services/apk/add_apk.go Vedi File

@@ -0,0 +1,37 @@
package apk

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type AddApkRequest struct {
*requests.RpcRequest
List string `position:"Body" field:"list" default:"[]" `
}

type AddApkResponse struct {
*responses.BaseResponse
Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
Data struct {
Count int `json:"count"`
} `json:"data"`
}

func CreateAddApkRequest() (req *AddApkRequest) {
req = &AddApkRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/apk/add")
req.Method = requests.POST
return
}

func CreateAddApkResponse() (response *AddApkResponse) {
response = &AddApkResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 36
- 0
services/apk/add_top.go Vedi File

@@ -0,0 +1,36 @@
package apk

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type AddTopRequest struct {
*requests.RpcRequest
Id int `position:"Body" field:"id" default:"0" `
Ids string `position:"Body" field:"ids" default:"" `
Top int `position:"Body" field:"top" default:"0"`
}

type AddTopResponse struct {
*responses.BaseResponse
Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
}

func CreateAddTopRequest() (req *AddTopRequest) {
req = &AddTopRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/apk/AddTop")
req.Method = requests.POST
return
}

func CreateAddTopResponse() (response *AddTopResponse) {
response = &AddTopResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 66
- 0
services/apk/client.go Vedi File

@@ -0,0 +1,66 @@
package apk

import (
"encoding/json"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)

const (
VERSION = "2021-07-30"
)

var HOST requests.Host = requests.Host{
Default: "c.api.gaore.com",
Func: func(s string) string {
var a = map[string]string{
requests.RELEASE: "c.api.gaore.com",
requests.PRE: "c.api.gaore.com",
requests.TEST: "c.api.gaore.com",
}
return a[s]
},
}

type Client struct {
sdk.Client
}

func NewClient() (client *Client) {
client = &Client{}
client.InitWithAccessKey("", "", "")
return
}

// 打包任务添加优先级
func (c *Client) AddApkTop(req *AddTopRequest) (response *AddTopResponse, err error) {
response = CreateAddTopResponse()
err = c.DoAction(req, response)
return
}

// 添加打包任务
func (c *Client) AddApk(req *AddApkRequest) (response *AddApkResponse, err error) {
response = CreateAddApkResponse()
err = c.DoAction(req, response)
return
}

// 清除cdn
func (c *Client) RefreshApkR(req *RefreshApkRequest) (response *RefreshApkResponse, err error) {
response = CreateRefreshApkResponse()
if len(req.CdnUrlArray) > 0 {
cdnurls, _ := json.Marshal(req.CdnUrlArray)
req.cdnUrls = string(cdnurls)
}
err = c.DoAction(req, response)
return
}

// 获取打包日志
func (c *Client) SearchApk(req *SearchApkRequest) (response *SearchApkResponse, err error) {
response = CreateSearchApkResponse()

err = c.DoAction(req, response)
return
}

+ 21
- 0
services/apk/client_test.go Vedi File

@@ -0,0 +1,21 @@
package apk

import (
"fmt"
"testing"
"time"
)

func TestClient_GetUserInfo(t *testing.T) {
c := NewClient()
req := CreateSearchApkRequest()
req.GameIds = "3503"
req.Ver = "1.0.0"
req.SetReadTimeout(60 * time.Second)
resp, err := c.SearchApk(req)

fmt.Println(req)
fmt.Println(resp.GetHttpContentString())
fmt.Println(err)

}

+ 36
- 0
services/apk/refresh_apk.go Vedi File

@@ -0,0 +1,36 @@
package apk

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type RefreshApkRequest struct {
*requests.RpcRequest
cdnUrls string `position:"Body" field:"cdn_urls" default:"[]" `
CdnUrlArray []string
}

type RefreshApkResponse struct {
*responses.BaseResponse
Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
Data map[string]string `json:"data"`
}

func CreateRefreshApkRequest() (req *RefreshApkRequest) {
req = &RefreshApkRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/apk/refresh")
req.Method = requests.POST
return
}

func CreateRefreshApkResponse() (response *RefreshApkResponse) {
response = &RefreshApkResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 74
- 0
services/apk/search_apk.go Vedi File

@@ -0,0 +1,74 @@
package apk

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
"time"
)

type SearchApkRequest struct {
*requests.RpcRequest
StartTime string `position:"Body" field:"startTime" default:"" `
EndTime string `position:"Body" field:"endTime" default:"" `
State string `position:"Body" field:"state" default:"" `
SiteIds string `position:"Body" field:"siteIds" default:"" `
Ver string `position:"Body" field:"ver" default:"" `
SiteId int `position:"Body" field:"siteId" default:"" `
AgentId int `position:"Body" field:"agentId" default:"" `
Top int `position:"Body" field:"top" default:"" `
GameIds string `position:"Body" field:"gameIds" default:"" `
Autor string `position:"Body" field:"autor" default:"" `
Page int `position:"Body" field:"page" default:"1" `
Pagesize int `position:"Body" field:"pagesize" default:"20" `
Order string `position:"Body" field:"order" default:"" `
}

type ApkLog struct {
ID int `json:"Id"`
GameID int `json:"GameId"`
GameName string `json:"GameName"`
Ver string `json:"Ver"`
Top int `json:"Top"`
AgentID int `json:"AgentId"`
SiteID int `json:"SiteId"`
Addtime time.Time `json:"Addtime"`
Edittime time.Time `json:"Edittime"`
State int `json:"State"`
Times int `json:"Times"`
ReleaseTime int `json:"ReleaseTime"`
Env int `json:"Env"`
AliOss int `json:"AliOss"`
NeedCdn bool `json:"NeedCdn"`
Autor string `json:"Autor"`
Ext string `json:"Ext"`
IsAugment bool `json:"IsAugment"`
}

type SearchApkResponse struct {
*responses.BaseResponse
Code int `json:"code"`
Status bool `json:"status"`
Msg string `json:"msg"`
Data struct {
Page int `json:"Page"`
PageSize int `json:"PageSize"`
Total int `json:"Total"`
List []ApkLog `json:"List"`
} `json:"data"`
}

func CreateSearchApkRequest() (req *SearchApkRequest) {
req = &SearchApkRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/apk/list")
req.Method = requests.POST
return
}

func CreateSearchApkResponse() (response *SearchApkResponse) {
response = &SearchApkResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 48
- 0
services/callback/client.go Vedi File

@@ -0,0 +1,48 @@
package callback

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)

const (
VERSION = "2021-11-30"
)

var HOST requests.Host = requests.Host{
Default: "callback.api.gaore.com",
Func: func(s string) string {
var a = map[string]string{
requests.RELEASE: "callback.api.gaore.com",
requests.PRE: "callback.api.gaore.com",
requests.TEST: "callback.api.gaore.com",
}
return a[s]
},
}

type Client struct {
sdk.Client
}

func NewClient() (client *Client) {
client = &Client{}
client.InitWithAccessKey("", "", "")
return
}

// 上报关键行为
func (c *Client) SendAction(req *SendActionRequest) (response *SendActionResponse, err error) {
response = CreateSendActionResponse()
err = c.DoAction(req, response)
return
}

// 上报激活
func (c *Client) SendActive() {

}

// 上报付费

// 上报注册

+ 49
- 0
services/callback/send_action.go Vedi File

@@ -0,0 +1,49 @@
package callback

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

const OS_ANDROID = 2

const OS_IOS = 1

type SendActionRequest struct {
*requests.RpcRequest
GameId int64 `position:"Query" field:"game_id" default:"" `
AgentId int64 `position:"Query" field:"agent_id" default:"" `
SiteId int64 `position:"Query" field:"site_id" default:"" `
Imei string `position:"Query" field:"imei" default:"" `
Oaid string `position:"Query" field:"oaid" default:"" `
Ip string `position:"Query" field:"ip" default:"" `
Ua string `position:"Query" field:"ua" default:"" `
Os int `position:"Query" field:"os" default:"" `
ParamsArray []string
}

type SendActionResponseData struct {
Account string `json:"account"`
Total int `json:"total"`
}

type SendActionResponse struct {
*responses.BaseResponse
Data SendActionResponseData `json:"data"`
}

func CreateSendActionRequest() (req *SendActionRequest) {
req = &SendActionRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/callback/ads_callback/sendAction")
req.Method = requests.GET
return
}

func CreateSendActionResponse() (response *SendActionResponse) {
response = &SendActionResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 29
- 0
services/jedi/README.md Vedi File

@@ -0,0 +1,29 @@


### 发送短信调用示例
```go
import (
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/services/jedi"
)

func main() {
c, err := jedi.NewClientWithAccessKey("accessKeyId", "accessKeySecret", "xxx.xxx.com")
if err != nil {
return
}
req := jedi.CreateSendSmsRequest()
// sso统一用户名uid, 多个用户用逗句隔开
req.User = "liangzy,liaoks"
// 公共模板的代码模板
req.Code = "d7kt5IwP"
// 模板参数,模板里有多少个模板参数就传入几个替换字符串,
req.ParamsArray = []string{"www", "线上", "好人"}
if resp, err := c.SendSms(req); err == nil {
grlogs.Informational(fmt.Sprintf("%+v", resp.GetHttpContentString()))
} else {
grlogs.Error(err)
}
}
```

+ 48
- 0
services/jedi/client.go Vedi File

@@ -0,0 +1,48 @@
package jedi

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"strings"
)

const (
VERSION = "2020-09-24"
)

var HOST requests.Host = requests.Host{
Default: "jedi.api.gaore.com",
Func: func(s string) string {
var a = map[string]string{
requests.RELEASE: "jedi.api.gaore.com",
requests.PRE: "jedi.api.gaore.com",
requests.TEST: "jedi.oapi.gaore.com",
}
return a[s]
},
}

type Client struct {
sdk.Client
}

func (c *Client) SendSms(req *SendSmsRequest) (response *SendSmsResponse, err error) {
if req.ParamsArray != nil && len(req.ParamsArray) > 0 {
req.Params = strings.Join(req.ParamsArray, ",,,")
}
response = CreateSendSmsResponse()
err = c.DoAction(req, response)
return
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAccessKey(accesskey, secrect, source)
return
}

func NewClientWithAliAppcode(accesskey, secrect string, env ...string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAliAppcode(accesskey, secrect, env...)
return
}

+ 40
- 0
services/jedi/send_sms.go Vedi File

@@ -0,0 +1,40 @@
package jedi

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type SendSmsRequest struct {
*requests.RpcRequest
User string `position:"Body" field:"user" default:"" `
Code string `position:"Body" field:"code" default:"" `
Params string `position:"Body" field:"params" default:"" `
ParamsArray []string
}

type SendSmsResponseData struct {
Account string `json:"account"`
Total int `json:"total"`
}

type SendSmsResponse struct {
*responses.BaseResponse
Data SendSmsResponseData `json:"data"`
}

func CreateSendSmsRequest() (req *SendSmsRequest) {
req = &SendSmsRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/sms/send")
req.Method = requests.POST
return
}

func CreateSendSmsResponse() (response *SendSmsResponse) {
response = &SendSmsResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 50
- 0
services/mail/client.go Vedi File

@@ -0,0 +1,50 @@
package mail

import (
"crypto/md5"
"fmt"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"time"
)

const (
VERSION = "2021-09-27"
)

var HOST requests.Host = requests.Host{
Default: "mail.gaore.com",
Func: func(s string) string {
var a = map[string]string{
requests.RELEASE: "mail.gaore.com",
requests.PRE: "mail.gaore.com",
requests.TEST: "mail.gaore.com",
}
return a[s]
},
}

type Client struct {
sdk.Client
}

func NewClient() (client *Client) {
client = &Client{}
client.InitWithAccessKey("", "", "")
return
}

func (c *Client) SendEmail(req *PostEmailRequest) (response *PostEmailResponse, err error) {

now := time.Now().Second()
key := "04573fc4c8e01999a0909ab9c00bca5a"
signstr := fmt.Sprintf("%d%s", now, key)
data := []byte(signstr)
has := md5.Sum(data)
sign := fmt.Sprintf("%x", has)
req.Time = now
req.Sign = sign
response = CreatePostEmailResponse()
err = c.DoAction(req, response)
return
}

+ 22
- 0
services/mail/client_test.go Vedi File

@@ -0,0 +1,22 @@
package mail

import (
"fmt"
"testing"
"time"
)

func TestClient_GetUserInfo(t *testing.T) {
c := NewClient()
req := CreatePostEmailRequest()
req.Addresses = "3002467428@qq.com"
req.Body = "1111"
req.FromName = "213123121"
req.SetReadTimeout(60 * time.Second)
resp, err := c.SendEmail(req)

fmt.Println(req)
fmt.Println(resp.GetHttpContentString())
fmt.Println(err)

}

+ 36
- 0
services/mail/end_email.go Vedi File

@@ -0,0 +1,36 @@
package mail

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type PostEmailRequest struct {
*requests.RpcRequest
Addresses string `position:"Body" field:"addresses" default:"" `
Subject string `position:"Body" field:"subject" default:"" `
Body string `position:"Body" field:"body" default:""`
FromName string `position:"Body" field:"fromName" default:""`
Time int `position:"Body" field:"time" default:""`
Sign string `position:"Body" field:"sign" default:""`
}

type PostEmailResponse struct {
*responses.BaseResponse
}

func CreatePostEmailRequest() (req *PostEmailRequest) {
req = &PostEmailRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/email/post_email.php")
req.Method = requests.POST
return
}

func CreatePostEmailResponse() (response *PostEmailResponse) {
response = &PostEmailResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 31
- 0
services/mkt/client.go Vedi File

@@ -0,0 +1,31 @@
package mkt

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)

const (
VERSION = "2020-11-16"
)

var HOST = requests.Host{
Default: "mkt",
}

type Client struct {
sdk.Client
}

// PkgNotice 打包通知
func (c *Client) PkgNotice(req *PkgNoticeRequest) (response *PkgNoticeResponse, err error) {
response = CreatePkgNoticeResponse()
err = c.DoAction(req, response)
return
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAccessKey(accesskey, secrect, source)
return
}

+ 36
- 0
services/mkt/pkg_notice.go Vedi File

@@ -0,0 +1,36 @@
package mkt

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

// PkgNoticeRequest 打包通知请求信息
type PkgNoticeRequest struct {
*requests.RpcRequest
SiteID int64 `position:"Body" field:"site_id"` // 广告位ID
Status int `position:"Body" field:"status"` // 打包状态(0:失败 1:成功)
}

// PkgNoticeResponse 打包通知响应信息
type PkgNoticeResponse struct {
*responses.BaseResponse
}

// CreatePkgNoticeRequest 创建通知接口
func CreatePkgNoticeRequest() (req *PkgNoticeRequest) {
req = &PkgNoticeRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/game/pkgnotice")
req.Method = requests.POST
return
}

// CreatePkgNoticeResponse 创建通知响应
func CreatePkgNoticeResponse() (response *PkgNoticeResponse) {
response = &PkgNoticeResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 48
- 0
services/sso/client.go Vedi File

@@ -0,0 +1,48 @@
package sso

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)

const (
VERSION = "2020-08-07"
)

var HOST = requests.Host{
Default: "sso",
}

type Client struct {
sdk.Client
}

func (c *Client) CodeAuth(req *CodeAuthRequest) (response *CodeAuthResponse, err error) {
response = CreateCodeAuthResponse()
err = c.DoAction(req, response)
return
}

func (c *Client) GetUserInfo(req *GetUserInfoRequest) (response *GetUserInfoResponse, err error) {
response = CreateGetUserInfoResponse()
err = c.DoAction(req, response)
return
}

func (c *Client) RefreshToken(req *RefreshTokenRequest) (response *RefreshTokenResponse, err error) {
response = CreateRefreshTokenResponse()
err = c.DoAction(req, response)
return
}

func (c *Client) SearchUser(req *SearchUserRequest) (response *SearchUserResponse, err error) {
response = CreateSearchUserResponse()
err = c.DoAction(req, response)
return
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAccessKey(accesskey, secrect, source)
return
}

+ 39
- 0
services/sso/code_auth.go Vedi File

@@ -0,0 +1,39 @@
package sso

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type CodeAuthRequest struct {
*requests.RpcRequest
OauthCode string `position:"Body" field:"oauthCode" default:"" `
Ident string `position:"Body" field:"ident" default:"" `
}

type CodeAuthResponseData struct {
RefreshToken string `json:"refreshToken"`
RefreshTokenExpires int64 `json:"refreshTokenExpires"`
Token string `json:"token"`
TokenExpires int64 `json:"tokenExpires"`
User User `json:"user"`
}

type CodeAuthResponse struct {
*responses.BaseResponse
Data CodeAuthResponseData `json:"data"`
}

func CreateCodeAuthRequest() (req *CodeAuthRequest) {
req = &CodeAuthRequest{RpcRequest: &requests.RpcRequest{}}
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/codeAuth")
req.Method = requests.POST
return
}

func CreateCodeAuthResponse() (response *CodeAuthResponse) {
response = &CodeAuthResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 35
- 0
services/sso/get_user.go Vedi File

@@ -0,0 +1,35 @@
package sso

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type GetUserInfoRequest struct {
*requests.RpcRequest
Token string `position:"Body" field:"token" default:"" `
Ident string `position:"Body" field:"ident" default:"" `
}

type GetUserInfoResponseData struct {
User User `json:"user"`
}

type GetUserInfoResponse struct {
*responses.BaseResponse
Data GetUserInfoResponseData `json:"data"`
}

func CreateGetUserInfoRequest() (req *GetUserInfoRequest) {
req = &GetUserInfoRequest{RpcRequest: &requests.RpcRequest{}}
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/getUserInfo")
req.Method = requests.POST
return
}

func CreateGetUserInfoResponse() (response *GetUserInfoResponse) {
response = &GetUserInfoResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 37
- 0
services/sso/refresh_token.go Vedi File

@@ -0,0 +1,37 @@
package sso

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type RefreshTokenRequest struct {
*requests.RpcRequest
RefreshToken string `position:"Body" field:"refreshToken" default:"" `
Ident string `position:"Body" field:"ident" default:"" `
}

type RefreshTokenResponseData struct {
Token string `json:"token"`
TokenExpires int64 `json:"tokenExpires"`
User User `json:"user"`
}

type RefreshTokenResponse struct {
*responses.BaseResponse
Data GetUserInfoResponseData `json:"data"`
}

func CreateRefreshTokenRequest() (req *RefreshTokenRequest) {
req = &RefreshTokenRequest{RpcRequest: &requests.RpcRequest{}}
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/refreshToken")
req.Method = requests.POST
return
}

func CreateRefreshTokenResponse() (response *RefreshTokenResponse) {
response = &RefreshTokenResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 34
- 0
services/sso/search_user.go Vedi File

@@ -0,0 +1,34 @@
package sso

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type SearchUserRequest struct {
*requests.RpcRequest
Uid string `position:"Body" field:"uid" default:"" `
}

type SearchUserResponseData struct {
User User `json:"user"`
}

type SearchUserResponse struct {
*responses.BaseResponse
Data SearchUserResponseData `json:"data"`
}

func CreateSearchUserRequest() (req *SearchUserRequest) {
req = &SearchUserRequest{RpcRequest: &requests.RpcRequest{}}
req.InitWithApiInfo(HOST, VERSION, "/api/user/search")
req.Method = requests.POST
return
}

func CreateSearchUserResponse() (response *SearchUserResponse) {
response = &SearchUserResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 27
- 0
services/sso/struct.go Vedi File

@@ -0,0 +1,27 @@
package sso

type User struct {
Uid string `json:"uid"`
UidNumber string `json:"uidNumber"`
Name string `json:"name"`
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
RealName string `json:"realname"`
Mobile string `json:"mobile"`
Mail string `json:"mail"`
Department Department `json:"department"`
Roles []Role `json:"roles"`
Domains []string `json:"domains"`
}

type Department struct {
Gid string `json:"gid"`
Name string `json:"name"`
Abbr string `json:"abbr"`
}

type Role struct {
Name string `json:"name"`
Domains []string `json:"domains"`
Abbr string `json:"abbr"`
}

+ 44
- 0
services/www/client.go Vedi File

@@ -0,0 +1,44 @@
package www

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
)

const (
VERSION = "2020-09-24"
)

var HOST requests.Host = requests.Host{
Default: "apisdk.9ooo.cn",
Func: func(s string) string {
var a = map[string]string{
requests.RELEASE: "apisdk.9ooo.cn",
requests.PRE: "apisdk.9ooo.cn",
requests.TEST: "apisdk.9ooo.cn",
}
return a[s]
},
}

type Client struct {
sdk.Client
}

func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAccessKey(accesskey, secrect, source)
return
}

func NewClientWithAliAppcode(accesskey, secrect string, env ...string) (client *Client, err error) {
client = &Client{}
err = client.InitWithAliAppcode(accesskey, secrect, env...)
return
}

func (c *Client) GetUserInfo(req *GetPwdRequest) (response *GetPwdResponse, err error) {
response = CreateGetPwdResponse()
err = c.DoAction(req, response)
return
}

+ 25
- 0
services/www/client_test.go Vedi File

@@ -0,0 +1,25 @@
package www

import (
"fmt"
"log"
"testing"
)

func TestClient_GetUserInfo(t *testing.T) {

c, err := NewClientWithAliAppcode("203874304", "9e5489a82dd641729186cdad166d81a3")
if err != nil {
t.Error(err)
}

req := CreateGetPwdRequest()
req.UserName = "ttom666"

resp, err := c.GetUserInfo(req)
if err != nil {
log.Fatalln(err)
}
fmt.Println(resp.GetHttpContentString())
fmt.Println(resp.GetHttpHeaders())
}

+ 38
- 0
services/www/get_pwd.go Vedi File

@@ -0,0 +1,38 @@
package www

import (
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
)

type GetPwdRequest struct {
*requests.RpcRequest
UserName string `position:"Query" field:"user_name" default:"-" `
Uid int64 `position:"Query" field:"uid" default:"0"`
}

type GetPwdResponse struct {
*responses.BaseResponse
Ret int `json:"ret"`
Msg string `json:"msg"`
Data struct {
UserName string `json:"user_name"`
UserPwd string `json:"user_pwd"`
} `json:"data"`
}

func CreateGetPwdRequest() (req *GetPwdRequest) {
req = &GetPwdRequest{
RpcRequest: &requests.RpcRequest{},
}
req.InitWithApiInfo(HOST, VERSION, "/api/limit/getPwd.php")
req.Method = requests.GET
return
}

func CreateGetPwdResponse() (response *GetPwdResponse) {
response = &GetPwdResponse{
BaseResponse: &responses.BaseResponse{},
}
return
}

+ 1
- 0
services/www/get_token.go Vedi File

@@ -0,0 +1 @@
package www

Loading…
Annulla
Salva