aliyun-sdk 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: