stormmq-client 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|