diaspora-vines 0.1.22 → 0.1.24

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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diaspora-vines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.22
4
+ version: 0.1.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Graham
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-03 00:00:00.000000000 Z
12
+ date: 2014-10-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bcrypt
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - ~>
33
33
  - !ruby/object:Gem::Version
34
- version: 0.1.1
34
+ version: 0.3.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ~>
40
40
  - !ruby/object:Gem::Version
41
- version: 0.1.1
41
+ version: 0.3.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: eventmachine
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,20 +67,6 @@ dependencies:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0.6'
70
- - !ruby/object:Gem::Dependency
71
- name: net-ldap
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ~>
75
- - !ruby/object:Gem::Version
76
- version: '0.6'
77
- type: :runtime
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ~>
82
- - !ruby/object:Gem::Version
83
- version: '0.6'
84
70
  - !ruby/object:Gem::Dependency
85
71
  name: nokogiri
86
72
  requirement: !ruby/object:Gem::Requirement
@@ -191,15 +177,12 @@ files:
191
177
  - lib/vines/cluster/pubsub.rb
192
178
  - lib/vines/cluster/sessions.rb
193
179
  - lib/vines/cluster/subscriber.rb
194
- - lib/vines/command/bcrypt.rb
195
180
  - lib/vines/command/cert.rb
196
- - lib/vines/command/init.rb
197
- - lib/vines/command/ldap.rb
198
181
  - lib/vines/command/restart.rb
199
- - lib/vines/command/schema.rb
200
182
  - lib/vines/command/start.rb
201
183
  - lib/vines/command/stop.rb
202
184
  - lib/vines/config.rb
185
+ - lib/vines/config/diaspora.rb
203
186
  - lib/vines/config/host.rb
204
187
  - lib/vines/config/port.rb
205
188
  - lib/vines/config/pubsub.rb
@@ -216,6 +199,7 @@ files:
216
199
  - lib/vines/stanza/iq/disco_info.rb
217
200
  - lib/vines/stanza/iq/disco_items.rb
218
201
  - lib/vines/stanza/iq/error.rb
202
+ - lib/vines/stanza/iq/offline.rb
219
203
  - lib/vines/stanza/iq/ping.rb
220
204
  - lib/vines/stanza/iq/private_storage.rb
221
205
  - lib/vines/stanza/iq/query.rb
@@ -240,7 +224,6 @@ files:
240
224
  - lib/vines/stanza/pubsub/subscribe.rb
241
225
  - lib/vines/stanza/pubsub/unsubscribe.rb
242
226
  - lib/vines/storage.rb
243
- - lib/vines/storage/ldap.rb
244
227
  - lib/vines/storage/local.rb
245
228
  - lib/vines/storage/null.rb
246
229
  - lib/vines/storage/sql.rb
@@ -320,14 +303,12 @@ files:
320
303
  - test/stanza/pubsub/subscribe_test.rb
321
304
  - test/stanza/pubsub/unsubscribe_test.rb
322
305
  - test/stanza_test.rb
323
- - test/storage/ldap_test.rb
324
306
  - test/storage/local_test.rb
325
307
  - test/storage/mock_redis.rb
326
308
  - test/storage/null_test.rb
327
- - test/storage/sql.rb
328
309
  - test/storage/sql_schema.rb
310
+ - test/storage/sql_test.rb
329
311
  - test/storage/storage_tests.rb
330
- - test/storage_test.rb
331
312
  - test/store_test.rb
332
313
  - test/stream/client/auth_test.rb
333
314
  - test/stream/client/ready_test.rb
@@ -348,7 +329,6 @@ files:
348
329
  - test/test_helper.rb
349
330
  - test/token_bucket_test.rb
350
331
  - test/user_test.rb
351
- - vines.gemspec
352
332
  homepage: https://diasporafoundation.org
353
333
  licenses:
354
334
  - MIT
@@ -401,7 +381,6 @@ test_files:
401
381
  - test/stanza/pubsub/unsubscribe_test.rb
