aliyun-rails 0.1.7 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1b8d429bd2e0af97f8256a95486b4099c748a98299423f1034956e077863def
4
- data.tar.gz: 7e88442f78ebb508b1389aa6b0fb6adb7c31b0a16e8fef00972c02ec50be315e
3
+ metadata.gz: 0bfda2ced83243ced803fb987f85b20ceb20501b1a5ad5217c5892e38ba49f81
4
+ data.tar.gz: 285b9b4ef3ec57c4085a717d3a5e2f821ab3971c82c5be1ef0ae8fd29e2f7d73
5
5
  SHA512:
6
- metadata.gz: b0b3b8c019c286556461cc5057ecfc8bdb0346938e3945af10f8f0f11600e482eafe67cd4011eff7f06b022de04365766cc96859ba0fb03effc1af48d9ff7b18
7
- data.tar.gz: ca4d8ba575fb3a5e1a0c6db31ea665946ec73c9919e28ecc90dd81f4b385214bd59ade7d57d8725acdb9258ca3ab91312ffc4f723d005f32b67373e6fff72554
6
+ metadata.gz: ed383278974ad1383c8f9fef1ce1112826de64231ead5a16eae70fa0dd77d544a0d9a50a356ecf7b8b127d98472552ca80a2edae92fcce73a285bc63ab54e1ee
7
+ data.tar.gz: 8ff7bbdb1d7aea338877387e876b8eb6365329309a219db622f9607aed48a78597d9c5957dcd96039f0c1c0a01d51e1727c286d2f2d5adc8c0ef6f846d9a61fd
data/README.md CHANGED
@@ -1,85 +1,85 @@
1
- [English](./README.md) | 简体中文
2
-
3
-
4
- <p align="center">
5
- <a href=" https://www.alibabacloud.com"><img src="https://aliyunsdk-pages.alicdn.com/icons/Aliyun.svg"></a>
6
- </p>
7
-
8
- <h1 align="center">非官方SDK套件-用于RAILS项目的</h1>
9
-
10
- <p align="center">
11
- <a href="https://badge.fury.io/rb/aliyunsdkcore"><img src="https://badge.fury.io/rb/aliyunsdkcore.svg" alt="Gem Version"></a>
12
- <a href="https://travis-ci.org/aliyun/openapi-core-ruby-sdk"><img src="https://travis-ci.org/aliyun/openapi-core-ruby-sdk.svg?branch=master" alt="Build Status"></a>
13
- <a href="https://ci.appveyor.com/project/aliyun/openapi-core-ruby-sdk/branch/master"><img src="https://ci.appveyor.com/api/projects/status/uyepkk5bjbynofvu/branch/master?svg=true" alt="Build status"></a>
14
- <a href="https://codecov.io/gh/aliyun/openapi-core-ruby-sdk"><img src="https://codecov.io/gh/aliyun/openapi-core-ruby-sdk/branch/master/graph/badge.svg" alt="codecov"></a>
15
- </p>
16
-
17
-
18
- 支持 Rails 轻松访问阿里云服务,例如:弹性云主机(ECS)、负载均衡(SLB)、云监控(CloudMonitor)等。
19
-
20
- 本文档介绍如何安装和使用 aliyun-rails
21
-
22
- ## 使用诊断
23
- [Troubleshoot](https://troubleshoot.api.aliyun.com/?source=github_sdk) 提供 OpenAPI 使用诊断服务,通过 `RequestID` 或 `报错信息` ,帮助开发者快速定位,为开发者提供解决方案。
24
-
25
- ## 安装
26
-
27
- ```sh
28
- $ gem install aliyun-rails
29
- ```
30
-
31
- ## 使用
32
-
33
- RPC 示例;
34
-
35
- ```ruby
36
- require "aliyun-rails"
37
-
38
- client = Dysms.new(
39
- access_key_id: ENV['ACCESS_KEY_ID'],
40
- access_key_secret: ENV['ACCESS_KEY_SECRET'],
41
- )
42
-
43
- response = client.send_sms("1380000000", "SMS_10010", {param1: "11"}, "SIGN_NAME")
44
-
45
- puts response
46
- ```
47
-
48
-
49
- ROA 示例:
50
-
51
- ```ruby
52
- require 'aliyun-rails'
53
-
54
- client = ROAClient.new(
55
- endpoint: 'http://ros.aliyuncs.com',
56
- api_version: '2015-09-01',
57
- access_key_id: ENV['ACCESS_KEY_ID'],
58
- access_key_secret: ENV['ACCESS_KEY_SECRET'],
59
- )
60
-
61
- response = client.request(
62
- method: 'GET',
63
- uri: '/regions',
64
- options: {
65
- timeout: 15000
66
- }
67
- )
68
-
69
- print response.body
70
- ```
71
-
72
- ## 问题
73
- [提交 Issue](https://github.com/ciscolive/aliyun-rails/issues/new/choose),不符合指南的问题可能会立即关闭。
74
-
75
-
76
- ## 发行说明
77
- 每个版本的详细更改记录在[发行说明](CHANGELOG.md)中。
78
-
79
-
80
- ## 贡献
81
- 提交 Pull Request 之前请阅读[贡献指南](CONTRIBUTING.md)。
82
-
83
-
84
- ## 许可证
1
+ [English](./README.md) | 简体中文
2
+
3
+
4
+ <p align="center">
5
+ <a href=" https://www.alibabacloud.com"><img src="https://aliyunsdk-pages.alicdn.com/icons/Aliyun.svg"></a>
6
+ </p>
7
+
8
+ <h1 align="center">非官方SDK套件-用于RAILS项目的</h1>
9
+
10
+ <p align="center">
11
+ <a href="https://badge.fury.io/rb/aliyunsdkcore"><img src="https://badge.fury.io/rb/aliyunsdkcore.svg" alt="Gem Version"></a>
12
+ <a href="https://travis-ci.org/aliyun/openapi-core-ruby-sdk"><img src="https://travis-ci.org/aliyun/openapi-core-ruby-sdk.svg?branch=master" alt="Build Status"></a>
13
+ <a href="https://ci.appveyor.com/project/aliyun/openapi-core-ruby-sdk/branch/master"><img src="https://ci.appveyor.com/api/projects/status/uyepkk5bjbynofvu/branch/master?svg=true" alt="Build status"></a>
14
+ <a href="https://codecov.io/gh/aliyun/openapi-core-ruby-sdk"><img src="https://codecov.io/gh/aliyun/openapi-core-ruby-sdk/branch/master/graph/badge.svg" alt="codecov"></a>
15
+ </p>
16
+
17
+
18
+ 支持 Rails 轻松访问阿里云服务,例如:弹性云主机(ECS)、负载均衡(SLB)、云监控(CloudMonitor)等。
19
+
20
+ 本文档介绍如何安装和使用 aliyun-rails
21
+
22
+ ## 使用诊断
23
+ [Troubleshoot](https://troubleshoot.api.aliyun.com/?source=github_sdk) 提供 OpenAPI 使用诊断服务,通过 `RequestID` 或 `报错信息` ,帮助开发者快速定位,为开发者提供解决方案。
24
+
25
+ ## 安装
26
+
27
+ ```sh
28
+ $ gem install aliyun-rails
29
+ ```
30
+
31
+ ## 使用
32
+
33
+ RPC 示例;
34
+
35
+ ```ruby
36
+ require "aliyun-rails"
37
+
38
+ client = Dysms.new(
39
+ access_key_id: ENV['ACCESS_KEY_ID'],
40
+ access_key_secret: ENV['ACCESS_KEY_SECRET'],
41
+ )
42
+
43
+ response = client.send_sms("1380000000", "SMS_10010", {param1: "11"}, "SIGN_NAME")
44
+
45
+ puts response
46
+ ```
47
+
48
+
49
+ ROA 示例:
50
+
51
+ ```ruby
52
+ require 'aliyun-rails'
53
+
54
+ client = ROAClient.new(
55
+ endpoint: 'http://ros.aliyuncs.com',
56
+ api_version: '2015-09-01',
57
+ access_key_id: ENV['ACCESS_KEY_ID'],
58
+ access_key_secret: ENV['ACCESS_KEY_SECRET'],
59
+ )
60
+
61
+ response = client.request(
62
+ method: 'GET',
63
+ uri: '/regions',
64
+ options: {
65
+ timeout: 15000
66
+ }
67
+ )
68
+
69
+ print response.body
70
+ ```
71
+
72
+ ## 问题
73
+ [提交 Issue](https://github.com/ciscolive/aliyun-rails/issues/new/choose),不符合指南的问题可能会立即关闭。
74
+
75
+
76
+ ## 发行说明
77
+ 每个版本的详细更改记录在[发行说明](CHANGELOG.md)中。
78
+
79
+
80
+ ## 贡献
81
+ 提交 Pull Request 之前请阅读[贡献指南](CONTRIBUTING.md)。
82
+
83
+
84
+ ## 许可证
85
85
  [MIT](LICENSE.md)
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rubocop/rake_task"
5
-
6
- RuboCop::RakeTask.new
7
-
8
- task default: :rubocop
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :rubocop
@@ -1,168 +1,168 @@
1
- # frozen_string_literal: true
2
-
3
- require "faraday"
4
- require "securerandom"
5
- require "active_support/all"
6
- require "net/http"
7
-
8
- module Net::HTTPHeader
9
- def capitalize(name)
10
- name
11
- end
12
- private :capitalize
13
- end
14
-
15
- module Aliyun
16
- module Rails
17
- module Connector
18
- class ROAClient
19
- attr_accessor :endpoint, :api_version, :access_key_id,
20
- :access_key_secret, :security_token, :hostname, :opts
21
-
22
- def initialize(config)
23
- validate config
24
-
25
- self.endpoint = config[:endpoint]
26
- self.api_version = config[:api_version]
27
- self.access_key_id = config[:access_key_id]
28
- self.access_key_secret = config[:access_key_secret]
29
- self.security_token = config[:security_token]
30
- end
31
-
32
- def request(method:, uri:, params: {}, body: {}, headers: {}, options: {})
33
- # :"Content-Type" => "application/json" to "content-type" => "application/json"
34
- headers.deep_transform_keys! { |key| key.to_s.downcase }
35
- mix_headers = default_headers.merge(headers)
36
-
37
- response = connection.send(method.downcase) do |request|
38
- request.url uri, params
39
- if body
40
- if mix_headers["content-type"].start_with? "application/json"
41
- request_body = body.to_json
42
- elsif mix_headers["content-type"].start_with? "application/x-www-form-urlencoded"
43
- request_body = URI.encode_www_form(body)
44
- else
45
- request_body = body
46
- end
47
- mix_headers["content-md5"] = Digest::MD5.base64digest request_body
48
- mix_headers["content-length"] = request_body.length.to_s
49
- request.body = request_body
50
- end
51
- string2sign = string_to_sign(method, uri, mix_headers, params)
52
- mix_headers[:authorization] = authorization(string2sign)
53
- mix_headers.each { |key, value| request.headers[key] = value }
54
- end
55
-
56
- return response if options.has_key? :raw_body
57
-
58
- response_content_type = response.headers["Content-Type"] || ""
59
- if response_content_type.start_with?("application/json")
60
- if response.status >= 400
61
- result = JSON.parse(response.body)
62
- raise StandardError, "code: #{response.status}, #{result['Message']} requestid: #{result['RequestId']}"
63
- end
64
- end
65
-
66
- if response_content_type.start_with?("text/xml")
67
- result = Hash.from_xml(response.body)
68
- raise ACSError, result["Error"] if result["Error"]
69
- end
70
-
71
- response
72
- end
73
-
74
- def connection(adapter = Faraday.default_adapter)
75
- Faraday.new(url: self.endpoint) { |f| f.adapter adapter }
76
- end
77
-
78
- def get(uri: "", headers: {}, params: {}, options: {})
79
- request(method: :get, uri: uri, params: params, body: {}, headers: headers, options: options)
80
- end
81
-
82
- def post(uri: "", headers: {}, params: {}, body: {}, options: {})
83
- request(method: :post, uri: uri, params: params, body: body, headers: headers, options: options)
84
- end
85
-
86
- def put(uri: "", headers: {}, params: {}, body: {}, options: {})
87
- request(method: :put, uri: uri, params: params, body: body, headers: headers, options: options)
88
- end
89
-
90
- def delete(uri: "", headers: {}, params: {}, options: {})
91
- request(method: :delete, uri: uri, params: params, body: {}, headers: headers, options: options)
92
- end
93
-
94
- def default_headers
95
- default_headers = {
96
- "accept" => "application/json",
97
- "date" => Time.now.httpdate,
98
- "host" => URI(self.endpoint).host,
99
- "x-acs-signature-nonce" => SecureRandom.hex(16),
100
- "x-acs-signature-method" => "HMAC-SHA1",
101
- "x-acs-signature-version" => "1.0",
102
- "x-acs-version" => self.api_version,
103
- "x-sdk-client" => "RUBY(#{RUBY_VERSION})", # FIXME: 如何获取Gem的名称和版本号
104
- "user-agent" => DEFAULT_UA
105
- }
106
- if self.security_token
107
- default_headers["x-acs-accesskey-id"] = self.access_key_id
108
- default_headers["x-acs-security-token"] = self.security_token
109
- end
110
- default_headers
111
- end
112
-
113
- private
114
- def string_to_sign(method, uri, headers, query = {})
115
- header_string = [
116
- method,
117
- headers["accept"],
118
- headers["content-md5"] || "",
119
- headers["content-type"] || "",
120
- headers["date"],
121
- ].join("\n")
122
- "#{header_string}\n#{canonicalized_headers(headers)}#{canonicalized_resource(uri, query)}"
123
- end
124
-
125
- def canonicalized_headers(headers)
126
- headers.keys.select { |key| key.to_s.start_with? "x-acs-" }
127
- .sort.map { |key| "#{key}:#{headers[key].strip}\n" }.join
128
- end
129
-
130
- def canonicalized_resource(uri, query_hash = {})
131
- query_string = query_hash.sort.map { |key, value| "#{key}=#{value}" }.join("&")
132
- query_string.empty? ? uri : "#{uri}?#{query_string}"
133
- end
134
-
135
- def authorization(string_to_sign)
136
- "acs #{self.access_key_id}:#{signature(string_to_sign)}"
137
- end
138
-
139
- def signature(string_to_sign)
140
- Base64.encode64(OpenSSL::HMAC.digest("sha1", self.access_key_secret, string_to_sign)).strip
141
- end
142
-
143
- def validate(config)
144
- raise ArgumentError, 'must pass "config"' unless config
145
- raise ArgumentError, 'must pass "config[:endpoint]"' unless config[:endpoint]
146
- unless config[:endpoint].start_with?("http://") || config[:endpoint].start_with?("https://")
147
- raise ArgumentError, '"config.endpoint" must starts with \'https://\' or \'http://\'.'
148
- end
149
- raise ArgumentError, 'must pass "config[:api_version]"' unless config[:api_version]
150
- raise ArgumentError, 'must pass "config[:access_key_id]"' unless config[:access_key_id]
151
- raise ArgumentError, 'must pass "config[:access_key_secret]"' unless config[:access_key_secret]
152
- end
153
-
154
- class ACSError < StandardError
155
- attr_accessor :code
156
-
157
- def initialize(error)
158
- self.code = error["Code"]
159
- message = error["Message"]
160
- host_id = error["HostId"]
161
- request_id = error["RequestId"]
162
- super("#{message} host_id: #{host_id}, request_id: #{request_id}")
163
- end
164
- end
165
- end
166
- end
167
- end
168
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "securerandom"
5
+ require "active_support/all"
6
+ require "net/http"
7
+
8
+ module Net::HTTPHeader
9
+ def capitalize(name)
10
+ name
11
+ end
12
+ private :capitalize
13
+ end
14
+
15
+ module Aliyun
16
+ module Rails
17
+ module Connector
18
+ class ROAClient
19
+ attr_accessor :endpoint, :api_version, :access_key_id,
20
+ :access_key_secret, :security_token, :hostname, :opts
21
+
22
+ def initialize(config)
23
+ validate config
24
+
25
+ self.endpoint = config[:endpoint]
26
+ self.api_version = config[:api_version]
27
+ self.access_key_id = config[:access_key_id]
28
+ self.access_key_secret = config[:access_key_secret]
29
+ self.security_token = config[:security_token]
30
+ end
31
+
32
+ def request(method:, uri:, params: {}, body: {}, headers: {}, options: {})
33
+ # :"Content-Type" => "application/json" to "content-type" => "application/json"
34
+ headers.deep_transform_keys! { |key| key.to_s.downcase }
35
+ mix_headers = default_headers.merge(headers)
36
+
37
+ response = connection.send(method.downcase) do |request|
38
+ request.url uri, params
39
+ if body
40
+ if mix_headers["content-type"].start_with? "application/json"
41
+ request_body = body.to_json
42
+ elsif mix_headers["content-type"].start_with? "application/x-www-form-urlencoded"
43
+ request_body = URI.encode_www_form(body)
44
+ else
45
+ request_body = body
46
+ end
47
+ mix_headers["content-md5"] = Digest::MD5.base64digest request_body
48
+ mix_headers["content-length"] = request_body.length.to_s
49
+ request.body = request_body
50
+ end
51
+ string2sign = string_to_sign(method, uri, mix_headers, params)
52
+ mix_headers[:authorization] = authorization(string2sign)
53
+ mix_headers.each { |key, value| request.headers[key] = value }
54
+ end
55
+
56
+ return response if options.has_key? :raw_body
57
+
58
+ response_content_type = response.headers["Content-Type"] || ""
59
+ if response_content_type.start_with?("application/json")
60
+ if response.status >= 400
61
+ result = JSON.parse(response.body)
62
+ raise StandardError, "code: #{response.status}, #{result['Message']} requestid: #{result['RequestId']}"
63
+ end
64
+ end
65
+
66
+ if response_content_type.start_with?("text/xml")
67
+ result = Hash.from_xml(response.body)
68
+ raise ACSError, result["Error"] if result["Error"]
69
+ end
70
+
71
+ response
72
+ end
73
+
74
+ def connection(adapter = Faraday.default_adapter)
75
+ Faraday.new(url: self.endpoint) { |f| f.adapter adapter }
76
+ end
77
+
78
+ def get(uri: "", headers: {}, params: {}, options: {})
79
+ request(method: :get, uri: uri, params: params, body: {}, headers: headers, options: options)
80
+ end
81
+
82
+ def post(uri: "", headers: {}, params: {}, body: {}, options: {})
83
+ request(method: :post, uri: uri, params: params, body: body, headers: headers, options: options)
84
+ end
85
+
86
+ def put(uri: "", headers: {}, params: {}, body: {}, options: {})
87
+ request(method: :put, uri: uri, params: params, body: body, headers: headers, options: options)
88
+ end
89
+
90
+ def delete(uri: "", headers: {}, params: {}, options: {})
91
+ request(method: :delete, uri: uri, params: params, body: {}, headers: headers, options: options)
92
+ end
93
+
94
+ def default_headers
95
+ default_headers = {
96
+ "accept" => "application/json",
97
+ "date" => Time.now.httpdate,
98
+ "host" => URI(self.endpoint).host,
99
+ "x-acs-signature-nonce" => SecureRandom.hex(16),
100
+ "x-acs-signature-method" => "HMAC-SHA1",
101
+ "x-acs-signature-version" => "1.0",
102
+ "x-acs-version" => self.api_version,
103
+ "x-sdk-client" => "RUBY(#{RUBY_VERSION})", # FIXME: 如何获取Gem的名称和版本号
104
+ "user-agent" => DEFAULT_UA
105
+ }
106
+ if self.security_token
107
+ default_headers["x-acs-accesskey-id"] = self.access_key_id
108
+ default_headers["x-acs-security-token"] = self.security_token
109
+ end
110
+ default_headers
111
+ end
112
+
113
+ private
114
+ def string_to_sign(method, uri, headers, query = {})
115
+ header_string = [
116
+ method,
117
+ headers["accept"],
118
+ headers["content-md5"] || "",
119
+ headers["content-type"] || "",
120
+ headers["date"],
121
+ ].join("\n")
122
+ "#{header_string}\n#{canonicalized_headers(headers)}#{canonicalized_resource(uri, query)}"
123
+ end
124
+
125
+ def canonicalized_headers(headers)
126
+ headers.keys.select { |key| key.to_s.start_with? "x-acs-" }
127
+ .sort.map { |key| "#{key}:#{headers[key].strip}\n" }.join
128
+ end
129
+
130
+ def canonicalized_resource(uri, query_hash = {})
131
+ query_string = query_hash.sort.map { |key, value| "#{key}=#{value}" }.join("&")
132
+ query_string.empty? ? uri : "#{uri}?#{query_string}"
133
+ end
134
+
135
+ def authorization(string_to_sign)
136
+ "acs #{self.access_key_id}:#{signature(string_to_sign)}"
137
+ end
138
+
139
+ def signature(string_to_sign)
140
+ Base64.encode64(OpenSSL::HMAC.digest("sha1", self.access_key_secret, string_to_sign)).strip
141
+ end
142
+
143
+ def validate(config)
144
+ raise ArgumentError, 'must pass "config"' unless config
145
+ raise ArgumentError, 'must pass "config[:endpoint]"' unless config[:endpoint]
146
+ unless config[:endpoint].start_with?("http://") || config[:endpoint].start_with?("https://")
147
+ raise ArgumentError, '"config.endpoint" must starts with \'https://\' or \'http://\'.'
148
+ end
149
+ raise ArgumentError, 'must pass "config[:api_version]"' unless config[:api_version]
150
+ raise ArgumentError, 'must pass "config[:access_key_id]"' unless config[:access_key_id]
151
+ raise ArgumentError, 'must pass "config[:access_key_secret]"' unless config[:access_key_secret]
152
+ end
153
+
154
+ class ACSError < StandardError
155
+ attr_accessor :code
156
+
157
+ def initialize(error)
158
+ self.code = error["Code"]
159
+ message = error["Message"]
160
+ host_id = error["HostId"]
161
+ request_id = error["RequestId"]
162
+ super("#{message} host_id: #{host_id}, request_id: #{request_id}")
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -1,122 +1,113 @@
1
- # frozen_string_literal: true
2
-
3
- require "set"
4
- require "openssl"
5
- require "faraday"
6
- require "erb"
7
- require "active_support/all"
8
-
9
- module Aliyun
10
- module Rails
11
- module Connector
12
- class RPCClient
13
- # 类方法接受初始化变量
14
- class << self
15
- attr_accessor :access_key_id, :access_key_secret
16
-
17
- def configure
18
- yield self
19
- end
20
- end
21
-
22
- attr_accessor :endpoint, :api_version, :access_key_id, :access_key_secret,
23
- :security_token, :codes, :opts, :verbose
24
-
25
- # 对象初始化属性
26
- def initialize(verbose = false)
27
- config = configure
28
- validate config
29
-
30
- self.endpoint = config[:endpoint]
31
- self.api_version = config[:api_version]
32
- self.access_key_id = config[:access_key_id] || RPCClient.access_key_id
33
- self.access_key_secret = config[:access_key_secret] || RPCClient.access_key_secret
34
- self.security_token = config[:security_token]
35
- self.opts = config[:opts] || {}
36
- self.verbose = verbose.instance_of?(TrueClass) && verbose
37
- self.codes = Set.new [200, "200", "OK", "Success"]
38
- self.codes.merge config[:codes] if config[:codes]
39
- end
40
-
41
- # 通用请求接口
42
- def request(action:, params: {}, opts: {})
43
- opts = self.opts.merge(opts)
44
- action = upcase_first(action) if opts[:format_action]
45
- params = format_params(params) unless opts[:format_params]
46
- defaults = default_params
47
- params = { Action: action }.merge(defaults).merge(params)
48
- method = (opts[:method] || "GET").upcase
49
- sign = "#{method}&#{encode('/')}&#{encode(params.to_query)}"
50
- secret = "#{self.access_key_secret}&"
51
- signature = Base64.encode64(OpenSSL::HMAC.digest("sha1", secret, sign)).strip
52
- params["Signature"] = signature
53
-
54
- # 转换为 query 样式
55
- query_string = params.to_query
56
-
57
- # 特殊处理 POST
58
- uri = opts[:method] == "POST" ? "/" : "/?#{query_string}"
59
-
60
- # 初始化会话
61
- response = connection.send(method.downcase, uri) do |r|
62
- if opts[:method] == "POST"
63
- r.headers["Content-Type"] = "application/x-www-form-urlencoded"
64
- r.body = query_string
65
- end
66
- r.headers["User-Agent"] = DEFAULT_UA
67
- end
68
-
69
- # 解析接口响应
70
- response_body = JSON.parse(response.body)
71
- if response_body["Code"] && !response_body["Code"].to_s.empty? && !self.codes.include?(response_body["Code"])
72
- raise StandardError, "Code: #{response_body['Code']}, Message: #{response_body['Message']}, URL: #{uri}"
73
- end
74
-
75
- response_body
76
- end
77
-
78
- private
79
- def connection(adapter = Faraday.default_adapter)
80
- Faraday.new(url: self.endpoint) { |f| f.adapter adapter }
81
- end
82
-
83
- # 设置缺省参数
84
- def default_params
85
- params = {
86
- Format: "JSON",
87
- SignatureMethod: "HMAC-SHA1",
88
- SignatureNonce: SecureRandom.hex(16),
89
- SignatureVersion: "1.0",
90
- Timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
91
- AccessKeyId: self.access_key_id,
92
- Version: self.api_version,
93
- }
94
- params[:SecurityToken] = self.security_token if self.security_token.present?
95
- params
96
- end
97
-
98
- # 消息签名需要
99
- def encode(input)
100
- ERB::Util.url_encode input
101
- end
102
-
103
- # 转换 HASH key 样式
104
- def format_params(param_hash)
105
- param_hash.keys.each { |key| param_hash[upcase_first(key.to_s).to_sym] = param_hash.delete key }
106
- param_hash
107
- end
108
-
109
- def validate(config)
110
- raise ArgumentError, 'must pass "config"' unless config
111
- raise ArgumentError, 'must pass "config[:endpoint]"' unless config[:endpoint]
112
- unless config[:endpoint].match?(/^http[s]?:/i)
113
- raise ArgumentError, '"config.endpoint" must starts with \'https://\' or \'http://\'.'
114
- end
115
- raise ArgumentError, 'must pass "config[:api_version]"' unless config[:api_version]
116
- raise ArgumentError, 'must pass "config[:access_key_id]"' unless config[:access_key_id]
117
- raise ArgumentError, 'must pass "config[:access_key_secret]"' unless config[:access_key_secret]
118
- end
119
- end
120
- end
121
- end
122
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "openssl"
5
+ require "faraday"
6
+ require "erb"
7
+ require "active_support/all"
8
+
9
+ module Aliyun
10
+ module Rails
11
+ module Connector
12
+ class RPCClient
13
+ attr_accessor :endpoint, :api_version, :access_key_id, :access_key_secret,
14
+ :security_token, :codes, :opts, :verbose
15
+
16
+ # 对象初始化属性
17
+ def initialize(config, verbose = false)
18
+ validate config
19
+
20
+ self.endpoint = config[:endpoint]
21
+ self.api_version = config[:api_version]
22
+ self.access_key_id = config[:access_key_id]
23
+ self.access_key_secret = config[:access_key_secret]
24
+ self.security_token = config[:security_token]
25
+ self.opts = config[:opts] || {}
26
+ self.verbose = verbose.instance_of?(TrueClass) && verbose
27
+ self.codes = Set.new [200, "200", "OK", "Success"]
28
+ self.codes.merge config[:codes] if config[:codes]
29
+ end
30
+
31
+ # 通用请求接口
32
+ def request(action:, params: {}, opts: {})
33
+ opts = self.opts.merge(opts)
34
+ action = action.upcase_first if opts[:format_action]
35
+ params = format_params(params) unless opts[:format_params]
36
+ defaults = default_params
37
+ params = { Action: action }.merge(defaults).merge(params)
38
+ method = (opts[:method] || "GET").upcase
39
+ sign = "#{method}&#{encode('/')}&#{encode(params.to_query)}"
40
+ secret = "#{self.access_key_secret}&"
41
+ signature = Base64.encode64(OpenSSL::HMAC.digest("sha1", secret, sign)).strip
42
+ params["Signature"] = signature
43
+
44
+ # 转换为 query 样式
45
+ query_string = params.to_query
46
+
47
+ # 特殊处理 POST
48
+ uri = opts[:method] == "POST" ? "/" : "/?#{query_string}"
49
+
50
+ # 初始化会话
51
+ response = connection.send(method.downcase, uri) do |r|
52
+ if opts[:method] == "POST"
53
+ r.headers["Content-Type"] = "application/x-www-form-urlencoded"
54
+ r.body = query_string
55
+ end
56
+ r.headers["User-Agent"] = DEFAULT_UA
57
+ end
58
+
59
+ # 解析接口响应
60
+ response_body = JSON.parse(response.body)
61
+ if response_body["Code"] && !response_body["Code"].to_s.empty? && !self.codes.include?(response_body["Code"])
62
+ raise StandardError, "Code: #{response_body['Code']}, Message: #{response_body['Message']}, URL: #{uri}"
63
+ end
64
+
65
+ response_body
66
+ end
67
+
68
+ private
69
+ def connection(adapter = Faraday.default_adapter)
70
+ Faraday.new(url: self.endpoint) { |f| f.adapter adapter }
71
+ end
72
+
73
+ # 设置缺省参数
74
+ def default_params
75
+ params = {
76
+ Format: "JSON",
77
+ SignatureMethod: "HMAC-SHA1",
78
+ SignatureNonce: SecureRandom.hex(8),
79
+ SignatureVersion: "1.0",
80
+ Timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
81
+ AccessKeyId: self.access_key_id,
82
+ Version: self.api_version,
83
+ }
84
+ params[:SecurityToken] = self.security_token if self.security_token.present?
85
+ params
86
+ end
87
+
88
+ # 消息签名需要
89
+ def encode(input)
90
+ ERB::Util.url_encode input
91
+ end
92
+
93
+ # 转换 HASH key 样式
94
+ def format_params(param_hash)
95
+ param_hash.keys.each { |key| param_hash[(key.to_s.upcase_first).to_sym] = param_hash.delete key }
96
+ param_hash
97
+ end
98
+
99
+ def validate(config)
100
+ config.with_indifferent_access
101
+ raise ArgumentError, 'must pass "config"' unless config
102
+ raise ArgumentError, 'must pass "config[:endpoint]"' unless config[:endpoint]
103
+ unless config[:endpoint].match?(/^http[s]?:/i)
104
+ raise ArgumentError, '"config.endpoint" must starts with \'https://\' or \'http://\'.'
105
+ end
106
+ raise ArgumentError, 'must pass "config[:api_version]"' unless config[:api_version]
107
+ raise ArgumentError, 'must pass "config[:access_key_id]"' unless config[:access_key_id]
108
+ raise ArgumentError, 'must pass "config[:access_key_secret]"' unless config[:access_key_secret]
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,28 +1,27 @@
1
- # frozen_string_literal: true
2
-
3
- module Aliyun
4
- module Rails
5
- class Dysms < Aliyun::Rails::Connector::RPCClient
6
- # 本产品(Dysmsapi/2017-05-25)的OpenAPI采用RPC签名风格,签名细节参见签名机制说明。
7
- # 我们已经为开发者封装了常见编程语言的SDK,开发者可通过下载SDK直接调用本产品OpenAPI而无需关心技术细节。
8
- def initialize(config, verbose = nil)
9
- config["endpoint"] = "http://dysmsapi.aliyuncs.com"
10
- config["api_version"] = "2017-05-25"
11
-
12
- super
13
- end
14
-
15
- # 发送短信,发送前要申请短信签名和短信模板,并确保签名和模板已审核通过。
16
- def send_sms(phone_numbers, template_code, template_param, sign_name = "")
17
- params = {
18
- PhoneNumbers: phone_numbers,
19
- SignName: sign_name,
20
- TemplateCode: template_code,
21
- TemplateParam: template_param.to_json
22
- }
23
- opts = { method: "POST", timeout: 15000 }
24
- request(action: "SendSms", params: params, opts: opts)
25
- end
26
- end
27
- end
28
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Aliyun
4
+ module Rails
5
+ class Dysms < Aliyun::Rails::Connector::RPCClient
6
+ # 本产品(Dysmsapi/2017-05-25)的OpenAPI采用RPC签名风格,签名细节参见签名机制说明。
7
+ # 我们已经为开发者封装了常见编程语言的SDK,开发者可通过下载SDK直接调用本产品OpenAPI而无需关心技术细节。
8
+ def initialize(config, verbose = nil)
9
+ config[:endpoint] = "http://dysmsapi.aliyuncs.com"
10
+ config[:api_version] = "2017-05-25"
11
+ super(config, verbose)
12
+ end
13
+
14
+ # 发送短信,发送前要申请短信签名和短信模板,并确保签名和模板已审核通过。
15
+ def send_sms(phone_numbers, template_code, template_param, sign_name = "")
16
+ params = {
17
+ PhoneNumbers: phone_numbers,
18
+ SignName: sign_name,
19
+ TemplateCode: template_code,
20
+ TemplateParam: template_param.to_json
21
+ }
22
+ opts = { method: "POST", timeout: 15000 }
23
+ request(action: "SendSms", params: params, opts: opts)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,28 +1,27 @@
1
- # frozen_string_literal: true
2
-
3
- module Aliyun
4
- module Rails
5
- class Dysms < Aliyun::Rails::Connector::RPCClient
6
- # 本产品(Dyvmsapi/2017-05-25)的OpenAPI采用RPC签名风格,签名细节参见签名机制说明。
7
- # 我们已经为开发者封装了常见编程语言的SDK,开发者可通过下载SDK直接调用本产品OpenAPI而无需关心技术细节。
8
- def initialize(config, verbose = nil)
9
- config["endpoint"] = "http://dyvmsapi.aliyuncs.com"
10
- config["api_version"] = "2017-05-25"
11
-
12
- super
13
- end
14
-
15
- # 调用SingleCallByTts接口向指定号码发送语音验证码和带参数变量的语音通知
16
- def single_call_by_tts(called_show_number, called_number, tts_code, tts_param)
17
- params = {
18
- CalledShowNumber: called_show_number,
19
- CalledNumber: called_number,
20
- TtsCode: tts_code,
21
- TtsParam: tts_param.to_json
22
- }
23
- opts = { method: "POST", timeout: 15000 }
24
- request(action: "SendSms", params: params, opts: opts)
25
- end
26
- end
27
- end
28
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Aliyun
4
+ module Rails
5
+ class Dysms < Aliyun::Rails::Connector::RPCClient
6
+ # 本产品(Dyvmsapi/2017-05-25)的OpenAPI采用RPC签名风格,签名细节参见签名机制说明。
7
+ # 我们已经为开发者封装了常见编程语言的SDK,开发者可通过下载SDK直接调用本产品OpenAPI而无需关心技术细节。
8
+ def initialize(config, verbose = nil)
9
+ config[:endpoint] = "http://dyvmsapi.aliyuncs.com"
10
+ config[:api_version] = "2017-05-25"
11
+ super(config, verbose)
12
+ end
13
+
14
+ # 调用SingleCallByTts接口向指定号码发送语音验证码和带参数变量的语音通知
15
+ def single_call_by_tts(called_show_number, called_number, tts_code, tts_param)
16
+ params = {
17
+ CalledShowNumber: called_show_number,
18
+ CalledNumber: called_number,
19
+ TtsCode: tts_code,
20
+ TtsParam: tts_param.to_json
21
+ }
22
+ opts = { method: "POST", timeout: 15000 }
23
+ request(action: "SendSms", params: params, opts: opts)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,9 +1,9 @@
1
- # frozen_string_literal: true
2
-
3
- module Aliyun
4
- module Rails
5
- VERSION = "0.1.7"
6
- DEFAULT_UA = "AlibabaCloud (#{Gem::Platform.local.os}; " +
7
- "#{Gem::Platform.local.cpu}) Ruby/#{RUBY_VERSION} Core/#{VERSION}"
8
- end
9
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Aliyun
4
+ module Rails
5
+ VERSION = "0.1.10"
6
+ DEFAULT_UA = "AlibabaCloud (#{Gem::Platform.local.os}; " +
7
+ "#{Gem::Platform.local.cpu}) Ruby/#{RUBY_VERSION} Core/#{VERSION}"
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rails/version"
4
+ require_relative "rails/connector/roa_client"
5
+ require_relative "rails/connector/rpc_client"
6
+ require_relative "rails/dysms"
7
+ require_relative "rails/dyvms"
8
+
9
+ module Aliyun
10
+ module Rails
11
+ class Error < StandardError; end
12
+
13
+ # class << self
14
+ # def config(&block)
15
+ # RPCClient.init_params(&block)
16
+ # end
17
+ # end
18
+
19
+ # Your code goes here...
20
+ end
21
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliyun-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - WENWU.YAN
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-31 00:00:00.000000000 Z
11
+ date: 2022-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -47,7 +47,7 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - README.md
49
49
  - Rakefile
50
- - lib/aliyun-rails.rb
50
+ - lib/aliyun/rails.rb
51
51
  - lib/aliyun/rails/connector/roa_client.rb
52
52
  - lib/aliyun/rails/connector/rpc_client.rb
53
53
  - lib/aliyun/rails/dysms.rb
@@ -60,7 +60,7 @@ metadata:
60
60
  homepage_uri: https://github.com/ciscolive/aliyun-rails
61
61
  source_code_uri: https://github.com/ciscolive/aliyun-rails
62
62
  changelog_uri: https://github.com/ciscolive/aliyun-rails/blob/main/README.md
63
- post_install_message:
63
+ post_install_message:
64
64
  rdoc_options: []
65
65
  require_paths:
66
66
  - lib
@@ -75,8 +75,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 3.3.3
79
- signing_key:
78
+ rubygems_version: 3.3.7
79
+ signing_key:
80
80
  specification_version: 4
81
81
  summary: 非阿里云官方SDK,本GEM主要实现RAILS项目轻松调用 ** aliyun ** 相关接口
82
82
  test_files: []
data/lib/aliyun-rails.rb DELETED
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "aliyun/rails/version"
4
- require "aliyun/rails/connector/roa_client"
5
- require "aliyun/rails/connector/rpc_client"
6
- require "aliyun/rails/dysms"
7
- require "aliyun/rails/dyvms"
8
-
9
- module Aliyun
10
- module Rails
11
- class Error < StandardError; end
12
-
13
- # 模块方法接受代码块初始化参数
14
- class << self
15
- def config(&block)
16
- RPCClient.configure(&block)
17
- end
18
- end
19
-
20
- # Your code goes here...
21
- end
22
- end