azure-signature 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: a3e4bf37dea120788f3e4b8b1f1f4ba2cac0da67
4
- data.tar.gz: 804102d0275a2c4a7bb01dfda9636a85e32529dc
3
+ metadata.gz: 88506245b215c239f08a1c85f3970c1ae0b0aa61
4
+ data.tar.gz: 9ebc3da7b6ccd44d3004e44dd3e4d49fa8a71a00
5
5
  SHA512:
6
- metadata.gz: 3593818f612766c12b61de678db9f4766866855e17f936dd88e2fa3367cf7ba33b49557dc4f6b9925e7607bb4ae04e565d3053f4828a6f7e2814b0e79d16688d
7
- data.tar.gz: ad442a9a682c1d1a921a37bd5c1baf073b1555c00bcd6df310d0d44236e4b351e703b3d057c7a19361fe21d7e59398ba3f792fa374f9baf8363d2d7f5fa5dc67
6
+ metadata.gz: 5fdb546f7a4af2496b7e902aedcdd4ee5b0d6bb069f9eef1b99bd75731158de052fb90374d7d3dd10e5d70a9a66e19b003a9701213b5bec48cf80522e1ec48da
7
+ data.tar.gz: b76a9ba3cfa945e8932dba42ec3d00854972fe867b9bc5990d9c58be461f631ce2384db1d0b333108b1f4ce2055d2f0b6e4f7f66a0cee0516bdb33e2baa64669
data/CHANGES CHANGED
@@ -1,2 +1,7 @@
1
+ = 0.2.0 - 13-Oct-2015
2
+ * Added support for other types of signatures (blobs, queues, files).
3
+ * The :auth_string argument no longer returns the word "Authorization".
4
+ * Added an azure-signature file for convenience.
5
+
1
6
  = 0.1.0 - 25-Sep-2015
2
7
  * Initial release
data/README CHANGED
@@ -21,10 +21,6 @@
21
21
  # Or pass some options
22
22
  p sig.signature(:table, :auth_string => true, :date => some_date, :verb => 'PUT')
23
23
 
24
- = Caveats
25
- For the first release only table signatures are supported (because that's
26
- what I happened to need). I'll add blob, file and queue in the future.
27
-
28
24
  = Acknowledgements
29
25
  I borrowed the code to canonicalize resources and headers from the
30
26
  azure-sdk-for-ruby project.
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'azure-signature'
5
- gem.version = '0.1.0'
5
+ gem.version = '0.2.0'
6
6
  gem.author = 'Daniel J. Berger'
7
7
  gem.license = 'Apache 2.0'
8
8
  gem.email = 'djberg96@gmail.com'
@@ -0,0 +1 @@
1
+ require_relative 'azure/signature'
@@ -9,7 +9,7 @@ module Azure
9
9
  # The Signature class encapsulates an canonicalized resource string.
10
10
  class Signature
11
11
  # The version of the azure-signature library.
12
- VERSION = '0.1.0'
12
+ VERSION = '0.2.0'
13
13
 
14
14
  # The resource (URL) passed to the constructor.
15
15
  attr_reader :resource
@@ -29,6 +29,8 @@ module Azure
29
29
  alias url resource
30
30
  alias canonical_url canonical_resource
31
31
 
32
+ attr_reader :canonical_headers
33
+
32
34
  # Creates and returns an Azure::Signature object taking a +resource+ (URL)
33
35
  # as an argument and a storage account key. The +resource+ will typically
34
36
  # be an Azure storage account endpoint.
@@ -60,42 +62,162 @@ module Azure
60
62
  verb = options[:verb] || 'GET'
61
63
  date = options[:date] || Time.now.httpdate
62
64
  auth_string = options[:auth_string] || false
63
- content_md5 = options[:content_md5]
64
- content_type = options[:content_type]
65
+ content_md5 = options[:content_md5] || options['Content-MD5']
66
+ content_type = options[:content_type] || options['Content-Type']
65
67
 
66
68
  unless ['SharedKey', 'SharedKeyLight'].include?(auth_type)
67
69
  raise ArgumentError, "auth type must be SharedKey or SharedKeyLight"
68
70
  end
69
71
 
70
72
  if auth_type == 'SharedKey'