402
382
  - test/stanza/pubsub/delete_test.rb
403
383
  - test/token_bucket_test.rb
404
- - test/storage_test.rb
405
384
  - test/store_test.rb
406
385
  - test/stanza_test.rb
407
386
  - test/error_test.rb
@@ -427,7 +406,6 @@ test_files:
427
406
  - test/storage/storage_tests.rb
428
407
  - test/storage/sql_schema.rb
429
408
  - test/storage/null_test.rb
409
+ - test/storage/sql_test.rb
430
410
  - test/storage/mock_redis.rb
431
- - test/storage/ldap_test.rb
432
411
  - test/storage/local_test.rb
433
- - test/storage/sql.rb
@@ -1,12 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Vines
4
- module Command
5
- class Bcrypt
6
- def run(opts)
7
- raise 'vines bcrypt <clear text>' unless opts[:args].size == 1
8
- puts BCrypt::Password.create(opts[:args].first)
9
- end
10
- end
11
- end
12
- end
@@ -1,68 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Vines
4
- module Command
5
- class Init
6
- def run(opts)
7
- raise 'vines init <domain>' unless opts[:args].size == 1
8
- domain = opts[:args].first.downcase
9
- dir = File.expand_path(domain)
10
- raise "Directory already initialized: #{domain}" if File.exists?(dir)
11
- Dir.mkdir(dir)
12
-
13
- create_directories(dir)
14
- create_users(domain, dir)
15
- update_config(domain, dir)
16
- Command::Cert.new.create_cert(domain, File.join(dir, 'conf/certs'))
17
-
18
- puts "Initialized server directory: #{domain}"
19
- puts "Run 'cd #{domain} && vines start' to begin"
20
- end
21
-
22
- private
23
-
24
- # Limit file system database directory access so the server is the only
25
- # process managing the data. The config.rb file contains component and
26
- # database passwords, so restrict access to just the server user as well.
27
- def create_directories(dir)
28
- %w[conf web].each do |sub|
29
- FileUtils.cp_r(File.expand_path("../../../../#{sub}", __FILE__), dir)
30
- end
31
- %w[data log pid].each do |sub|
32
- Dir.mkdir(File.join(dir, sub), 0700)
33
- end
34
- File.chmod(0600, File.join(dir, 'conf/config.rb'))
35
- end
36
-
37
- def update_config(domain, dir)
38
- config = File.expand_path('conf/config.rb', dir)
39
- text = File.read(config, encoding: 'utf-8')
40
- File.open(config, 'w:utf-8') do |f|
41
- f.write(text.gsub('wonderland.lit', domain))
42
- end
43
- end
44
-
45
- def create_users(domain, dir)
46
- password = 'secr3t'
47
- alice, arthur = %w[alice arthur].map do |jid|
48
- User.new(jid: [jid, domain].join('@'),
49
- password: BCrypt::Password.create(password).to_s)
50
- end
51
-
52
- [[alice, arthur], [arthur, alice]].each do |user, contact|
53
- user.roster << Contact.new(
54
- jid: contact.jid,
55
- name: contact.jid.node.capitalize,
56
- subscription: 'both',
57
- groups: %w[Buddies])
58
- end
59
-
60
- storage = Storage::Local.new { dir(File.join(dir, 'data')) }
61
- [alice, arthur].each do |user|
62
- storage.save_user(user)
63
- puts "Created example user #{user.jid} with password #{password}"
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,38 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Vines
4
- module Command
5
- class Ldap
6
- def run(opts)
7
- raise 'vines ldap <domain>' unless opts[:args].size == 1
8
- require opts[:config]
9
- domain = opts[:args].first
10
- unless storage = Config.instance.vhost(domain).storage rescue nil
11
- raise "#{domain} virtual host not found in conf/config.rb"
12
- end
13
- unless storage.ldap?
14
- raise "LDAP connector not configured for #{domain} virtual host"
15
- end
16
- $stdout.write('JID: ')
17
- jid = $stdin.gets.chomp
18
- jid = [jid, domain].join('@') unless jid.include?('@')
19
- $stdout.write('Password: ')
20
- `stty -echo`
21
- password = $stdin.gets.chomp
22
- `stty echo`
23
- puts
24
-
25
- begin
26
- user = storage.ldap.authenticate(jid, password)
27
- rescue => e
28
- raise "LDAP connection failed: #{e.message}"
29
- end
30
-
31
- filter = storage.ldap.filter(jid)
32
- raise "User not found with filter:\n #{filter}" unless user
33
- name = user.name.empty? ? '<name missing>' : user.name
34
- puts "Found user #{name} with filter:\n #{filter}"
35
- end
36
- end
37
- end
38
- end
@@ -1,24 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Vines
4
- module Command
5
- class Schema
6
- def run(opts)
7
- raise 'vines schema <domain>' unless opts[:args].size == 1
8
- require opts[:config]
9
- domain = opts[:args].first
10
- unless storage = Config.instance.vhost(domain).storage rescue nil
11
- raise "#{domain} virtual host not found in conf/config.rb"
12
- end
13
- unless storage.respond_to?(:create_schema)
14
- raise "SQL storage not configured for #{domain} virtual host"
15
- end
16
- begin
17
- storage.create_schema
18
- rescue => e
19
- raise "Schema creation failed: #{e.message}"
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,71 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Vines
4
- class Storage
5
-
6
- # Authenticates usernames and passwords against an LDAP directory. This can
7
- # provide authentication logic for the other, full-featured Storage
8
- # implementations while they store and retrieve the rest of the user
9
- # information.
10
- class Ldap
11
- @@required = [:host, :port]
12
- %w[tls dn password basedn object_class user_attr name_attr groupdn].each do |name|
13
- @@required << name.to_sym unless name == 'groupdn'
14
- define_method name do |*args|
15
- @config[name.to_sym] = args.first
16
- end
17
- end
18
-
19
- def initialize(host='localhost', port=636, &block)
20
- @config = {host: host, port: port}
21
- instance_eval(&block)
22
- @@required.each {|key| raise "Must provide #{key}" if @config[key].nil? }
23
- end
24
-
25
- # Validates a username and password by binding to the LDAP instance with
26
- # those credentials. If the bind succeeds, the user's attributes are
27
- # retrieved.
28
- def authenticate(username, password)
29
- username = JID.new(username).to_s rescue nil
30
- return if [username, password].any? {|arg| (arg || '').strip.empty? }
31
-
32
- ldap = connect(@config[:dn], @config[:password])
33
- entries = ldap.search(
34
- attributes: [@config[:name_attr], 'mail'],
35
- filter: filter(username))
36
- return unless entries && entries.size == 1
37
-
38
- user = if connect(entries.first.dn, password).bind
39
- name = entries.first[@config[:name_attr]].first
40
- User.new(jid: username, name: name.to_s, roster: [])
41
- end
42
- user
43
- end
44
-
45
- # Return an LDAP search filter for a user optionally belonging to the
46
- # group defined by the groupdn config attribute.
47
- def filter(username)
48
- clas = Net::LDAP::Filter.eq('objectClass', @config[:object_class])
49
- uid = Net::LDAP::Filter.eq(@config[:user_attr], username)
50
- filter = clas & uid
51
- if group = @config[:groupdn]
52
- memberOf = Net::LDAP::Filter.eq('memberOf', group)
53
- isMemberOf = Net::LDAP::Filter.eq('isMemberOf', group)
54
- filter = filter & (memberOf | isMemberOf)
55
- end
56
- filter
57
- end
58
-
59
- private
60
-
61
- def connect(dn, password)
62
- options = [:host, :port, :base].zip(
63
- @config.values_at(:host, :port, :basedn))
64
- Net::LDAP.new(Hash[options]).tap do |ldap|
65
- ldap.encryption(:simple_tls) if @config[:tls]
66
- ldap.auth(dn, password)
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,201 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'test_helper'
4
-
5
- describe Vines::Storage::Ldap do
6
- ALICE_DN = 'uid=alice@wondlerand.lit,ou=People,dc=wonderland,dc=lit'
7
- CONTEXT = {}
8
-
9
- after do
10
- CONTEXT.clear
11
- end
12
-
13
- describe '#initialize' do
14
- it 'raises with missing host and port' do
15
- assert_raises(RuntimeError) do
16
- Vines::Storage::Ldap.new(nil, nil) do
17
- tls true
18
- dn 'cn=Directory Manager'
19
- password 'secr3t'
20
- basedn 'dc=wonderland,dc=lit'
21
- object_class 'person'
22
- user_attr 'uid'
23
- name_attr 'cn'
24
- end
25
- end
26
- end
27
-
28
- it 'does not raise when using default host and port' do
29
- Vines::Storage::Ldap.new do
30
- tls true
31
- dn 'cn=Directory Manager'
32
- password 'secr3t'
33
- basedn 'dc=wonderland,dc=lit'
34
- object_class 'person'
35
- user_attr 'uid'
36
- name_attr 'cn'
37
- end
38
- end
39
-
40
- it 'does not raise when given a host and port' do
41
- Vines::Storage::Ldap.new('0.0.0.1', 42) do
42
- tls true
43
- dn 'cn=Directory Manager'
44
- password 'secr3t'
45
- basedn 'dc=wonderland,dc=lit'
46
- object_class 'person'
47
- user_attr 'uid'
48
- name_attr 'cn'
49
- end
50
- end
51
-
52
- it 'raises when given no parameters' do
53
- assert_raises(RuntimeError) do
54
- Vines::Storage::Ldap.new {}
55
- end
56
- end
57
-
58
- it 'raises when given blank parameters' do
59
- assert_raises(RuntimeError) do
60
- Vines::Storage::Ldap.new do
61
- tls
62
- dn
63
- password
64
- basedn
65
- object_class
66
- user_attr
67
- name_attr
68
- end
69
- end
70
- end
71
-
72
- it 'handles boolean false values without raising' do
73
- Vines::Storage::Ldap.new do
74
- tls false
75
- dn 'cn=Directory Manager'
76
- password 'secr3t'
77
- basedn 'dc=wonderland,dc=lit'
78
- object_class 'person'
79
- user_attr 'uid'
80
- name_attr 'cn'
81
- end
82
- end
83
- end
84
-
85
- describe '#authenticate' do
86
- it 'fails with invalid credentials' do
87
- ldap = connect
88
- assert_nil ldap.authenticate(nil, nil)
89
- assert_nil ldap.authenticate('', '')
90
- assert_nil ldap.authenticate('alice@wonderland.lit', ' ')
91
- assert_nil ldap.authenticate('bogus"jid@wonderland.lit', 'password')
92
- assert_nil ldap.authenticate(Vines::JID.new('alice@wonderland.lit'), '')
93
- end
94
-
95
- it 'fails when user not found' do
96
- CONTEXT.merge!({
97
- :mock_ldap => MiniTest::Mock.new,
98
- :connect_calls => 0
99
- })
100
- ldap = connect
101
- def ldap.connect(dn, password)
102
- CONTEXT[:connect_calls] += 1
103
- raise unless 'cn=Directory Manager' == dn
104
- raise unless 'secr3t' == password
105
-
106
- clas = Net::LDAP::Filter.eq('objectClass', 'person')
107
- uid = Net::LDAP::Filter.eq('uid', 'alice@wonderland.lit')
108
-
109
- mock = CONTEXT[:mock_ldap]
110
- mock.expect(:search, [], [{:attributes => ['cn', 'mail'], :filter => clas & uid}])
111
- end
112
- assert_nil ldap.authenticate('alice@wonderland.lit', 'passw0rd')
113
- assert CONTEXT[:mock_ldap]
114
- assert_equal 1, CONTEXT[:connect_calls]
115
- end
116
-
117
- it 'fails when user cannot bind' do
118
- CONTEXT.merge!({
119
- :credentials => [
120
- {:dn => 'cn=Directory Manager', :password => 'secr3t'},
121
- {:dn => ALICE_DN, :password => 'passw0rd'}
122
- ],
123
- :mock_ldap => MiniTest::Mock.new,
124
- :mock_entry => MiniTest::Mock.new,
125
- :connect_calls => 0
126
- })
127
- ldap = connect
128
- def ldap.connect(dn, password)
129
- credentials = CONTEXT[:credentials][CONTEXT[:connect_calls]]
130
- CONTEXT[:connect_calls] += 1
131
- raise unless credentials[:dn] == dn && credentials[:password] == password
132
-
133
- clas = Net::LDAP::Filter.eq('objectClass', 'person')
134
- uid = Net::LDAP::Filter.eq('uid', 'alice@wonderland.lit')
135
-
136
- entry = CONTEXT[:mock_entry]
137
- entry.expect(:dn, ALICE_DN)
138
-
139
- mock = CONTEXT[:mock_ldap]
140
- mock.expect(:search, [entry], [{:attributes => ['cn', 'mail'], :filter => clas & uid}])
141
- mock.expect(:bind, false)
142
- end
143
- assert_nil ldap.authenticate('alice@wonderland.lit', 'passw0rd')
144
- assert_equal 2, CONTEXT[:connect_calls]
145
- assert CONTEXT[:mock_entry].verify
146
- assert CONTEXT[:mock_ldap].verify
147
- end
148
-
149
- it 'authenticates successfully with proper credentials' do
150
- CONTEXT.merge!({
151
- :credentials => [
152
- {:dn => 'cn=Directory Manager', :password => 'secr3t'},
153
- {:dn => ALICE_DN, :password => 'passw0rd'}
154
- ],
155
- :mock_ldap => MiniTest::Mock.new,
156
- :mock_entry => MiniTest::Mock.new,
157
- :connect_calls => 0
158
- })
159
- ldap = connect
160
- def ldap.connect(dn, password)
161
- credentials = CONTEXT[:credentials][CONTEXT[:connect_calls]]
162
- CONTEXT[:connect_calls] += 1
163
- raise unless credentials[:dn] == dn && credentials[:password] == password
164
-
165
- clas = Net::LDAP::Filter.eq('objectClass', 'person')
166
- uid = Net::LDAP::Filter.eq('uid', 'alice@wonderland.lit')
167
-
168
- entry = CONTEXT[:mock_entry]
169
- entry.expect(:dn, ALICE_DN)
170
- entry.expect(:[], ['Alice Liddell'], ['cn'])
171
-
172
- mock = CONTEXT[:mock_ldap]
173
- mock.expect(:search, [entry], [{:attributes => ['cn', 'mail'], :filter => clas & uid}])
174
- mock.expect(:bind, true)
175
- end
176
- user = ldap.authenticate('alice@wonderland.lit', 'passw0rd')
177
- refute_nil user
178
- assert_equal 'alice@wonderland.lit', user.jid.to_s
179
- assert_equal 'Alice Liddell', user.name
180
- assert_equal [], user.roster
181
-
182
- assert_equal 2, CONTEXT[:connect_calls]
183
- assert CONTEXT[:mock_entry].verify
184
- assert CONTEXT[:mock_ldap].verify
185
- end
186
- end
187
-
188
- private
189
-
190
- def connect
191
- Vines::Storage::Ldap.new('0.0.0.0', 636) do
192
- tls true
193
- dn 'cn=Directory Manager'
194
- password 'secr3t'
195
- basedn 'dc=wonderland,dc=lit'
196
- object_class 'person'
197
- user_attr 'uid'
198
- name_attr 'cn'
199
- end
200
- end
201
- end