aliyun-sdk 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +28 -4
  4. data/examples/aliyun/oss/bucket.rb +1 -1
  5. data/examples/aliyun/oss/object.rb +1 -1
  6. data/examples/aliyun/oss/resumable_download.rb +1 -1
  7. data/examples/aliyun/oss/resumable_upload.rb +1 -1
  8. data/examples/aliyun/oss/streaming.rb +1 -1
  9. data/examples/aliyun/oss/using_sts.rb +48 -0
  10. data/examples/aliyun/sts/assume_role.rb +59 -0
  11. data/lib/aliyun/common.rb +6 -0
  12. data/lib/aliyun/common/exception.rb +18 -0
  13. data/lib/aliyun/{oss → common}/logging.rb +3 -3
  14. data/lib/aliyun/common/struct.rb +56 -0
  15. data/lib/aliyun/oss.rb +1 -2
  16. data/lib/aliyun/oss/bucket.rb +1 -1
  17. data/lib/aliyun/oss/client.rb +2 -2
  18. data/lib/aliyun/oss/config.rb +3 -2
  19. data/lib/aliyun/oss/download.rb +3 -0
  20. data/lib/aliyun/oss/exception.rb +2 -14
  21. data/lib/aliyun/oss/http.rb +3 -1
  22. data/lib/aliyun/oss/multipart.rb +2 -4
  23. data/lib/aliyun/oss/object.rb +1 -1
  24. data/lib/aliyun/oss/protocol.rb +1 -1
  25. data/lib/aliyun/oss/struct.rb +5 -54
  26. data/lib/aliyun/oss/upload.rb +3 -0
  27. data/lib/aliyun/oss/util.rb +1 -1
  28. data/lib/aliyun/sts.rb +9 -0
  29. data/lib/aliyun/sts/client.rb +38 -0
  30. data/lib/aliyun/sts/config.rb +21 -0
  31. data/lib/aliyun/sts/exception.rb +53 -0
  32. data/lib/aliyun/sts/protocol.rb +130 -0
  33. data/lib/aliyun/sts/struct.rb +64 -0
  34. data/lib/aliyun/sts/util.rb +48 -0
  35. data/lib/aliyun/{oss/version.rb → version.rb} +1 -3
  36. data/spec/aliyun/oss/client/client_spec.rb +21 -1
  37. data/spec/aliyun/sts/client_spec.rb +150 -0
  38. data/spec/aliyun/sts/util_spec.rb +39 -0
  39. metadata +21 -4
@@ -0,0 +1,48 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'time'
4
+ require 'cgi'
5
+ require 'base64'
6
+ require 'openssl'
7
+ require 'digest/md5'
8
+
9
+ module Aliyun
10
+ module STS
11
+ ##
12
+ # Util functions to help generate formatted Date, signatures,
13
+ # etc.
14
+ #
15
+ module Util
16
+
17
+ class << self
18
+
19
+ include Common::Logging
20
+
21
+ # Calculate request signatures
22
+ def get_signature(verb, params, key)
23
+ logger.debug("Sign, verb: #{verb}, params: #{params}")
24
+
25
+ cano_query = params.sort.map {
26
+ |k, v| [CGI.escape(k), CGI.escape(v)].join('=') }.join('&')
27
+
28
+ string_to_sign =
29
+ verb + '&' + CGI.escape('/') + '&' + CGI.escape(cano_query)
30
+
31
+ logger.debug("String to sign: #{string_to_sign}")
32
+
33
+ Util.sign(key + '&', string_to_sign)
34
+ end
35
+
36
+ # Sign a string using HMAC and BASE64
37
+ # @param [String] key the secret key
38
+ # @param [String] string_to_sign the string to sign
39
+ # @return [String] the signature
40
+ def sign(key, string_to_sign)
41
+ Base64.strict_encode64(
42
+ OpenSSL::HMAC.digest('sha1', key, string_to_sign))
43
+ end
44
+
45
+ end # self
46
+ end # Util
47
+ end # STS
48
+ end # Aliyun
@@ -1,9 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  module Aliyun
4
- module OSS
5
4
 
6
- VERSION = "0.1.8"
5
+ VERSION = "0.2.0"
7
6
 
