azure-signature 0.1.0 → 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.
- checksums.yaml +4 -4
- data/CHANGES +5 -0
- data/README +0 -4
- data/azure-signature.gemspec +1 -1
- data/lib/azure-signature.rb +1 -0
- data/lib/azure/signature.rb +134 -12
- data/test/test_signature.rb +14 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88506245b215c239f08a1c85f3970c1ae0b0aa61
|
4
|
+
data.tar.gz: 9ebc3da7b6ccd44d3004e44dd3e4d49fa8a71a00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fdb546f7a4af2496b7e902aedcdd4ee5b0d6bb069f9eef1b99bd75731158de052fb90374d7d3dd10e5d70a9a66e19b003a9701213b5bec48cf80522e1ec48da
|
7
|
+
data.tar.gz: b76a9ba3cfa945e8932dba42ec3d00854972fe867b9bc5990d9c58be461f631ce2384db1d0b333108b1f4ce2055d2f0b6e4f7f66a0cee0516bdb33e2baa64669
|
data/CHANGES
CHANGED
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.
|
data/azure-signature.gemspec
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'azure/signature'
|
data/lib/azure/signature.rb
CHANGED
@@ -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.
|
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
|
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
|
-
"
|
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
|
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] }
|
data/test/test_signature.rb
CHANGED
@@ -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.
|
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.
|
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-
|
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
|