vines 0.4.5 → 0.4.6
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/Gemfile +3 -0
- data/README.md +48 -0
- data/Rakefile +6 -58
- data/bin/vines +12 -2
- data/conf/certs/ca-bundle.crt +568 -39
- data/conf/config.rb +9 -42
- data/lib/vines.rb +1 -8
- data/lib/vines/command/cert.rb +4 -4
- data/lib/vines/command/init.rb +3 -3
- data/lib/vines/config.rb +9 -0
- data/lib/vines/kit.rb +2 -7
- data/lib/vines/storage/local.rb +50 -17
- data/lib/vines/store.rb +6 -4
- data/lib/vines/stream.rb +1 -1
- data/lib/vines/stream/http/session.rb +0 -0
- data/lib/vines/stream/http/sessions.rb +0 -0
- data/lib/vines/stream/parser.rb +3 -2
- data/lib/vines/token_bucket.rb +19 -10
- data/lib/vines/version.rb +1 -1
- data/test/cluster/publisher_test.rb +45 -33
- data/test/cluster/sessions_test.rb +32 -39
- data/test/cluster/subscriber_test.rb +93 -78
- data/test/config/host_test.rb +2 -4
- data/test/config/pubsub_test.rb +132 -126
- data/test/config_test.rb +2 -4
- data/test/contact_test.rb +80 -66
- data/test/error_test.rb +54 -55
- data/test/jid_test.rb +1 -2
- data/test/kit_test.rb +22 -17
- data/test/router_test.rb +187 -146
- data/test/stanza/iq/disco_info_test.rb +59 -59
- data/test/stanza/iq/disco_items_test.rb +36 -34
- data/test/stanza/iq/private_storage_test.rb +138 -143
- data/test/stanza/iq/roster_test.rb +198 -175
- data/test/stanza/iq/session_test.rb +17 -18
- data/test/stanza/iq/vcard_test.rb +117 -116
- data/test/stanza/iq/version_test.rb +47 -46
- data/test/stanza/iq_test.rb +53 -49
- data/test/stanza/message_test.rb +92 -89
- data/test/stanza/presence/probe_test.rb +2 -5
- data/test/stanza/presence/subscribe_test.rb +67 -54
- data/test/stanza/pubsub/create_test.rb +86 -108
- data/test/stanza/pubsub/delete_test.rb +141 -114
- data/test/stanza/pubsub/publish_test.rb +256 -320
- data/test/stanza/pubsub/subscribe_test.rb +169 -150
- data/test/stanza/pubsub/unsubscribe_test.rb +111 -142
- data/test/stanza_test.rb +61 -54
- data/test/storage/ldap_test.rb +1 -2
- data/test/storage/local_test.rb +3 -5
- data/test/storage/null_test.rb +3 -4
- data/test/storage/storage_tests.rb +1 -3
- data/test/storage_test.rb +1 -2
- data/test/store_test.rb +1 -2
- data/test/stream/client/auth_test.rb +61 -63
- data/test/stream/client/ready_test.rb +7 -8
- data/test/stream/client/session_test.rb +19 -18
- data/test/stream/component/handshake_test.rb +40 -37
- data/test/stream/component/ready_test.rb +76 -61
- data/test/stream/component/start_test.rb +7 -8
- data/test/stream/http/auth_test.rb +3 -4
- data/test/stream/http/ready_test.rb +52 -60
- data/test/stream/http/request_test.rb +1 -3
- data/test/stream/http/sessions_test.rb +2 -3
- data/test/stream/http/start_test.rb +3 -4
- data/test/stream/parser_test.rb +3 -4
- data/test/stream/sasl_test.rb +105 -86
- data/test/stream/server/auth_test.rb +40 -36
- data/test/stream/server/outbound/auth_test.rb +3 -4
- data/test/stream/server/ready_test.rb +51 -51
- data/test/test_helper.rb +42 -0
- data/test/token_bucket_test.rb +38 -18
- data/test/user_test.rb +79 -49
- data/vines.gemspec +33 -0
- data/web/chat/javascripts/app.js +1 -1
- data/web/lib/coffeescripts/layout.coffee +1 -1
- data/web/lib/javascripts/base.js +10 -10
- data/web/lib/javascripts/jquery.js +4 -4
- metadata +31 -128
- data/README +0 -35
- data/lib/vines/storage/couchdb.rb +0 -129
- data/lib/vines/storage/mongodb.rb +0 -132
- data/lib/vines/storage/redis.rb +0 -127
- data/lib/vines/storage/sql.rb +0 -220
- data/test/rake_test_loader.rb +0 -17
- data/test/storage/couchdb_test.rb +0 -107
- data/test/storage/mock_mongo.rb +0 -40
- data/test/storage/mongodb_test.rb +0 -81
- data/test/storage/redis_test.rb +0 -51
- data/test/storage/sql_test.rb +0 -62
data/test/stanza_test.rb
CHANGED
@@ -1,78 +1,85 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@stream = MiniTest::Mock.new
|
13
|
-
@config = Vines::Config.new do
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
describe Vines::Stanza do
|
6
|
+
subject { Vines::Stanza::Message.new(xml, stream) }
|
7
|
+
let(:alice) { Vines::JID.new('alice@wonderland.lit/tea') }
|
8
|
+
let(:romeo) { Vines::JID.new('romeo@verona.lit/balcony') }
|
9
|
+
let(:stream) { MiniTest::Mock.new }
|
10
|
+
let(:config) do
|
11
|
+
Vines::Config.new do
|
14
12
|
host 'wonderland.lit' do
|
15
13
|
storage(:fs) { dir Dir.tmpdir }
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
stanza = Vines::Stanza::Message.new(node, @stream)
|
23
|
-
assert_nil stanza.validate_to
|
24
|
-
assert_nil stanza.validate_from
|
25
|
-
assert @stream.verify
|
26
|
-
end
|
18
|
+
describe 'when stanza contains no addresses' do
|
19
|
+
let(:xml) { node(%Q{<message>hello!</message>}) }
|
27
20
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
assert @stream.verify
|
21
|
+
it 'validates them as nil' do
|
22
|
+
subject.validate_to.must_be_nil
|
23
|
+
subject.validate_from.must_be_nil
|
24
|
+
stream.verify
|
25
|
+
end
|
34
26
|
end
|
35
27
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
describe 'when stanza contains valid addresses' do
|
29
|
+
let(:xml) { node(%Q{<message from="#{alice}" to="#{romeo}">hello!</message>}) }
|
30
|
+
|
31
|
+
it 'validates and returns JID objects' do
|
32
|
+
subject.validate_to.must_equal romeo
|
33
|
+
subject.validate_from.must_equal alice
|
34
|
+
stream.verify
|
35
|
+
end
|
42
36
|
end
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
38
|
+
describe 'when stanza contains invalid addresses' do
|
39
|
+
let(:xml) { node(%Q{<message from="a lice@wonderland.lit" to="romeo@v erona.lit">hello!</message>}) }
|
40
|
+
|
41
|
+
it 'raises a jid-malformed stanza error' do
|
42
|
+
-> { subject.validate_to }.must_raise Vines::StanzaErrors::JidMalformed
|
43
|
+
-> { subject.validate_from }.must_raise Vines::StanzaErrors::JidMalformed
|
44
|
+
stream.verify
|
45
|
+
end
|
48
46
|
end
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
describe 'when receiving a non-routable stanza type' do
|
49
|
+
let(:xml) { node('<auth/>') }
|
50
|
+
|
51
|
+
it 'handles locally rather than routing' do
|
52
|
+
subject.local?.must_equal true
|
53
|
+
stream.verify
|
54
|
+
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
describe 'when stanza is missing a to address' do
|
58
|
+
let(:xml) { node(%Q{<message>hello!</message>}) }
|
59
|
+
|
60
|
+
it 'handles locally rather than routing' do
|
61
|
+
subject.local?.must_equal true
|
62
|
+
stream.verify
|
63
|
+
end
|
63
64
|
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
describe 'when stanza is addressed to a local jid' do
|
67
|
+
let(:xml) { node(%Q{<message to="#{alice}">hello!</message>}) }
|
68
|
+
|
69
|
+
it 'handles locally rather than routing' do
|
70
|
+
stream.expect :config, config
|
71
|
+
subject.local?.must_equal true
|
72
|
+
stream.verify
|
73
|
+
end
|
71
74
|
end
|
72
75
|
|
73
|
-
|
76
|
+
describe 'when stanza is addressed to a remote jid' do
|
77
|
+
let(:xml) { node(%Q{<message to="#{romeo}">hello!</message>}) }
|
74
78
|
|
75
|
-
|
76
|
-
|
79
|
+
it 'is not considered a local stanza' do
|
80
|
+
stream.expect :config, config
|
81
|
+
subject.local?.must_equal false
|
82
|
+
stream.verify
|
83
|
+
end
|
77
84
|
end
|
78
85
|
end
|
data/test/storage/ldap_test.rb
CHANGED
data/test/storage/local_test.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'storage_tests'
|
4
|
-
require '
|
5
|
-
require 'vines'
|
6
|
-
require 'minitest/autorun'
|
4
|
+
require 'test_helper'
|
7
5
|
|
8
|
-
|
6
|
+
describe Vines::Storage::Local do
|
9
7
|
include StorageTests
|
10
8
|
|
11
9
|
DIR = Dir.mktmpdir
|
@@ -23,7 +21,7 @@ class LocalTest < MiniTest::Unit::TestCase
|
|
23
21
|
:bcrypt => "#{DIR}/user/bcrypt_password@wonderland.lit",
|
24
22
|
:full => "#{DIR}/user/full@wonderland.lit",
|
25
23
|
:vcard => "#{DIR}/vcard/full@wonderland.lit",
|
26
|
-
:fragment => "#{DIR}/fragment/full@wonderland.lit-#{FRAGMENT_ID}"
|
24
|
+
:fragment => "#{DIR}/fragment/full@wonderland.lit-#{StorageTests::FRAGMENT_ID}"
|
27
25
|
}
|
28
26
|
File.open(files[:empty], 'w') {|f| f.write('') }
|
29
27
|
File.open(files[:no_pass], 'w') {|f| f.write('foo: bar') }
|
data/test/storage/null_test.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
describe Vines::Storage::Null do
|
6
|
+
before do
|
8
7
|
@storage = Vines::Storage::Null.new
|
9
8
|
@user = Vines::User.new(jid: 'alice@wonderland.lit')
|
10
9
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'ext/nokogiri'
|
5
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
6
4
|
|
7
5
|
# Mixin methods for storage implementation test classes. The behavioral
|
8
6
|
# tests are the same regardless of implementation so share those methods
|
data/test/storage_test.rb
CHANGED
data/test/store_test.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
5
4
|
|
6
5
|
describe Vines::Stream::Client::Auth do
|
7
6
|
# disable logging for tests
|
@@ -27,113 +26,112 @@ describe Vines::Stream::Client::Auth do
|
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
@state = Vines::Stream::Client::Auth.new(@stream)
|
33
|
-
end
|
29
|
+
subject { Vines::Stream::Client::Auth.new(stream) }
|
30
|
+
let(:stream) { MiniTest::Mock.new }
|
34
31
|
|
35
32
|
describe 'error handling' do
|
36
33
|
it 'rejects invalid element' do
|
37
34
|
node = node('<bogus/>')
|
38
|
-
|
35
|
+
-> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized
|
39
36
|
end
|
40
37
|
|
41
38
|
it 'rejects invalid element in sasl namespace' do
|
42
39
|
node = node(%Q{<bogus xmlns="#{Vines::NAMESPACES[:sasl]}"/>})
|
43
|
-
|
40
|
+
-> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized
|
44
41
|
end
|
45
42
|
|
46
43
|
it 'rejects auth elements missing sasl namespace' do
|
47
44
|
node = node('<auth/>')
|
48
|
-
|
45
|
+
-> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized
|
49
46
|
end
|
50
47
|
|
51
48
|
it 'rejects auth element with invalid namespace' do
|
52
49
|
node = node('<auth xmlns="bogus"/>')
|
53
|
-
|
50
|
+
-> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized
|
54
51
|
end
|
55
52
|
|
56
53
|
it 'rejects valid auth element missing mechanism' do
|
57
|
-
|
58
|
-
|
54
|
+
stream.expect :error, nil, [Vines::SaslErrors::InvalidMechanism]
|
55
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
59
56
|
node = node(%Q{<auth xmlns="#{Vines::NAMESPACES[:sasl]}">tokens</auth>})
|
60
|
-
|
61
|
-
|
57
|
+
subject.node(node)
|
58
|
+
stream.verify
|
62
59
|
end
|
63
60
|
|
64
61
|
it 'rejects valid auth element with invalid mechanism' do
|
65
|
-
|
66
|
-
|
62
|
+
stream.expect :error, nil, [Vines::SaslErrors::InvalidMechanism]
|
63
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
67
64
|
node = node(%Q{<auth xmlns="#{Vines::NAMESPACES[:sasl]}" mechanism="bogus">tokens</auth>})
|
68
|
-
|
69
|
-
|
65
|
+
subject.node(node)
|
66
|
+
stream.verify
|
70
67
|
end
|
71
68
|
end
|
72
69
|
|
73
70
|
describe 'plain auth' do
|
74
71
|
it 'rejects valid mechanism missing base64 text' do
|
75
|
-
|
76
|
-
node =
|
77
|
-
|
78
|
-
|
72
|
+
stream.expect :error, nil, [Vines::SaslErrors::MalformedRequest]
|
73
|
+
node = plain('')
|
74
|
+
subject.node(node)
|
75
|
+
stream.verify
|
79
76
|
end
|
80
77
|
|
81
78
|
it 'rejects invalid base64 text' do
|
82
|
-
|
83
|
-
|
84
|
-
node =
|
85
|
-
|
86
|
-
|
79
|
+
stream.expect :error, nil, [Vines::SaslErrors::IncorrectEncoding]
|
80
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
81
|
+
node = plain('tokens')
|
82
|
+
subject.node(node)
|
83
|
+
stream.verify
|
87
84
|
end
|
88
85
|
|
89
86
|
it 'rejects invalid password' do
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
node =
|
95
|
-
|
96
|
-
|
87
|
+
stream.expect :storage, MockStorage.new
|
88
|
+
stream.expect :domain, 'wonderland.lit'
|
89
|
+
stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized]
|
90
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
91
|
+
node = plain(Base64.strict_encode64("\x00alice\x00bogus"))
|
92
|
+
subject.node(node)
|
93
|
+
stream.verify
|
97
94
|
end
|
98
95
|
|
99
96
|
it 'passes with valid password' do
|
100
97
|
user = Vines::User.new(jid: 'alice@wonderland.lit')
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
node =
|
109
|
-
|
110
|
-
|
98
|
+
stream.expect :reset, nil
|
99
|
+
stream.expect :domain, 'wonderland.lit'
|
100
|
+
stream.expect :storage, MockStorage.new
|
101
|
+
stream.expect :user=, nil, [user]
|
102
|
+
stream.expect :write, nil, [%Q{<success xmlns="#{Vines::NAMESPACES[:sasl]}"/>}]
|
103
|
+
stream.expect :advance, nil, [Vines::Stream::Client::BindRestart]
|
104
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
105
|
+
node = plain(Base64.strict_encode64("\x00alice\x00secr3t"))
|
106
|
+
subject.node(node)
|
107
|
+
stream.verify
|
111
108
|
end
|
112
109
|
|
113
110
|
it 'raises policy-violation after max auth attempts is reached' do
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
111
|
+
stream.expect :domain, 'wonderland.lit'
|
112
|
+
stream.expect :storage, MockStorage.new
|
113
|
+
node = -> { plain(Base64.strict_encode64("\x00alice\x00bogus")) }
|
114
|
+
|
115
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
116
|
+
stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized]
|
117
|
+
subject.node(node.call)
|
118
|
+
stream.verify
|
119
|
+
|
120
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
121
|
+
stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized]
|
122
|
+
subject.node(node.call)
|
123
|
+
stream.verify
|
124
|
+
|
125
|
+
stream.expect :authentication_mechanisms, ['PLAIN']
|
126
|
+
stream.expect :error, nil, [Vines::StreamErrors::PolicyViolation]
|
127
|
+
subject.node(node.call)
|
128
|
+
stream.verify
|
131
129
|
end
|
132
130
|
end
|
133
131
|
|
134
132
|
private
|
135
133
|
|
136
|
-
def
|
137
|
-
|
134
|
+
def plain(authzid)
|
135
|
+
node(%Q{<auth xmlns="#{Vines::NAMESPACES[:sasl]}" mechanism="PLAIN">#{authzid}</auth>})
|
138
136
|
end
|
139
137
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
5
4
|
|
6
|
-
|
5
|
+
describe Vines::Stream::Client::Ready do
|
7
6
|
STANZAS = []
|
8
7
|
|
9
|
-
|
8
|
+
before do
|
10
9
|
@stream = MiniTest::Mock.new
|
11
10
|
@state = Vines::Stream::Client::Ready.new(@stream, nil)
|
12
11
|
def @state.to_stanza(node)
|
@@ -17,24 +16,24 @@ class ClientReadyTest < MiniTest::Unit::TestCase
|
|
17
16
|
stanza.expect(:process, nil)
|
18
17
|
stanza.expect(:validate_to, nil)
|
19
18
|
stanza.expect(:validate_from, nil)
|
20
|
-
|
19
|
+
STANZAS << stanza
|
21
20
|
stanza
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
|
25
|
+
after do
|
27
26
|
STANZAS.clear
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
it 'processes a valid node' do
|
31
30
|
node = node('<message/>')
|
32
31
|
@state.node(node)
|
33
32
|
assert_equal 1, STANZAS.size
|
34
33
|
assert STANZAS.map {|s| s.verify }.all?
|
35
34
|
end
|
36
35
|
|
37
|
-
|
36
|
+
it 'raises an unsupported-stanza-type stream error for invalid node' do
|
38
37
|
node = node('<bogus/>')
|
39
38
|
assert_raises(Vines::StreamErrors::UnsupportedStanzaType) { @state.node(node) }
|
40
39
|
assert STANZAS.empty?
|
@@ -1,26 +1,27 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_equality
|
13
|
-
one = Vines::Stream::Client::Session.new(@stream)
|
14
|
-
two = Vines::Stream::Client::Session.new(@stream)
|
5
|
+
describe Vines::Stream::Client::Session do
|
6
|
+
subject { Vines::Stream::Client::Session.new(stream) }
|
7
|
+
let(:another) { Vines::Stream::Client::Session.new(stream) }
|
8
|
+
let(:stream) { OpenStruct.new(config: nil) }
|
15
9
|
|
16
|
-
|
10
|
+
describe 'session equality checks' do
|
11
|
+
it 'uses class in equality check' do
|
12
|
+
(subject <=> 42).must_be_nil
|
13
|
+
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
it 'is equal to itself' do
|
16
|
+
assert subject == subject
|
17
|
+
assert subject.eql?(subject)
|
18
|
+
assert subject.hash == subject.hash
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
it 'is not equal to another session' do
|
22
|
+
refute subject == another
|
23
|
+
refute subject.eql?(another)
|
24
|
+
refute subject.hash == another.hash
|
25
|
+
end
|
25
26
|
end
|
26
27
|
end
|