71
- body = [verb, content_md5, content_type, date, canonical_resource].join("\n")
73
+ body = [verb, content_md5, content_type, date, canonical_resource].join("\n").encode('UTF-8')
74
+ else
75
+ body = [date, canonical_resource].join("\n").encode('UTF-8')
76
+ end
77
+
78
+ if auth_string
79
+ "#{auth_type} #{account_name}:" + sign(body)
72
80
  else
73
- body = [date, canonical_resource].join("\n")
81
+ sign(body)
82
+ end
83
+ end
84
+
85
+ # Generate a signature for use with the blob service. Use the +headers+
86
+ # hash to pass optional information. The following additional keys are
87
+ # supported:
88
+ #
89
+ # - :auth_type. Either 'SharedKey' (the default) or 'SharedKeyLight'.
90
+ # - :verb. The http verb used for SharedKey auth. The default is 'GET'.
91
+ # - :x_ms_date. The x-ms-date used. The default is Time.now.httpdate.
92
+ # - :x_ms_version. The x-ms-version used. The default is '2015-02-21'.
93
+ # - :auth_string. If true, prepends the auth_type + account name to the
94
+ # result and returns a string. The default is false.
95
+ #
96
+ # The other headers of potential significance are below. Note that you
97
+ # are not required to set any of them.
98
+ #
99
+ # - 'Content-Encoding'
100
+ # - 'Content-Language'
101
+ # - 'Content-Length'
102
+ # - 'Content-MD5'
103
+ # - 'Content-Type'
104
+ # - 'Date'
105
+ # - 'If-Modified-Since'
106
+ # - 'If-Match'
107
+ # - 'If-None-Match'
108
+ # - 'If-Unmodified-Since'
109
+ # - 'Range'
110
+ #
111
+ # The result is a digest string that you can use as an authorization header
112
+ # for future http requests to (presumably) Azure storage endpoints.
113
+ #
114
+ # Example:
115
+ #
116
+ # require 'azure-signature'
117
+ # require 'rest-client'
118
+ #
119
+ # url = "https://yourstuff.blob.core.windows.net/system?restype=container&comp=list&include=snapshots"
120
+ # key = "xyzabcwhatever"
121
+ #
122
+ # sig = Signature.new(url, key)
123
+ # date = Time.now.httpdate
124
+ # vers = '2015-02-21'
125
+ #
126
+ # headers = {
127
+ # 'x-ms-date' => date,
128
+ # 'x-ms-version' => vers,
129
+ # 'Accept' => 'application/xml',
130
+ # :auth_string => true,
131
+ # }
132
+ #
133
+ # sig = sig.blob_signature(headers)
134
+ # headers['Authorization'] = sig
135
+ #
136
+ # req = RestClient::Request.new(
137
+ # :method => 'get',
138
+ # :url => url,
139
+ # :headers => headers
140
+ # )
141
+ #
142
+ # response = req.execute
143
+ # p response.body
144
+ #
145
+ def blob_signature(headers = {})
146
+ auth_string = headers.delete(:auth_string) || false
147
+ auth_type = headers.delete(:auth_type) || 'SharedKey'
148
+ verb = headers.delete(:verb) || 'GET'
149
+
150
+ unless ['SharedKey', 'SharedKeyLight'].include?(auth_type)
151
+ raise ArgumentError, "auth type must be SharedKey or SharedKeyLight"
74
152
  end
75
153
 
154
+ headers['x-ms-date'] ||= headers.delete(:x_ms_date) || Time.now.httpdate
155
+ headers['x-ms-version'] ||= headers.delete(:x_ms_version) || '2015-02-21'
156
+
157
+ if auth_type == 'SharedKeyLight'
158
+ headers['Date'] ||= headers['x-ms-date'] || headers[:date] || Time.now.httpdate
159
+ end
160
+
161
+ body = generate_string(verb, headers, auth_type).encode('UTF-8')
162
+
76
163
  if auth_string
77
- "Authorization: #{auth_type} #{account_name}:" + sign(body)
164
+ "SharedKey #{account_name}:" + sign(body)
78
165
  else
79
166
  sign(body)
80
167
  end
81
168
  end
82
169
 
170
+ alias file_signature blob_signature
171
+ alias queue_signature blob_signature
172
+
83
173
  # Generic wrapper method for getting a signature, where +type+ can be
84
174
  # :table, :blob, :queue, or :file.