8
- end # OSS
9
7
  end # Aliyun
@@ -14,12 +14,14 @@ module Aliyun
14
14
  endpoint = 'oss-cn-hangzhou.aliyuncs.com'
15
15
  client = Client.new(
16
16
  :endpoint => endpoint,
17
- :access_key_id => 'xxx ', :access_key_secret => ' yyy ')
17
+ :access_key_id => 'xxx ', :access_key_secret => ' yyy ',
18
+ :sts_token => 'sts-token')
18
19
 
19
20
  config = client.instance_variable_get('@config')
20
21
  expect(config.endpoint.to_s).to eq("http://#{endpoint}")
21
22
  expect(config.access_key_id).to eq('xxx')
22
23
  expect(config.access_key_secret).to eq('yyy')
24
+ expect(config.sts_token).to eq('sts-token')
23
25
  end
24
26
 
25
27
  it "should not set Authorization with anonymous client" do
@@ -37,6 +39,24 @@ module Aliyun
37
39
  .with{ |req| not req.headers.has_key?('Authorization') }
38
40
  end
39
41
 
42
+ it "should set STS header" do
43
+ endpoint = 'oss-cn-hangzhou.aliyuncs.com'
44
+ bucket = 'rubysdk-bucket'
45
+ object = 'rubysdk-object'
46
+ client = Client.new(
47
+ :endpoint => endpoint,
48
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
49
+ :sts_token => 'sts-token')
50
+
51
+ stub_request(:get, "#{bucket}.#{endpoint}/#{object}")
52
+
53
+ client.get_bucket(bucket).get_object(object) {}
54
+
55
+ expect(WebMock)
56
+ .to have_requested(:get, "#{bucket}.#{endpoint}/#{object}")
57
+ .with{ |req| not req.headers.has_key?('x-oss-security-token') }
58
+ end
59
+
40
60
  it "should construct different client" do
41
61
  bucket = 'rubysdk-bucket'
