stormmq-client 0.0.6 → 0.0.7
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.
- data/CHANGELOG +8 -0
- data/bin/stormmq-amqp-echo-test +2 -5
- data/bin/stormmq-create-system +1 -4
- data/bin/stormmq-delete-system +1 -4
- data/bin/stormmq-describe-company +1 -4
- data/bin/stormmq-describe-system +1 -4
- data/bin/stormmq-get-amqpuser-password +1 -4
- data/bin/stormmq-list-amqpusers +1 -4
- data/bin/stormmq-list-apis +1 -4
- data/bin/stormmq-list-bindings +1 -4
- data/bin/stormmq-list-clusters +1 -4
- data/bin/stormmq-list-companies +1 -4
- data/bin/stormmq-list-exchanges +1 -4
- data/bin/stormmq-list-queues +1 -4
- data/bin/stormmq-list-systems +1 -4
- data/bin/stormmq-url-signer +1 -4
- data/lib/stormmq/application.rb +10 -0
- data/lib/stormmq/secret_keys.rb +24 -14
- data/lib/stormmq/url.rb +3 -2
- data/lib/stormmq/version.rb +1 -1
- data/spec/secret-keys.json +1 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/stormmq/amqp_spec.rb +29 -1
- data/spec/stormmq/base64_extensions_spec.rb +28 -0
- data/spec/stormmq/secret_keys_spec.rb +51 -2
- data/spec/stormmq/url_spec.rb +70 -1
- data/spec/stormmq/utils_spec.rb +26 -1
- metadata +7 -4
data/CHANGELOG
CHANGED
data/bin/stormmq-amqp-echo-test
CHANGED
@@ -93,7 +93,7 @@ class StormMQ::Application::AMQPEchoTest < StormMQ::Application
|
|
93
93
|
msg = queue.pop[:payload]
|
94
94
|
|
95
95
|
if msg == test_message
|
96
|
-
puts "\
|
96
|
+
puts "\nSUCCESS: received test message '#{msg}'"
|
97
97
|
retval = 0
|
98
98
|
else
|
99
99
|
puts "\nFAILURE: expected test message, but got '#{msg}' instead"
|
@@ -190,10 +190,7 @@ NOTES
|
|
190
190
|
|
191
191
|
For a default system, you'll just need your userName.
|
192
192
|
|
193
|
-
|
194
|
-
|
195
|
-
Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
|
196
|
-
All rights reserved.
|
193
|
+
#{_man_copyright}
|
197
194
|
|
198
195
|
EOM
|
199
196
|
end
|
data/bin/stormmq-create-system
CHANGED
data/bin/stormmq-delete-system
CHANGED
data/bin/stormmq-describe-system
CHANGED
data/bin/stormmq-list-amqpusers
CHANGED
data/bin/stormmq-list-apis
CHANGED
data/bin/stormmq-list-bindings
CHANGED
data/bin/stormmq-list-clusters
CHANGED
data/bin/stormmq-list-companies
CHANGED
data/bin/stormmq-list-exchanges
CHANGED
data/bin/stormmq-list-queues
CHANGED
data/bin/stormmq-list-systems
CHANGED
data/bin/stormmq-url-signer
CHANGED
data/lib/stormmq/application.rb
CHANGED
data/lib/stormmq/secret_keys.rb
CHANGED
@@ -11,20 +11,23 @@ require 'json'
|
|
11
11
|
require 'base64'
|
12
12
|
require 'stormmq/base64_extensions'
|
13
13
|
require 'stormmq/errors'
|
14
|
+
require 'stormmq/utils'
|
14
15
|
|
15
16
|
module StormMQ
|
16
17
|
|
17
|
-
SECRET_KEYS_SEARCH_PATH = [
|
18
|
+
SECRET_KEYS_SEARCH_PATH = [
|
19
|
+
File.join(ENV['HOME'], '.stormmq'),
|
20
|
+
File.join('/', 'etc', 'stormmq')
|
21
|
+
]
|
22
|
+
|
18
23
|
SECRET_KEYS_FILENAME = 'secret-keys.json'
|
19
24
|
|
20
25
|
class SecretKeys
|
21
26
|
include Singleton
|
22
|
-
attr_writer :key_cache
|
23
27
|
|
24
|
-
# Returns the
|
28
|
+
# Returns the secret key for the given user name from the secret keys file.
|
25
29
|
def key_for(user)
|
26
|
-
raise Error::UserNotProvidedError, "user cannot be
|
27
|
-
raise Error::UserNotProvidedError, "user cannot be empty." if user.empty?
|
30
|
+
raise Error::UserNotProvidedError, "user cannot be blank." if user.blank?
|
28
31
|
keys[user] || (raise Error::SecretKeyNotFoundError, "a secret key for user '#{user}' could not be found in the secret key file.", caller)
|
29
32
|
end
|
30
33
|
|
@@ -33,21 +36,16 @@ module StormMQ
|
|
33
36
|
keys.keys
|
34
37
|
end
|
35
38
|
|
36
|
-
private
|
37
|
-
|
38
|
-
# Return a hash of keys stored in the secret keys file.
|
39
|
-
def keys
|
40
|
-
@secret_keys_cache ||= load_secret_keys
|
41
|
-
end
|
42
|
-
|
43
39
|
# Load the keys from the secret keys file <tt>keyfile</tt>. Walks the locations specified in
|
44
40
|
# <tt>search_path</tt> in order of preference.
|
45
41
|
def load_secret_keys(search_path=SECRET_KEYS_SEARCH_PATH, keyfile=SECRET_KEYS_FILENAME)
|
46
|
-
full_paths = search_path.map{|p| File.expand_path(
|
42
|
+
full_paths = search_path.map{|p| File.expand_path(File.join(p,keyfile))}
|
47
43
|
full_paths.each do |full_path|
|
48
44
|
begin
|
49
|
-
return SecretKeys.secret_keys_hash_from_json(IO.read(full_path))
|
45
|
+
return @secret_keys_cache = SecretKeys.secret_keys_hash_from_json(IO.read(full_path))
|
50
46
|
rescue
|
47
|
+
# A dummy statement so that this branch is picked up by rcov
|
48
|
+
dummy = true
|
51
49
|
end
|
52
50
|
end
|
53
51
|
raise Error::LoadSecretKeysError,
|
@@ -55,6 +53,18 @@ module StormMQ
|
|
55
53
|
caller
|
56
54
|
end
|
57
55
|
|
56
|
+
def forget_keys
|
57
|
+
@secret_keys_cache = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Return a hash of keys stored in the secret keys file.
|
63
|
+
def keys
|
64
|
+
@secret_keys_cache ||= load_secret_keys
|
65
|
+
end
|
66
|
+
|
67
|
+
|
58
68
|
def self.key_for(*args)
|
59
69
|
self.instance.key_for(*args)
|
60
70
|
end
|
data/lib/stormmq/url.rb
CHANGED
@@ -11,7 +11,7 @@ require 'cgi'
|
|
11
11
|
require 'hmac'
|
12
12
|
require 'hmac-sha2'
|
13
13
|
require 'base64'
|
14
|
-
|
14
|
+
require 'stormmq/base64_extensions'
|
15
15
|
require 'stormmq/errors'
|
16
16
|
|
17
17
|
module StormMQ
|
@@ -80,7 +80,7 @@ module StormMQ
|
|
80
80
|
|
81
81
|
def to_h
|
82
82
|
components = URI.split(@url.to_s)
|
83
|
-
{
|
83
|
+
component_hash = {
|
84
84
|
:scheme => components[0],
|
85
85
|
:userinfo => components[1],
|
86
86
|
:host => components[2],
|
@@ -91,6 +91,7 @@ module StormMQ
|
|
91
91
|
:query => components[7],
|
92
92
|
:fragment => components[8]
|
93
93
|
}.reject {|k,v| v.nil?}
|
94
|
+
component_hash
|
94
95
|
end
|
95
96
|
|
96
97
|
def self.escape(string)
|
data/lib/stormmq/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
{"test":"qQC5BNDK5rMOxLC0G2hkOoW5Z7P-c4aO2pok5r0V0Ac"}
|
data/spec/spec_helper.rb
ADDED
data/spec/stormmq/amqp_spec.rb
CHANGED
@@ -6,9 +6,25 @@
|
|
6
6
|
# for terms of use and redistribution.
|
7
7
|
#++
|
8
8
|
|
9
|
-
require File.dirname(__FILE__)
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
10
|
+
require 'stormmq/amqp'
|
10
11
|
|
11
12
|
describe StormMQ::AMQPClient do
|
13
|
+
|
14
|
+
it "adds default StormMQ client options to an option hash" do
|
15
|
+
options = {
|
16
|
+
:company => 'a_company',
|
17
|
+
:system => 'a_system',
|
18
|
+
:environment => 'an_environment'
|
19
|
+
}
|
20
|
+
new_options = StormMQ::AMQPClient.add_stormmq_options(options)
|
21
|
+
|
22
|
+
new_options[:host].should == 'amqp.stormmq.com'
|
23
|
+
new_options[:port].should == 443
|
24
|
+
new_options[:vhost].should == '/a_company/a_system/an_environment'
|
25
|
+
new_options[:ssl].should be_true
|
26
|
+
end
|
27
|
+
|
12
28
|
it "constructs the virtual host string from the StormMQ specific options in the connect option hash" do
|
13
29
|
options = {
|
14
30
|
:company => 'a_company',
|
@@ -17,5 +33,17 @@ describe StormMQ::AMQPClient do
|
|
17
33
|
}
|
18
34
|
StormMQ::AMQPClient.vhost_from_options(options).should == '/a_company/a_system/an_environment'
|
19
35
|
end
|
36
|
+
|
37
|
+
it "returns an instance of the Bunny AMQP client" do
|
38
|
+
StormMQ::AMQPClient.instance.should be_instance_of(Bunny::Client)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "run block in scope of Bunny AMQP client instance" do
|
42
|
+
block = Proc.new { }
|
43
|
+
options = StormMQ::AMQPClient.add_stormmq_options({})
|
44
|
+
Bunny.should_receive(:run).with(options, &block)
|
45
|
+
StormMQ::AMQPClient.run({}, &block)
|
46
|
+
end
|
47
|
+
|
20
48
|
end
|
21
49
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010, Tony Byrne & StormMQ Ltd.
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Please refer to the LICENSE file that accompanies this source
|
6
|
+
# for terms of use and redistribution.
|
7
|
+
#++
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
10
|
+
require 'base64'
|
11
|
+
require 'stormmq/base64_extensions'
|
12
|
+
|
13
|
+
describe Base64 do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@unsafe_encoded = "jv7N7mnDnl4FWgayyxzN695zYJ4SC/OTnXel9SPIP/2XV6d7+3vTyV4v0zQWAfvNwZm/bB/h6P+X+FUUdcvJig=="
|
17
|
+
@safe_encoded = "jv7N7mnDnl4FWgayyxzN695zYJ4SC_OTnXel9SPIP_2XV6d7-3vTyV4v0zQWAfvNwZm_bB_h6P-X-FUUdcvJig=="
|
18
|
+
end
|
19
|
+
|
20
|
+
it "implements a URL safe base64 decode" do
|
21
|
+
Base64.encode64(Base64.urlsafe_decode64(@safe_encoded)).gsub(/\n/,'').should == @unsafe_encoded
|
22
|
+
end
|
23
|
+
|
24
|
+
it "implements a URL safe base64 encode" do
|
25
|
+
Base64.urlsafe_encode64(Base64.decode64(@unsafe_encoded)).gsub(/\n/,'').should == @safe_encoded
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -6,9 +6,11 @@
|
|
6
6
|
# for terms of use and redistribution.
|
7
7
|
#++
|
8
8
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
9
10
|
require 'base64'
|
10
|
-
require
|
11
|
-
require
|
11
|
+
require 'stormmq/secret_keys'
|
12
|
+
require 'stormmq/base64_extensions'
|
13
|
+
require 'stormmq/errors'
|
12
14
|
|
13
15
|
describe StormMQ::SecretKeys do
|
14
16
|
|
@@ -22,4 +24,51 @@ describe StormMQ::SecretKeys do
|
|
22
24
|
|
23
25
|
end
|
24
26
|
|
27
|
+
describe "loading of keys from keyfile" do
|
28
|
+
|
29
|
+
it "should throw an error when keyfile does not exist" do
|
30
|
+
keystore = StormMQ::SecretKeys.instance
|
31
|
+
lambda { keystore.load_secret_keys('/non-existing-path') }.should raise_error(StormMQ::Error::LoadSecretKeysError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should load keys from a file" do
|
35
|
+
keystore = StormMQ::SecretKeys.instance
|
36
|
+
lambda { keystore.load_secret_keys(File.join('spec')) }.should_not raise_error(StormMQ::Error::LoadSecretKeysError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should handle an error while reading the keyfile" do
|
40
|
+
IO.should_receive(:read).and_raise "bang! The universe has ended."
|
41
|
+
keystore = StormMQ::SecretKeys.instance
|
42
|
+
lambda { keystore.load_secret_keys(File.join('spec')) }.should raise_error(StormMQ::Error::LoadSecretKeysError)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "key and user retrieval" do
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
@keystore = StormMQ::SecretKeys.instance
|
51
|
+
@keystore.forget_keys
|
52
|
+
@keystore.load_secret_keys(File.join('spec'))
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return a list of users found in the key file" do
|
56
|
+
@keystore.users.should == ['test']
|
57
|
+
StormMQ::SecretKeys.key_for('test').should_not be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should retrieve the key for a named user" do
|
61
|
+
@keystore.key_for('test').should_not be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should retrieve the key for a named user when using the class method" do
|
65
|
+
StormMQ::SecretKeys.key_for('test').should_not be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should raise an error when a key for a named user is not present in the keyfile" do
|
69
|
+
lambda { @keystore.key_for('wibble') }.should raise_error(StormMQ::Error::SecretKeyNotFoundError)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
25
74
|
end
|
data/spec/stormmq/url_spec.rb
CHANGED
@@ -6,7 +6,8 @@
|
|
6
6
|
# for terms of use and redistribution.
|
7
7
|
#++
|
8
8
|
|
9
|
-
require File.dirname(__FILE__)
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
10
|
+
require 'stormmq/url'
|
10
11
|
|
11
12
|
describe StormMQ::URL do
|
12
13
|
|
@@ -126,4 +127,72 @@ describe StormMQ::URL do
|
|
126
127
|
|
127
128
|
end
|
128
129
|
|
130
|
+
describe "valid?" do
|
131
|
+
|
132
|
+
it "a valid URL" do
|
133
|
+
StormMQ::URL.new("http://www.byrnehq.com").valid?.should be_true
|
134
|
+
end
|
135
|
+
|
136
|
+
it "an invalid URL" do
|
137
|
+
lambda { StormMQ::URL.new("random://www") }.should raise_error(StormMQ::Error::InvalidURLError)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "an invalid URI as detected by URI.parse" do
|
141
|
+
URI.should_receive(:parse).and_raise URI::InvalidURIError
|
142
|
+
lambda { StormMQ::URL.new({:host => 'www.byrnehq.com'}) }.should raise_error(StormMQ::Error::InvalidURLError)
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "to_h" do
|
148
|
+
|
149
|
+
before(:each) do
|
150
|
+
@hash = StormMQ::URL.new('http://www.stormmq.com:81/path?query=1').to_h
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should extract the scheme" do
|
154
|
+
@hash[:scheme].should == 'http'
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should extract the host" do
|
158
|
+
@hash[:host].should == 'www.stormmq.com'
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should extract the port" do
|
162
|
+
@hash[:port].should == '81'
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should extract the path" do
|
166
|
+
@hash[:path].should == '/path'
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should extract the query" do
|
170
|
+
@hash[:query].should == 'query=1'
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should not contain a fragment" do
|
174
|
+
@hash[:fragment].should be_nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should not contain an opaque" do
|
178
|
+
@hash[:opaque].should be_nil
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should not contain a registry" do
|
182
|
+
@hash[:registry].should be_nil
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "canonicalise and sign" do
|
188
|
+
|
189
|
+
it "should canonicalise and sign a URL (in one step)" do
|
190
|
+
base64key = "d60bfe079c88f2c78310131d9bb419214ec3badb0bdfccb20a1c568f380426c5"
|
191
|
+
key = Base64::decode64(base64key)
|
192
|
+
StormMQ::URL.new('http://api.stormmq.com/').canonicalise_and_sign('test', base64key).to_s.should ==
|
193
|
+
'http://api.stormmq.com:80/?signature=qQC5BNDK5rMOxLC0G2hkOoW5Z7P-c4aO2pok5r0V0Ac%3D&user=test&version=0'
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
129
198
|
end
|
data/spec/stormmq/utils_spec.rb
CHANGED
@@ -6,8 +6,33 @@
|
|
6
6
|
# for terms of use and redistribution.
|
7
7
|
#++
|
8
8
|
|
9
|
-
require File.dirname(__FILE__)
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
10
|
+
require 'stormmq/utils'
|
10
11
|
|
11
12
|
describe StormMQ::Utils do
|
12
13
|
|
14
|
+
describe NilClass, 'blank?' do
|
15
|
+
|
16
|
+
it "should extend NilClass to add a 'blank?' method" do
|
17
|
+
nil.blank?.should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe String, 'blank?' do
|
23
|
+
|
24
|
+
it "a string with non space characters is not blank" do
|
25
|
+
'not blank'.blank?.should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "an empty string is blank" do
|
29
|
+
''.blank?.should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "a string containing only space is blank" do
|
33
|
+
' '.blank?.should be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
13
38
|
end
|
metadata
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stormmq-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 7
|
10
|
+
version: 0.0.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tony Byrne
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain:
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-18 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -209,7 +209,10 @@ files:
|
|
209
209
|
- bin/stormmq-list-queues
|
210
210
|
- bin/stormmq-list-systems
|
211
211
|
- bin/stormmq-url-signer
|
212
|
+
- spec/secret-keys.json
|
213
|
+
- spec/spec_helper.rb
|
212
214
|
- spec/stormmq/amqp_spec.rb
|
215
|
+
- spec/stormmq/base64_extensions_spec.rb
|
213
216
|
- spec/stormmq/secret_keys_spec.rb
|
214
217
|
- spec/stormmq/url_spec.rb
|
215
218
|
- spec/stormmq/utils_spec.rb
|