85
175
  #
86
- # At the moment only :table is supported.
87
- #--
88
- # TODO: Add support for other types.
89
- #
90
176
  def signature(type, args = {})
91
177
  case type.to_s.downcase
92
178
  when 'table'
93
179
  table_signature(args)
180
+ when 'blob', 'file', 'queue'
181
+ blob_signature(args)
182
+ else
183
+ raise ArgumentError, "invalid signature type '#{type}'"
94
184
  end
95
185
  end
96
186
 
97
187
  private
98
188
 
189
+ def generate_string(verb, headers, auth_type)
190
+ canonical_headers = canonicalize_headers(headers)
191
+
192
+ if auth_type == 'SharedKeyLight'
193
+ [
194
+ verb.to_s.upcase,
195
+ headers['Content-MD5'],
196
+ headers['Content-Type'],
197
+ headers['Date'],
198
+ canonical_headers,
199
+ canonical_resource
200
+ ].join("\n")
201
+ else
202
+ [
203
+ verb.to_s.upcase,
204
+ headers['Content-Encoding'],
205
+ headers['Content-Language'],
206
+ headers['Content-Length'],
207
+ headers['Content-MD5'],
208
+ headers['Content-Type'],
209
+ headers['Date'],
210
+ headers['If-Modified-Since'],
211
+ headers['If-Match'],
212
+ headers['If-None-Match'],
213
+ headers['If-Unmodified-Since'],
214
+ headers['Range'],
215
+ canonical_headers,
216
+ canonical_resource,
217
+ ].join("\n")
218
+ end
219
+ end
220
+
99
221
  # Generate a canonical URL from an endpoint.
100
222
  #--
101
223
  # Borrowed from azure-sdk-for-ruby. I had my own, but this was nicer.
@@ -112,8 +234,8 @@ module Azure
112
234
  #--
113
235
  # Borrowed from azure-sdk-for-ruby.
114
236
  #
115
- def canonicalized_headers(headers)
116
- headers = headers.map { |k,v| [k.to_s.downcase, v] }
237
+ def canonicalize_headers(headers)
238
+ headers = headers.map { |k,v| [k.to_s.gsub('_', '-').downcase, v] }
117
239
  headers.select! { |k,v| k =~ /^x-ms-/ }
118
240
  headers.sort_by! { |k,v| k }
119
241
  headers.map! { |k,v| '%s:%s' % [k, v] }
@@ -9,7 +9,7 @@ class TC_Azure_Signature < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  test "version constant is set to expected value" do
12
- assert_equal("0.1.0", Azure::Signature::VERSION)
12
+ assert_equal("0.2.0", Azure::Signature::VERSION)
13
13
  end
14
14
 
15
15
  test "key method basic functionality" do
@@ -82,6 +82,19 @@ class TC_Azure_Signature < Test::Unit::TestCase
82
82
  assert_raise(ArgumentError){ Azure::Signature.new('http://foo/bar') }
83
83
  end
84
84
 
85
+ test "table_signature basic functionality" do
86
+ assert_respond_to(@sig, :table_signature)
87
+ end
88
+
89
+ test "blob_signature basic functionality" do
90
+ assert_respond_to(@sig, :blob_signature)
91
+ end
92
+
93
+ test "file_signature and queue_signature are aliases for blob_signature" do
94
+ assert_alias_method(@sig, :blob_signature, :file_signature)
95
+ assert_alias_method(@sig, :blob_signature, :queue_signature)
96
+ end
97
+
85
98
  def teardown
86
99
  @key = nil
87
100
  @url = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: azure-signature
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-25 00:00:00.000000000 Z
11
+ date: 2015-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -41,6 +41,7 @@ files:
41
41
  - README
42
42
  - Rakefile
43
43
  - azure-signature.gemspec
44
+ - lib/azure-signature.rb
44
45
  - lib/azure/signature.rb
45
46
  - test/test_signature.rb
46
47
  homepage: http://github.com/djberg96/azure-signature
@@ -63,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
64
  version: '0'
64
65
  requirements: []
65
66
  rubyforge_project:
66
- rubygems_version: 2.4.5
67
+ rubygems_version: 2.4.5.1
67
68
  signing_key:
68
69
  specification_version: 4
69
70
  summary: Generate authentication signatures for Azure