42
62
  object = 'rubysdk-object'
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+ require 'yaml'
3
+ require 'nokogiri'
4
+
5
+ module Aliyun
6
+ module STS
7
+
8
+ describe Client do
9
+
10
+ context "construct" do
11
+ it "should setup a/k" do
12
+ client = Client.new(
13
+ :access_key_id => 'xxx', :access_key_secret => 'yyy')
14
+
15
+ config = client.instance_variable_get('@config')
16
+ expect(config.access_key_id).to eq('xxx')
17
+ expect(config.access_key_secret).to eq('yyy')
18
+ end
19
+ end
20
+
21
+ def mock_sts(id, key, token, expiration)
22
+ Nokogiri::XML::Builder.new do |xml|
23
+ xml.AssumeRoleResponse {
24
+ xml.RequestId '0000'
25
+ xml.AssumedRoleUser {
26
+ xml.arn 'arn-001'
27
+ xml.AssumedRoleUserId 'id-001'
28
+ }
29
+ xml.Credentials {
30
+ xml.AccessKeyId id
31
+ xml.AccessKeySecret key
32
+ xml.SecurityToken token
33
+ xml.Expiration expiration.utc.iso8601
34
+ }
35
+ }
36
+ end.to_xml
37
+ end
38
+
39
+ def mock_error(code, message)
40
+ Nokogiri::XML::Builder.new do |xml|
41
+ xml.Error {
42
+ xml.Code code
43
+ xml.Message message
44
+ xml.RequestId '0000'
45
+ }
46
+ end.to_xml
47
+ end
48
+
49
+ def err(msg, reqid = '0000')
50
+ "#{msg} RequestId: #{reqid}"
51
+ end
52
+
53
+ before :all do
54
+ @url = 'https://sts.aliyuncs.com'
55
+ @client = Client.new(access_key_id: 'xxx', access_key_secret: 'yyy')
56
+ end
57
+
58
+ context "assume role" do
59
+ it "should assume role" do
60
+ expiration = Time.parse(Time.now.utc.iso8601)
61
+
62
+ stub_request(:post, @url)
63
+ .to_return(:body => mock_sts(
64
+ 'sts_id', 'sts_key', 'sts_token', expiration))
65
+
66
+ token = @client.assume_role('role-1', 'app-1')
67
+
68
+ rbody = nil
69
+ expect(WebMock).to have_requested(:post, @url)
70
+ .with { |req| rbody = req.body }
71
+ params = rbody.split('&').reduce({}) { |h, i|
72
+ v = i.split('=')
73
+ h.merge({v[0] => v[1]})
74
+ }
75
+ expect(params['Action']).to eq('AssumeRole')
76
+ expect(params['RoleArn']).to eq('role-1')
77
+ expect(params['RoleSessionName']).to eq('app-1')
78
+ expect(params['DurationSeconds']).to eq('3600')
79
+ expect(params['Format']).to eq('XML')
80
+ expect(params['Version']).to eq('2015-04-01')
81
+ expect(params['AccessKeyId']).to eq('xxx')
82
+ expect(params.key?('Signature')).to be true
83
+ expect(params.key?('SignatureNonce')).to be true
84
+ expect(params['SignatureMethod']).to eq('HMAC-SHA1')
85
+
86
+ expect(token.access_key_id).to eq('sts_id')
87
+ expect(token.access_key_secret).to eq('sts_key')
88
+ expect(token.security_token).to eq('sts_token')
89
+ expect(token.expiration).to eq(expiration)
90
+ end
91
+
92
+ it "should raise error" do
93
+ code = "InvalidParameter"
94
+ message = "Bla bla bla."
95
+
96
+ stub_request(:post, @url)
97
+ .to_return(:status => 400,
98
+ :body => mock_error(code, message))
99
+
100
+
101
+ expect {
102
+ @client.assume_role('role-1', 'app-1')
103
+ }.to raise_error(ServerError, err(message))
104
+
105
+ end
106
+
107
+ it "should set policy and duration" do
108
+ expiration = Time.parse(Time.now.utc.iso8601)
109
+
110
+ stub_request(:post, @url)
111
+ .to_return(:body => mock_sts(
112
+ 'sts_id', 'sts_key', 'sts_token', expiration))
113
+
114
+ policy = Policy.new
115
+ policy.allow(
116
+ ['oss:Get*', 'oss:PutObject'],
117
+ ['acs:oss:*:*:bucket', 'acs::oss:*:*:bucket/*'])
118
+ duration = 300
119
+ token = @client.assume_role('role-1', 'app-1', policy, duration)
120
+
121
+ rbody = nil
122
+ expect(WebMock).to have_requested(:post, @url)
123
+ .with { |req| rbody = req.body }
124
+ params = rbody.split('&').reduce({}) { |h, i|
125
+ v = i.split('=')
126
+ h.merge({v[0] => CGI.unescape(v[1])})
127
+ }
128
+ expect(params['Action']).to eq('AssumeRole')
129
+ expect(params['RoleArn']).to eq('role-1')
130
+ expect(params['RoleSessionName']).to eq('app-1')
131
+ expect(params['DurationSeconds']).to eq('300')
132
+ expect(params['Format']).to eq('XML')
133
+ expect(params['Version']).to eq('2015-04-01')
134
+ expect(params['AccessKeyId']).to eq('xxx')
135
+ expect(params.key?('Signature')).to be true
136
+ expect(params.key?('SignatureNonce')).to be true
137
+ expect(params['SignatureMethod']).to eq('HMAC-SHA1')
138
+ expect(params['Policy']).to eq(policy.serialize)
139
+
140
+ expect(token.access_key_id).to eq('sts_id')
141
+ expect(token.access_key_secret).to eq('sts_key')
142
+ expect(token.security_token).to eq('sts_token')
143
+ expect(token.expiration).to eq(expiration)
144
+ end
145
+ end
146
+
147
+ end # Client
148
+
149
+ end # OSS
150
+ end # Aliyun
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+ require 'yaml'
5
+ require 'nokogiri'
6
+
7
+ module Aliyun
8
+ module STS
9
+
10
+ describe Util do
11
+
12
+ it "should get correct signature" do
13
+ key = 'helloworld'
14
+ ts = '2015-12-07T07:18:41Z'
15
+
16
+ params = {
17
+ 'Action' => 'AssumeRole',
18
+ 'RoleArn' => 'role-1',
19
+ 'RoleSessionName' => 'app-1',
20
+ 'DurationSeconds' => '300',
21
+ 'Format' => 'XML',
22
+ 'Version' => '2015-04-01',
23
+ 'AccessKeyId' => 'xxx',
24
+ 'SignatureMethod' => 'HMAC-SHA1',
25
+ 'SignatureVersion' => '1.0',
26
+ 'SignatureNonce' => '3.14159',
27
+ 'Timestamp' => ts
28
+ }
29
+
30
+ signature = Util.get_signature('POST', params, key)
31
+ expect(signature).to eq("92ta30QopCT4YTbRCaWtS31kyeg=")
32
+
33
+ signature = Util.get_signature('GET', params, key)
34
+ expect(signature).to eq("nvMmnOSxGrfK+1zf0oFR5RB2M7k=")
35
+ end
36
+
37
+ end # Util
38
+ end # OSS
39
+ end # Aliyun
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliyun-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tianlong Wu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-03 00:00:00.000000000 Z
11
+ date: 2015-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -124,6 +124,12 @@ files:
124
124
  - examples/aliyun/oss/resumable_download.rb
