vines 0.2.1 → 0.3.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.
- data/README +1 -1
- data/Rakefile +10 -10
- data/conf/certs/ca-bundle.crt +112 -378
- data/conf/config.rb +18 -9
- data/lib/vines.rb +8 -1
- data/lib/vines/command/cert.rb +2 -1
- data/lib/vines/command/init.rb +11 -0
- data/lib/vines/command/ldap.rb +6 -3
- data/lib/vines/command/schema.rb +1 -1
- data/lib/vines/config.rb +57 -146
- data/lib/vines/config/host.rb +85 -0
- data/lib/vines/config/port.rb +111 -0
- data/lib/vines/contact.rb +1 -1
- data/lib/vines/jid.rb +26 -4
- data/lib/vines/kit.rb +6 -0
- data/lib/vines/log.rb +24 -0
- data/lib/vines/router.rb +70 -38
- data/lib/vines/stanza.rb +45 -8
- data/lib/vines/stanza/iq.rb +3 -3
- data/lib/vines/stanza/iq/disco_info.rb +5 -1
- data/lib/vines/stanza/iq/disco_items.rb +3 -0
- data/lib/vines/stanza/iq/private_storage.rb +9 -5
- data/lib/vines/stanza/iq/roster.rb +11 -12
- data/lib/vines/stanza/iq/vcard.rb +4 -4
- data/lib/vines/stanza/iq/version.rb +25 -0
- data/lib/vines/stanza/message.rb +4 -5
- data/lib/vines/stanza/presence.rb +20 -18
- data/lib/vines/stanza/presence/probe.rb +3 -4
- data/lib/vines/stanza/presence/subscribe.rb +4 -3
- data/lib/vines/stanza/presence/subscribed.rb +6 -5
- data/lib/vines/stanza/presence/unsubscribe.rb +4 -4
- data/lib/vines/stanza/presence/unsubscribed.rb +4 -3
- data/lib/vines/storage/couchdb.rb +3 -3
- data/lib/vines/storage/ldap.rb +19 -8
- data/lib/vines/storage/local.rb +23 -12
- data/lib/vines/storage/redis.rb +3 -3
- data/lib/vines/storage/sql.rb +5 -5
- data/lib/vines/stream.rb +40 -6
- data/lib/vines/stream/client.rb +5 -6
- data/lib/vines/stream/client/auth.rb +3 -2
- data/lib/vines/stream/client/bind.rb +2 -2
- data/lib/vines/stream/client/bind_restart.rb +1 -2
- data/lib/vines/stream/client/ready.rb +2 -0
- data/lib/vines/stream/client/session.rb +13 -4
- data/lib/vines/stream/client/tls.rb +1 -0
- data/lib/vines/stream/component.rb +6 -5
- data/lib/vines/stream/component/ready.rb +5 -6
- data/lib/vines/stream/http.rb +10 -4
- data/lib/vines/stream/http/request.rb +23 -2
- data/lib/vines/stream/server.rb +13 -11
- data/lib/vines/stream/server/outbound/auth_result.rb +1 -0
- data/lib/vines/stream/server/outbound/tls_result.rb +1 -0
- data/lib/vines/stream/server/ready.rb +2 -2
- data/lib/vines/user.rb +2 -1
- data/lib/vines/version.rb +1 -1
- data/test/config/host_test.rb +292 -0
- data/test/config_test.rb +244 -103
- data/test/contact_test.rb +7 -1
- data/test/jid_test.rb +48 -0
- data/test/router_test.rb +16 -47
- data/test/stanza/iq/disco_info_test.rb +76 -0
- data/test/stanza/iq/disco_items_test.rb +47 -0
- data/test/stanza/iq/private_storage_test.rb +33 -10
- data/test/stanza/iq/roster_test.rb +15 -5
- data/test/stanza/iq/vcard_test.rb +8 -25
- data/test/stanza/iq/version_test.rb +62 -0
- data/test/stanza/iq_test.rb +13 -10
- data/test/stanza/message_test.rb +16 -24
- data/test/stanza/presence/probe_test.rb +52 -0
- data/test/stanza/presence/subscribe_test.rb +1 -5
- data/test/stanza_test.rb +77 -0
- data/test/stream/client/auth_test.rb +1 -0
- data/test/stream/client/ready_test.rb +2 -0
- data/test/stream/client/session_test.rb +7 -2
- data/test/stream/component/ready_test.rb +19 -36
- data/test/stream/http/request_test.rb +22 -2
- data/test/stream/server/ready_test.rb +14 -21
- data/web/404.html +9 -3
- data/web/chat/index.html +2 -2
- data/web/chat/javascripts/app.js +1 -1
- data/web/chat/stylesheets/chat.css +4 -9
- data/web/lib/coffeescripts/layout.coffee +2 -2
- data/web/{chat → lib}/coffeescripts/logout.coffee +0 -0
- data/web/lib/coffeescripts/notification.coffee +14 -0
- data/web/lib/coffeescripts/session.coffee +28 -24
- data/web/lib/coffeescripts/transfer.coffee +37 -34
- data/web/lib/javascripts/base.js +8 -8
- data/web/lib/javascripts/icons.js +3 -0
- data/web/lib/javascripts/jquery.js +4 -18
- data/web/lib/javascripts/layout.js +2 -2
- data/web/{chat → lib}/javascripts/logout.js +0 -0
- data/web/lib/javascripts/notification.js +26 -0
- data/web/lib/javascripts/session.js +20 -16
- data/web/lib/javascripts/transfer.js +45 -55
- data/web/lib/stylesheets/base.css +45 -9
- metadata +31 -15
@@ -7,17 +7,17 @@ module Vines
|
|
7
7
|
# streams. This serves connected streams using the jabber:component:accept
|
8
8
|
# namespace.
|
9
9
|
class Component < Stream
|
10
|
-
attr_reader :
|
10
|
+
attr_reader :remote_domain
|
11
11
|
|
12
12
|
def initialize(config)
|
13
|
-
|
13
|
+
super
|
14
14
|
@remote_domain = nil
|
15
15
|
@stream_id = Kit.uuid
|
16
16
|
advance(Start.new(self))
|
17
17
|
end
|
18
18
|
|
19
19
|
def max_stanza_size
|
20
|
-
|
20
|
+
config[:component].max_stanza_size
|
21
21
|
end
|
22
22
|
|
23
23
|
def ready?
|
@@ -31,13 +31,14 @@ module Vines
|
|
31
31
|
def start(node)
|
32
32
|
@remote_domain = node['to']
|
33
33
|
send_stream_header
|
34
|
-
raise StreamErrors::
|
34
|
+
raise StreamErrors::ImproperAddressing unless valid_address?(@remote_domain)
|
35
|
+
raise StreamErrors::HostUnknown unless config.component?(@remote_domain)
|
35
36
|
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:component]
|
36
37
|
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns:stream'] == NAMESPACES[:stream]
|
37
38
|
end
|
38
39
|
|
39
40
|
def secret
|
40
|
-
password =
|
41
|
+
password = config.component_password(@remote_domain)
|
41
42
|
Digest::SHA1.hexdigest(@stream_id + password)
|
42
43
|
end
|
43
44
|
|
@@ -7,13 +7,12 @@ module Vines
|
|
7
7
|
def node(node)
|
8
8
|
stanza = to_stanza(node)
|
9
9
|
raise StreamErrors::UnsupportedStanzaType unless stanza
|
10
|
-
to =
|
11
|
-
|
12
|
-
raise StreamErrors::
|
10
|
+
to, from = stanza.validate_to, stanza.validate_from
|
11
|
+
raise StreamErrors::ImproperAddressing unless to && from
|
12
|
+
raise StreamErrors::InvalidFrom unless from.domain == stream.remote_domain
|
13
|
+
stream.user = User.new(:jid => from)
|
13
14
|
if stanza.local?
|
14
|
-
|
15
|
-
recipient.write(node)
|
16
|
-
end
|
15
|
+
stanza.process
|
17
16
|
else
|
18
17
|
stanza.route
|
19
18
|
end
|
data/lib/vines/stream/http.rb
CHANGED
@@ -13,6 +13,11 @@ module Vines
|
|
13
13
|
def post_init
|
14
14
|
super
|
15
15
|
router.delete(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Override +Stream#create_parser+ to provide an HTTP parser rather than
|
19
|
+
# a Nokogiri XML parser.
|
20
|
+
def create_parser
|
16
21
|
@parser = ::Http::Parser.new.tap do |p|
|
17
22
|
body = ''
|
18
23
|
p.on_body = proc {|data| body << data }
|
@@ -33,9 +38,9 @@ module Vines
|
|
33
38
|
!!session
|
34
39
|
end
|
35
40
|
|
36
|
-
%w[max_stanza_size max_resources_per_account
|
41
|
+
%w[max_stanza_size max_resources_per_account bind root].each do |name|
|
37
42
|
define_method name do |*args|
|
38
|
-
|
43
|
+
config[:http].send(name, *args)
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
@@ -86,7 +91,8 @@ module Vines
|
|
86
91
|
|
87
92
|
raise StreamErrors::UndefinedCondition.new('rid required') if rid.empty?
|
88
93
|
raise StreamErrors::UnsupportedVersion unless version == '1.0'
|
89
|
-
raise StreamErrors::
|
94
|
+
raise StreamErrors::ImproperAddressing unless valid_address?(domain)
|
95
|
+
raise StreamErrors::HostUnknown unless config.vhost?(domain)
|
90
96
|
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:http_bind]
|
91
97
|
|
92
98
|
Sessions[@session.id] = @session
|
@@ -109,7 +115,7 @@ module Vines
|
|
109
115
|
doc = Nokogiri::XML::Document.new
|
110
116
|
node = doc.create_element('body',
|
111
117
|
'charsets' => 'UTF-8',
|
112
|
-
'from' => @session.domain,
|
118
|
+
'from' => @session.domain,
|
113
119
|
'hold' => @session.hold,
|
114
120
|
'inactivity' => @session.inactivity,
|
115
121
|
'polling' => '5',
|
@@ -6,6 +6,7 @@ module Vines
|
|
6
6
|
class Request
|
7
7
|
BUF_SIZE = 1024
|
8
8
|
MODIFIED = '%a, %d %b %Y %H:%M:%S GMT'.freeze
|
9
|
+
MOVED = 'Moved Permanently'.freeze
|
9
10
|
NOT_FOUND = 'Not Found'.freeze
|
10
11
|
NOT_MODIFIED = 'Not Modified'.freeze
|
11
12
|
IF_MODIFIED = 'If-Modified-Since'.freeze
|
@@ -44,6 +45,13 @@ module Vines
|
|
44
45
|
# to implement caching.
|
45
46
|
def reply_with_file(dir)
|
46
47
|
path = File.expand_path(File.join(dir, @path))
|
48
|
+
|
49
|
+
# redirect requests missing a slash so relative links work
|
50
|
+
if File.directory?(path) && !@path.end_with?('/')
|
51
|
+
send_status(301, MOVED, "Location: #{redirect_uri}")
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
47
55
|
path = File.join(path, 'index.html') if File.directory?(path)
|
48
56
|
|
49
57
|
if path.start_with?(dir) && File.exist?(path)
|
@@ -72,6 +80,18 @@ module Vines
|
|
72
80
|
|
73
81
|
private
|
74
82
|
|
83
|
+
# Attempt to rebuild the full request URI from the Host header. If it
|
84
|
+
# wasn't sent by the client, just return the relative path that
|
85
|
+
# was requested. The Location response header must contain the fully
|
86
|
+
# qualified URI, but most browsers will accept relative paths as well.
|
87
|
+
def redirect_uri
|
88
|
+
host = headers['Host']
|
89
|
+
uri = "#{path}/"
|
90
|
+
uri = "#{uri}?#{query}" unless (query || '').empty?
|
91
|
+
uri = "http://#{host}#{uri}" if host
|
92
|
+
uri
|
93
|
+
end
|
94
|
+
|
75
95
|
# Return true if the file has been modified since the client last
|
76
96
|
# requested it with the If-Modified-Since header.
|
77
97
|
def modified?(path)
|
@@ -82,10 +102,11 @@ module Vines
|
|
82
102
|
File.mtime(path).utc.strftime(MODIFIED)
|
83
103
|
end
|
84
104
|
|
85
|
-
def send_status(status, message)
|
105
|
+
def send_status(status, message, *headers)
|
86
106
|
header = [
|
87
107
|
"HTTP/1.1 #{status} #{message}",
|
88
|
-
"Connection: close"
|
108
|
+
"Connection: close",
|
109
|
+
*headers
|
89
110
|
].join("\r\n")
|
90
111
|
@stream.stream_write("#{header}\r\n\r\n")
|
91
112
|
@stream.close_connection_after_writing
|
data/lib/vines/stream/server.rb
CHANGED
@@ -23,7 +23,7 @@ module Vines
|
|
23
23
|
end
|
24
24
|
cb = proc do |srv|
|
25
25
|
if srv.empty?
|
26
|
-
srv << {:
|
26
|
+
srv << {target: to, port: 5269}
|
27
27
|
class << srv.first
|
28
28
|
def method_missing(name); self[name]; end
|
29
29
|
end
|
@@ -39,7 +39,7 @@ module Vines
|
|
39
39
|
else
|
40
40
|
begin
|
41
41
|
rr = srv.shift
|
42
|
-
opts = {:
|
42
|
+
opts = {to: to, from: from, srv: srv, callback: callback}
|
43
43
|
EM.connect(rr.target.to_s, rr.port, Server, config, opts)
|
44
44
|
rescue Exception => e
|
45
45
|
connect(config, to, from, srv, callback)
|
@@ -47,11 +47,12 @@ module Vines
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
attr_reader
|
50
|
+
attr_reader :domain
|
51
51
|
attr_accessor :remote_domain
|
52
52
|
|
53
53
|
def initialize(config, options={})
|
54
|
-
|
54
|
+
super(config)
|
55
|
+
@connected = false
|
55
56
|
@remote_domain = options[:to]
|
56
57
|
@domain = options[:from]
|
57
58
|
@srv = options[:srv]
|
@@ -67,7 +68,7 @@ module Vines
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def max_stanza_size
|
70
|
-
|
71
|
+
config[:server].max_stanza_size
|
71
72
|
end
|
72
73
|
|
73
74
|
def ssl_handshake_completed
|
@@ -80,16 +81,17 @@ module Vines
|
|
80
81
|
|
81
82
|
def unbind
|
82
83
|
super
|
83
|
-
if @outbound &&
|
84
|
-
Server.connect(
|
84
|
+
if @outbound && !@connected
|
85
|
+
Server.connect(config, @remote_domain, @domain, @srv, @callback)
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
88
89
|
def vhost?(domain)
|
89
|
-
|
90
|
+
config.vhost?(domain)
|
90
91
|
end
|
91
92
|
|
92
93
|
def notify_connected
|
94
|
+
@connected = true
|
93
95
|
if @callback
|
94
96
|
@callback.call(self)
|
95
97
|
@callback = nil
|
@@ -105,9 +107,9 @@ module Vines
|
|
105
107
|
@domain, @remote_domain = %w[to from].map {|a| node[a] }
|
106
108
|
send_stream_header
|
107
109
|
raise StreamErrors::UnsupportedVersion unless node['version'] == '1.0'
|
108
|
-
raise StreamErrors::ImproperAddressing
|
109
|
-
raise StreamErrors::HostUnknown unless
|
110
|
-
raise StreamErrors::NotAuthorized unless
|
110
|
+
raise StreamErrors::ImproperAddressing unless valid_address?(@domain) && valid_address?(@remote_domain)
|
111
|
+
raise StreamErrors::HostUnknown unless config.vhost?(@domain)
|
112
|
+
raise StreamErrors::NotAuthorized unless config.s2s?(@remote_domain)
|
111
113
|
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns'] == NAMESPACES[:server]
|
112
114
|
raise StreamErrors::InvalidNamespace unless node.namespaces['xmlns:stream'] == NAMESPACES[:stream]
|
113
115
|
end
|
@@ -7,8 +7,8 @@ module Vines
|
|
7
7
|
def node(node)
|
8
8
|
stanza = to_stanza(node)
|
9
9
|
raise StreamErrors::UnsupportedStanzaType unless stanza
|
10
|
-
to, from =
|
11
|
-
raise StreamErrors::ImproperAddressing
|
10
|
+
to, from = stanza.validate_to, stanza.validate_from
|
11
|
+
raise StreamErrors::ImproperAddressing unless to && from
|
12
12
|
raise StreamErrors::InvalidFrom unless from.domain == stream.remote_domain
|
13
13
|
raise StreamErrors::HostUnknown unless to.domain == stream.domain
|
14
14
|
stream.user = User.new(:jid => from)
|
data/lib/vines/user.rb
CHANGED
@@ -9,7 +9,8 @@ module Vines
|
|
9
9
|
|
10
10
|
def initialize(args={})
|
11
11
|
@jid = JID.new(args[:jid])
|
12
|
-
raise ArgumentError, 'invalid jid'
|
12
|
+
raise ArgumentError, 'invalid jid' if @jid.empty?
|
13
|
+
|
13
14
|
@name = args[:name]
|
14
15
|
@password = args[:password]
|
15
16
|
@roster = args[:roster] || []
|
data/lib/vines/version.rb
CHANGED
@@ -0,0 +1,292 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'vines'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
class HostTest < MiniTest::Unit::TestCase
|
7
|
+
def test_missing_storage
|
8
|
+
assert_raises(RuntimeError) do
|
9
|
+
Vines::Config.new do
|
10
|
+
host 'wonderland.lit' do
|
11
|
+
# missing storage
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_bad_storage
|
18
|
+
assert_raises(RuntimeError) do
|
19
|
+
Vines::Config.new do
|
20
|
+
host 'wonderland.lit' do
|
21
|
+
storage 'bogus' do
|
22
|
+
# no bogus storage implementation
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_duplicate_storage
|
30
|
+
assert_raises(RuntimeError) do
|
31
|
+
Vines::Config.new do
|
32
|
+
host 'wonderland.lit' do
|
33
|
+
storage('fs') { dir '.' }
|
34
|
+
storage('fs') { dir '.' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_good_storage_raises_no_errors
|
41
|
+
config = Vines::Config.new do
|
42
|
+
host 'wonderland.lit' do
|
43
|
+
storage 'fs' do
|
44
|
+
dir '.'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
refute_nil config.vhosts['wonderland.lit'].storage
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_ldap_added_to_storage
|
52
|
+
config = Vines::Config.new do
|
53
|
+
host 'wonderland.lit' do
|
54
|
+
storage(:fs) { dir '.' }
|
55
|
+
# added after storage
|
56
|
+
ldap 'ldap.wonderland.lit', 1636 do
|
57
|
+
tls true
|
58
|
+
dn 'cn=Directory Manager'
|
59
|
+
password 'secr3t'
|
60
|
+
basedn 'dc=wonderland,dc=lit'
|
61
|
+
groupdn 'cn=chatters,dc=wonderland,dc=lit'
|
62
|
+
object_class 'person'
|
63
|
+
user_attr 'uid'
|
64
|
+
name_attr 'cn'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
host 'verona.lit' do
|
69
|
+
ldap 'ldap.verona.lit', 1636 do
|
70
|
+
tls true
|
71
|
+
dn 'cn=Directory Manager'
|
72
|
+
password 'secr3t'
|
73
|
+
basedn 'dc=wonderland,dc=lit'
|
74
|
+
object_class 'person'
|
75
|
+
user_attr 'uid'
|
76
|
+
name_attr 'cn'
|
77
|
+
end
|
78
|
+
# added before storage
|
79
|
+
storage(:fs) { dir '.' }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
%w[wonderland.lit verona.lit].each do |domain|
|
83
|
+
refute_nil config.vhosts[domain].storage.ldap
|
84
|
+
assert config.vhosts[domain].storage.ldap?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_empty_component_name_raises
|
89
|
+
assert_raises(RuntimeError) do
|
90
|
+
Vines::Config.new do
|
91
|
+
host 'wonderland.lit' do
|
92
|
+
storage(:fs) { dir '.' }
|
93
|
+
components '' => 'secr3t'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_nil_component_name_raises
|
100
|
+
assert_raises(RuntimeError) do
|
101
|
+
Vines::Config.new do
|
102
|
+
host 'wonderland.lit' do
|
103
|
+
storage(:fs) { dir '.' }
|
104
|
+
components nil => 'secr3t'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_empty_component_password_raises
|
111
|
+
assert_raises(RuntimeError) do
|
112
|
+
Vines::Config.new do
|
113
|
+
host 'wonderland.lit' do
|
114
|
+
storage(:fs) { dir '.' }
|
115
|
+
components 'tea' => ''
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_nil_component_password_raises
|
122
|
+
assert_raises(RuntimeError) do
|
123
|
+
Vines::Config.new do
|
124
|
+
host 'wonderland.lit' do
|
125
|
+
storage(:fs) { dir '.' }
|
126
|
+
components 'tea' => nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_duplicate_component_raises
|
133
|
+
assert_raises(RuntimeError) do
|
134
|
+
Vines::Config.new do
|
135
|
+
host 'wonderland.lit' do
|
136
|
+
storage(:fs) { dir '.' }
|
137
|
+
components 'tea' => 'one'
|
138
|
+
components 'TEA' => 'two'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_duplicate_component_in_one_call_raises
|
145
|
+
assert_raises(RuntimeError) do
|
146
|
+
Vines::Config.new do
|
147
|
+
host 'wonderland.lit' do
|
148
|
+
storage(:fs) { dir '.' }
|
149
|
+
components 'tea' => 'one', 'TEA' => 'two'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_duplicate_component_symbol_raises
|
156
|
+
assert_raises(RuntimeError) do
|
157
|
+
Vines::Config.new do
|
158
|
+
host 'wonderland.lit' do
|
159
|
+
storage(:fs) { dir '.' }
|
160
|
+
components 'tea' => 'one'
|
161
|
+
components :TEA => 'two'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_invalid_host_domain_raises
|
168
|
+
assert_raises(ArgumentError) do
|
169
|
+
Vines::Config.new do
|
170
|
+
host 'wonderland.lit ' do
|
171
|
+
storage(:fs) { dir '.' }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_invalid_jid_host_domain_raises
|
178
|
+
assert_raises(RuntimeError) do
|
179
|
+
Vines::Config.new do
|
180
|
+
host 'alice@wonderland.lit' do
|
181
|
+
storage(:fs) { dir '.' }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_invalid_component_domain_raises
|
188
|
+
assert_raises(ArgumentError) do
|
189
|
+
Vines::Config.new do
|
190
|
+
host 'wonderland.lit' do
|
191
|
+
storage(:fs) { dir '.' }
|
192
|
+
components 'exam ple' => 'one'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_invalid_jid_component_domain_raises
|
199
|
+
assert_raises(RuntimeError) do
|
200
|
+
Vines::Config.new do
|
201
|
+
host 'wonderland.lit' do
|
202
|
+
storage(:fs) { dir '.' }
|
203
|
+
components 'alice@example' => 'one'
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_multi_subdomain_component_raises
|
210
|
+
assert_raises(RuntimeError) do
|
211
|
+
Vines::Config.new do
|
212
|
+
host 'wonderland.lit' do
|
213
|
+
storage(:fs) { dir '.' }
|
214
|
+
components 'exam.ple' => 'one'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_case_insensitive_component_name
|
221
|
+
config = Vines::Config.new do
|
222
|
+
host 'WONDERLAND.LIT' do
|
223
|
+
storage(:fs) { dir '.' }
|
224
|
+
components 'TEA' => 'secr3t', CAKE: 'Passw0rd'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
host = config.vhosts['wonderland.lit']
|
228
|
+
refute_nil host
|
229
|
+
assert_equal 2, host.components.size
|
230
|
+
assert_equal host.components['tea.wonderland.lit'], 'secr3t'
|
231
|
+
assert_equal host.components['cake.wonderland.lit'], 'Passw0rd'
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_component?
|
235
|
+
config = Vines::Config.new do
|
236
|
+
host 'wonderland.lit' do
|
237
|
+
storage(:fs) { dir '.' }
|
238
|
+
components 'tea' => 'secr3t', cake: 'passw0rd'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
host = config.vhosts['wonderland.lit']
|
242
|
+
refute_nil host
|
243
|
+
refute host.component?(nil)
|
244
|
+
refute host.component?('tea')
|
245
|
+
refute host.component?(:cake)
|
246
|
+
assert host.component?('tea.wonderland.lit')
|
247
|
+
assert host.component?('cake.wonderland.lit')
|
248
|
+
assert_nil host.password(nil)
|
249
|
+
assert_nil host.password('bogus')
|
250
|
+
assert_equal 'secr3t', host.password('tea.wonderland.lit')
|
251
|
+
assert_equal 'passw0rd', host.password('cake.wonderland.lit')
|
252
|
+
expected = {'tea.wonderland.lit' => 'secr3t', 'cake.wonderland.lit' => 'passw0rd'}
|
253
|
+
assert_equal expected, host.components
|
254
|
+
|
255
|
+
refute config.component?(nil)
|
256
|
+
refute config.component?('tea')
|
257
|
+
refute config.component?('bogus')
|
258
|
+
assert config.component?('tea.wonderland.lit')
|
259
|
+
assert config.component?('cake.wonderland.lit')
|
260
|
+
assert config.component?('tea.wonderland.lit', 'cake.wonderland.lit')
|
261
|
+
refute config.component?('tea.wonderland.lit', 'bogus.wonderland.lit')
|
262
|
+
|
263
|
+
assert_nil config.component_password(nil)
|
264
|
+
assert_nil config.component_password('bogus')
|
265
|
+
assert_equal 'secr3t', config.component_password('tea.wonderland.lit')
|
266
|
+
assert_equal 'passw0rd', config.component_password('cake.wonderland.lit')
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_default_private_storage_is_off
|
270
|
+
config = Vines::Config.new do
|
271
|
+
host 'wonderland.lit' do
|
272
|
+
storage(:fs) { dir '.' }
|
273
|
+
end
|
274
|
+
end
|
275
|
+
host = config.vhosts['wonderland.lit']
|
276
|
+
refute_nil host
|
277
|
+
refute host.private_storage?
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_enable_private_storage
|
281
|
+
config = Vines::Config.new do
|
282
|
+
host 'wonderland.lit' do
|
283
|
+
private_storage true
|
284
|
+
storage(:fs) { dir '.' }
|
285
|
+
end
|
286
|
+
end
|
287
|
+
host = config.vhosts['wonderland.lit']
|
288
|
+
refute_nil host
|
289
|
+
assert host.private_storage?
|
290
|
+
assert config.private_storage?('wonderland.lit')
|
291
|
+
end
|
292
|
+
end
|