huawei.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package smsdriver
  15. import (
  16. "crypto/sha256"
  17. "encoding/base64"
  18. "fmt"
  19. "net/http"
  20. "net/url"
  21. "strings"
  22. "time"
  23. uuid "github.com/satori/go.uuid"
  24. "yunion.io/x/pkg/errors"
  25. "yunion.io/x/pkg/util/httputils"
  26. api "yunion.io/x/onecloud/pkg/apis/notify"
  27. "yunion.io/x/onecloud/pkg/notify/models"
  28. )
  29. // 无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
  30. const WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\""
  31. // 无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
  32. const AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\""
  33. type SHuaweiSMSDriver struct{}
  34. func (d *SHuaweiSMSDriver) Name() string {
  35. return DriverHuawei
  36. }
  37. func (d *SHuaweiSMSDriver) Verify(config *api.NotifyConfig) error {
  38. return d.Send(api.SSMSSendParams{
  39. RemoteTemplate: config.VerifiyCode,
  40. To: config.PhoneNumber,
  41. RemoteTemplateParam: api.SRemoteTemplateParam{Code: "0000"},
  42. }, true, config)
  43. }
  44. func (d *SHuaweiSMSDriver) Send(args api.SSMSSendParams, isVerify bool, config *api.NotifyConfig) error {
  45. if isVerify {
  46. args.AppKey = config.AccessKeyId
  47. args.AppSecret = config.AccessKeySecret
  48. args.Signature = config.Signature
  49. } else {
  50. args.AppKey = models.ConfigMap[api.MOBILE].Content.AccessKeyId
  51. args.AppSecret = models.ConfigMap[api.MOBILE].Content.AccessKeySecret
  52. args.Signature = models.ConfigMap[api.MOBILE].Content.Signature
  53. }
  54. args.TemplateId = strings.Split(args.RemoteTemplate, "/")[1]
  55. args.From = strings.Split(args.RemoteTemplate, "/")[0]
  56. return d.sendSms(args)
  57. }
  58. func (d *SHuaweiSMSDriver) sendSms(args api.SSMSSendParams) error {
  59. uri := models.ConfigMap[api.MOBILE].Content.ServiceUrl + HuaweiSendUri + "?"
  60. header := http.Header{}
  61. header.Set("Content-Type", "application/x-www-form-urlencoded")
  62. header.Set("Authorization", AUTH_HEADER_VALUE)
  63. header.Set("X-WSSE", buildWsseHeader(args.AppKey, args.AppSecret))
  64. params := url.Values{}
  65. params.Set("from", args.From)
  66. params.Set("to", args.To)
  67. params.Set("templateId", args.TemplateId)
  68. params.Set("templateParas", args.TemplateParas)
  69. params.Set("signature", args.Signature)
  70. resp, err := sendRequest(uri, httputils.POST, header, params, nil)
  71. if err != nil {
  72. return errors.Wrap(err, "huawei sendRequest")
  73. }
  74. code, _ := resp.GetString("code")
  75. if code != "000000" {
  76. return errors.Wrap(errors.ErrInvalidFormat, resp.PrettyString())
  77. }
  78. return nil
  79. }
  80. func buildWsseHeader(appKey, appSecret string) string {
  81. var cTime = time.Now().Format("2006-01-02T15:04:05Z")
  82. var nonce = uuid.NewV4().String()
  83. nonce = strings.ReplaceAll(nonce, "-", "")
  84. h := sha256.New()
  85. h.Write([]byte(nonce + cTime + appSecret))
  86. passwordDigestBase64Str := base64.StdEncoding.EncodeToString(h.Sum(nil))
  87. return fmt.Sprintf(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, cTime)
  88. }
  89. func init() {
  90. models.SMSRegister(&SHuaweiSMSDriver{})
  91. }