125
125
  - examples/aliyun/oss/resumable_upload.rb
126
126
  - examples/aliyun/oss/streaming.rb
127
+ - examples/aliyun/oss/using_sts.rb
128
+ - examples/aliyun/sts/assume_role.rb
129
+ - lib/aliyun/common.rb
130
+ - lib/aliyun/common/exception.rb
131
+ - lib/aliyun/common/logging.rb
132
+ - lib/aliyun/common/struct.rb
127
133
  - lib/aliyun/oss.rb
128
134
  - lib/aliyun/oss/bucket.rb
129
135
  - lib/aliyun/oss/client.rb
@@ -132,14 +138,20 @@ files:
132
138
  - lib/aliyun/oss/exception.rb
133
139
  - lib/aliyun/oss/http.rb
134
140
  - lib/aliyun/oss/iterator.rb
135
- - lib/aliyun/oss/logging.rb
136
141
  - lib/aliyun/oss/multipart.rb
137
142
  - lib/aliyun/oss/object.rb
138
143
  - lib/aliyun/oss/protocol.rb
139
144
  - lib/aliyun/oss/struct.rb
140
145
  - lib/aliyun/oss/upload.rb
141
146
  - lib/aliyun/oss/util.rb
142
- - lib/aliyun/oss/version.rb
147
+ - lib/aliyun/sts.rb
148
+ - lib/aliyun/sts/client.rb
149
+ - lib/aliyun/sts/config.rb
150
+ - lib/aliyun/sts/exception.rb
151
+ - lib/aliyun/sts/protocol.rb
152
+ - lib/aliyun/sts/struct.rb
153
+ - lib/aliyun/sts/util.rb
154
+ - lib/aliyun/version.rb
143
155
  - spec/aliyun/oss/bucket_spec.rb
144
156
  - spec/aliyun/oss/client/bucket_spec.rb
145
157
  - spec/aliyun/oss/client/client_spec.rb
@@ -150,6 +162,8 @@ files:
150
162
  - spec/aliyun/oss/object_spec.rb
151
163
  - spec/aliyun/oss/service_spec.rb
152
164
  - spec/aliyun/oss/util_spec.rb
165
+ - spec/aliyun/sts/client_spec.rb
166
+ - spec/aliyun/sts/util_spec.rb
153
167
  - tests/test_content_type.rb
154
168
  - tests/test_encoding.rb
155
169
  - tests/test_large_file.rb
@@ -191,9 +205,12 @@ test_files:
191
205
  - spec/aliyun/oss/object_spec.rb
192
206
  - spec/aliyun/oss/service_spec.rb
193
207
  - spec/aliyun/oss/util_spec.rb
208
+ - spec/aliyun/sts/client_spec.rb
209
+ - spec/aliyun/sts/util_spec.rb
194
210
  - tests/test_content_type.rb
195
211
  - tests/test_encoding.rb
196
212
  - tests/test_large_file.rb
197
213
  - tests/test_multipart.rb
198
214
  - tests/test_object_key.rb
199
215
  - tests/test_resumable.rb
216
+ has_rdoc: