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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a46173efffc5217b488d5f6c5976884ccc2f708
4
- data.tar.gz: aa7dd385af0c647ff67c13c2342dec210f04e131
3
+ metadata.gz: 33f5f3afd1563cc0deb0d6c01e2e4e106c080c1c
4
+ data.tar.gz: c9efd2b5249a1bae0c7b778b8c8450f4b77fa508
5
5
  SHA512:
6
- metadata.gz: 6b07389956b5f47fc57f9b79afa0a6e28c013da900800e526c31247773877681bcc54a4940356370ebfe3fb2c36a0a62c667b25e71c593e4f151b03ef1b25f0f
7
- data.tar.gz: 7196743cd8ee5505f72d05b662b10fc691187437e202bb9e8aef9341a338a7d477d299e1d951d1c2d5f0ef75833d2896a165e68e7a5606aaed802c3dd77d1ae4
6
+ metadata.gz: b28a8475282ff632df35a67467eb2650c38d7e91d8cf0fb952b151ee94e6d3372e298c20f5d459a57626d2cd105b6fd87789a0a7dcee7803b1146a016ab005a7
7
+ data.tar.gz: e4334b4750a2858ddc01c82be62a9a6d4af7036ca2e212d861d85fbffb280fe3c3c61844653cb693fd2cb65af72ffc077163d04931f0831b07d9bf754afaeff6
data/conf/config.rb CHANGED
@@ -12,11 +12,9 @@ Vines::Config.configure do
12
12
  # `vines init`.
13
13
  certs 'conf/certs'
14
14
 
15
- # Setup a pepper to generate the encrypted password.
16
- pepper "065eb8798b181ff0ea2c5c16aee0ff8b70e04e2ee6bd6e08b49da46924223e39127d5335e466207d42bf2a045c12be5f90e92012a4f05f7fc6d9f3c875f4c95b"
17
-
18
15
  host 'diaspora' do
19
16
  cross_domain_messages true
17
+ accept_self_signed false
20
18
  storage 'sql'
21
19
  end
22
20
 
@@ -31,14 +29,14 @@ Vines::Config.configure do
31
29
  # much larger than the setting for client-to-server.
32
30
  server '0.0.0.0', 5269 do
33
31
  max_stanza_size 131072
34
- hosts []
32
+ blacklist []
35
33
  end
36
34
 
37
35
  # Configure the built-in HTTP server that serves static files and responds to
38
36
  # XEP-0124 BOSH requests. This allows HTTP clients to connect to
39
37
  # the XMPP server.
40
38
  http '0.0.0.0', 5280 do
41
- bind '/xmpp'
39
+ bind '/http-bind'
42
40
  max_stanza_size 65536
43
41
  max_resources_per_account 5
44
42
  root 'public'
data/lib/vines.rb CHANGED
@@ -54,12 +54,6 @@ module Vines
54
54
  end
55
55
  end
56
56
 
57
- begin
58
- # try to initialize diaspora configuration
59
- require "#{Dir.pwd}/config/application.rb"
60
- require "#{Dir.pwd}/config/load_config.rb"
61
- rescue LoadError; end
62
-
63
57
  %w[
64
58
  active_record
65
59
  base64
@@ -72,13 +66,13 @@ rescue LoadError; end
72
66
  http/parser
73
67
  json
74
68
  logger
75
- net/ldap
76
69
  nokogiri
77
70
  openssl
78
71
  optparse
79
72
  resolv
80
73
  set
81
74
  socket
75
+ uri
82
76
  yaml
83
77
 
84
78
  vines/cli
@@ -116,7 +110,6 @@ rescue LoadError; end
116
110
  vines/stanza/pubsub/unsubscribe
117
111
 
118
112
  vines/storage
119
- vines/storage/ldap
120
113
  vines/storage/local
121
114
  vines/storage/sql
122
115
  vines/storage/null
@@ -192,12 +185,21 @@ rescue LoadError; end
192
185
  vines/stream/server/outbound/final_restart
193
186
  vines/stream/server/outbound/final_features
194
187
 
195
- vines/command/bcrypt
196
188
  vines/command/cert
197
- vines/command/init
198
- vines/command/ldap
199
189
  vines/command/restart
200
- vines/command/schema
201
190
  vines/command/start
202
191
  vines/command/stop
203
192
  ].each {|f| require f }
193
+
194
+ # Try loading diaspora configuration
195
+ %w[
196
+ config/application.rb
197
+ config/load_config.rb
198
+ config/initializers/devise.rb
199
+ ].each {|c|
200
+ begin
201
+ require "#{Dir.pwd}/#{c}"
202
+ rescue LoadError
203
+ puts "Was not able to load #{c}! This not a standalone version. You should use it only in a diaspora environment."
204
+ end
205
+ }
data/lib/vines/cli.rb CHANGED
@@ -3,7 +3,7 @@ module Vines
3
3
  # in the gem. Parses the command line arguments to create a new server
4
4
  # directory, and starts and stops the server.
5
5
  class CLI
6
- COMMANDS = %w[start stop restart init bcrypt cert ldap schema]
6
+ COMMANDS = %w[start stop restart cert]
7
7
 
8
8
  def self.start
9
9
  self.new.start
@@ -14,36 +14,17 @@ module Vines
14
14
  #
15
15
  # Returns nothing.
16
16
  def start
17
- register_storage
18
17
  opts = parse(ARGV)
19
- check_config(opts)
20
18
  command = Command.const_get(opts[:command].capitalize).new
21
19
  begin
22
20
  command.run(opts)
23
21
  rescue SystemExit
24
22
  # do nothing
25
- rescue Exception => e
26
- puts e.message
27
- exit(1)
28
23
  end
29
24
  end
30
25
 
31
26
  private
32
27
 
33
- # Try to load various storage backends provided by vines-* gems and register
34
- # them with the storage system for the config file to use.
35
- #
36
- # Returns nothing.
37
- def register_storage
38
- %w[couchdb mongodb redis sql].each do |backend|
39
- begin
40
- require 'vines/storage/%s' % backend
41
- rescue LoadError
42
- # do nothing
43
- end
44
- end
45
- end
46
-
47
28
  # Parse the command line arguments and run the matching sub-command
48
29
  # (e.g. init, start, stop, etc).
49
30
  #
@@ -110,22 +91,12 @@ module Vines
110
91
  options.tap do |opts|
111
92
  opts[:args] = args
112
93
  opts[:command] = command
113
- opts[:config] = File.expand_path("#{Dir.pwd}/config/vines.rb") || File.expand_path("conf/config.rb")
94
+ opts[:config] = File.expand_path("conf/config.rb")
114
95
  opts[:pid] = File.expand_path(opts[:pid])
115
96
  opts[:log] = File.expand_path(opts[:log])
116
- end
117
- end
118
-
119
- # Many commands must be run in the context of a vines server directory
120
- # created with `vines init`. If the command can't find the server's config
121
- # file, print an error message and exit.
122
- #
123
- # Returns nothing.
124
- def check_config(opts)
125
- return if %w[bcrypt init].include?(opts[:command])
126
- unless File.exists?(opts[:config])
127
- puts "No config file found at #{opts[:config]}"
128
- exit(1)
97
+ if defined? AppConfig
98
+ opts[:config] = "vines/config/diaspora"
99
+ end
129
100
  end
130
101
  end
131
102
  end
@@ -25,4 +25,4 @@ module Vines
25
25
  end
26
26
  end
27
27
  end
28
- end
28
+ end
data/lib/vines/config.rb CHANGED
@@ -21,7 +21,6 @@ module Vines
21
21
  end
22
22
 
23
23
  def initialize(&block)
24
- @pepper = "" # no pepper set
25
24
  @certs = File.expand_path('conf/certs')
26
25
  @vhosts, @ports, @cluster = {}, {}, nil
27
26
  @null = Storage::Null.new
@@ -39,19 +38,11 @@ module Vines
39
38
  dupes = names.uniq.size != names.size || (@vhosts.keys & names).any?
40
39
  raise "one host definition per domain allowed" if dupes
41
40
  names.each do |name|
42
- if name.eql? "diaspora"
43
- @vhosts[domain_name] = Host.new(self, domain_name, &block)
44
- else
45
- @vhosts[name] = Host.new(self, name, &block)
46
- end
41
+ @vhosts[name] = Host.new(self, name, &block)
47
42
  end
48
43
  end
49
44
 
50
- def pepper(pepper=nil)
51
- pepper ? @pepper = pepper : @pepper
52
- end
53
-
54
- def domain_name
45
+ def diaspora_domain
55
46
  AppConfig.environment.url
56
47
  .gsub(/^http(s){0,1}:\/\/|\/$/, '')
57
48
  .to_s rescue "localhost"
@@ -78,7 +69,7 @@ module Vines
78
69
  unless File.exists?(file)
79
70
  File.new(file, 'w') rescue raise "log directory doesn't exists"
80
71
  end
81
-
72
+
82
73
  if File.exists?(file)
83
74
  Vines::Log.set_log_file(file)
84
75
  end
@@ -158,10 +149,10 @@ module Vines
158
149
  # Returns true if server-to-server connections are allowed with the
159
150
  # given domain.
160
151
  def s2s?(domain)
161
- # NOTE: Disabled whitelisting; It is necessary to allow
162
- # anonymous hosts, otherwise everyone has to add all hosts manually
163
- # TODO: Create a blacklist in case we have to block a malicious host
164
- @ports[:server] # && @ports[:server].hosts.include?(domain.to_s)
152
+ # Disabled whitelisting to allow anonymous hosts,
153
+ # otherwise everyone has to add manually all hosts.
154
+ # Using blacklist in case we have to block a malicious host.
155
+ @ports[:server] && !@ports[:server].blacklist.include?(domain.to_s)
165
156
  end
166
157
 
167
158
  # Return true if the server is a member of a cluster, serving the same
@@ -0,0 +1,35 @@
1
+ # ############################################################## #
2
+ # Do NOT touch this file you'll find the options in diaspora.yml #
3
+ # ############################################################## #
4
+
5
+ Vines::Config.configure do
6
+ log AppConfig.chat.server.log.file.to_s do
7
+ level AppConfig.chat.server.log.level.to_sym
8
+ end
9
+
10
+ certs AppConfig.chat.server.certs.to_s
11
+
12
+ host diaspora_domain do
13
+ cross_domain_messages AppConfig.chat.server.cross_domain_messages
14
+ accept_self_signed AppConfig.chat.server.accept_self_signed
15
+ storage 'sql'
16
+ end
17
+
18
+ client AppConfig.chat.server.c2s.address.to_s, AppConfig.chat.server.c2s.port.to_i do
19
+ max_stanza_size AppConfig.chat.server.c2s.max_stanza_size.to_i
20
+ max_resources_per_account AppConfig.chat.server.c2s.max_resources_per_account.to_i
21
+ end
22
+
23
+ server AppConfig.chat.server.s2s.address.to_s, AppConfig.chat.server.s2s.port.to_i do
24
+ max_stanza_size AppConfig.chat.server.s2s.max_stanza_size.to_i
25
+ blacklist AppConfig.chat.server.s2s.blacklist.get
26
+ end
27
+
28
+ http AppConfig.chat.server.bosh.address.to_s, AppConfig.chat.server.bosh.port.to_i do
29
+ bind AppConfig.chat.server.bosh.bind.to_s
30
+ max_stanza_size AppConfig.chat.server.bosh.max_stanza_size.to_i
31
+ max_resources_per_account AppConfig.chat.server.bosh.max_resources_per_account.to_i
32
+ root 'public'
33
+ vroute ''
34
+ end
35
+ end
@@ -11,9 +11,10 @@ module Vines
11
11
 
12
12
  def initialize(config, name, &block)
13
13
  @config, @name = config, name.downcase
14
- @storage, @ldap = nil, nil
14
+ @storage = nil
15
15
  @cross_domain_messages = false
16
16
  @private_storage = false
17
+ @accept_self_signed = false
17
18
  @components, @pubsubs = {}, {}
18
19
  validate_domain(@name)
19
20
  instance_eval(&block)
@@ -24,15 +25,17 @@ module Vines
24
25
  if name
25
26
  raise "one storage mechanism per host allowed" if @storage
26
27
  @storage = Storage.from_name(name, &block)
27
- @storage.ldap = @ldap
28
28
  else
29
29
  @storage
30
30
  end
31
31
  end
32
32
 
33
- def ldap(host='localhost', port=636, &block)
34
- @ldap = Storage::Ldap.new(host, port, &block)
35
- @storage.ldap = @ldap if @storage
33
+ def accept_self_signed(enabled)
34
+ @accept_self_signed = !!enabled
35
+ end
36
+
37
+ def accept_self_signed?
38
+ @accept_self_signed
36
39
  end
37
40
 
38
41
  def cross_domain_messages(enabled)
@@ -59,16 +59,16 @@ module Vines
59
59
 
60
60
  class ServerPort < Port
61
61
  def initialize(config, host='0.0.0.0', port=5269, &block)
62
- @hosts, @stream = [], Vines::Stream::Server
62
+ @blacklist, @stream = [], Vines::Stream::Server
63
63
  super(config, host, port, &block)
64
64
  end
65
65
 
66
- def hosts(*hosts)
67
- if hosts.any?
68
- @hosts << hosts
69
- @hosts.flatten!
66
+ def blacklist(*blacklist)
67
+ if blacklist.any?
68
+ @blacklist << blacklist
69
+ @blacklist.flatten!
70
70
  else
71
- @hosts
71
+ @blacklist
72
72
  end
73
73
  end
74
74
  end
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+
3
+ module Vines
4
+ class Stanza
5
+ class Iq
6
+ class Ping < Iq
7
+ include Vines::Log
8
+
9
+ NS = NAMESPACES[:disco_info]
10
+ NODE = NAMESPACES[:offline]
11
+
12
+ register "/iq[@id and @type='get']/ns:offline", 'ns' => NODE
13
+
14
+ def process
15
+ log.debug("heelo world::#{to_result.to_yaml}")
16
+ #return if route_iq || !allowed?
17
+ #stream.write(to_result)
18
+ result = to_result.tap do |el|
19
+ el << el.document.create_element('query') do |query|
20
+ query.default_namespace = NS
21
+ query['node'] = NODE
22
+ items = [
23
+ [
24
+ :jid => 'romeo@montague.net',
25
+ :node => '2003-02-27T22:49:17.008Z',
26
+ :name => 'mercutio@shakespeare.lit/pda'
27
+ ],
28
+ [
29
+ :jid => 'romeo@montague.net',
30
+ :node => '2003-02-27T22:52:51.270Z',
31
+ :name => 'juliet@capulet.com/balcony'
32
+ ]
33
+ ]
34
+ items(query, items)
35
+ end
36
+ end
37
+ stream.write(result)
38
+ end
39
+
40
+ private
41
+
42
+ def items(query, *items)
43
+ items.flatten.each do |item|
44
+ query << query.document.create_element(
45
+ 'item',
46
+ 'jid' => item[:jid],
47
+ 'node' => item[:node],
48
+ 'name'=> item[:name])
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/vines/storage.rb CHANGED
@@ -4,12 +4,14 @@ module Vines
4
4
  class Storage
5
5
  include Vines::Log
6
6
 
7
- attr_accessor :ldap
8
-
9
7
  @@nicks = {}
10
8
 
11
9
  # Register a nickname that can be used in the config file to specify this
12
10
  # storage implementation.
11
+ #
12
+ # name - The String name for this storage backend.
13
+ #
14
+ # Returns nothing.
13
15
  def self.register(name)
14
16
  @@nicks[name.to_sym] = self
15
17
  end
@@ -25,15 +27,18 @@ module Vines
25
27
  # with blocking IO don't need to worry about threading or blocking the
26
28
  # EventMachine reactor thread if they wrap their methods with this one.
27
29
  #
28
- # For example:
29
- # def find_user(jid)
30
- # some_blocking_lookup(jid)
31
- # end
32
- # defer :find_user
30
+ # Examples
31
+ #
32
+ # def find_user(jid)
33
+ # some_blocking_lookup(jid)
34
+ # end
35
+ # defer :find_user
33
36
  #
34
37
  # Storage classes that use asynchronous IO (through an EventMachine
35
38
  # enabled library like em-http-request or em-redis) don't need any special
36
39
  # consideration and must not use this method.
40
+ #
41
+ # Returns nothing.
37
42
  def self.defer(method)
38
43
  old = instance_method(method)
39
44
  define_method method do |*args|
@@ -45,40 +50,26 @@ module Vines
45
50
  end
46
51
  end
47
52
 
48
- # Wrap an authenticate method with a new method that uses LDAP if it's
49
- # enabled in the config file. If LDAP is not enabled, invoke the original
50
- # authenticate method as usual. This allows storage classes to implement
51
- # their native authentication logic and not worry about handling LDAP.
52
- #
53
- # For example:
54
- # def authenticate(username, password)
55
- # some_user_lookup_by_password(username, password)
56
- # end
57
- # wrap_ldap :authenticate
58
- def self.wrap_ldap(method)
59
- old = instance_method(method)
60
- define_method method do |*args|
61
- ldap? ? authenticate_with_ldap(*args) : old.bind(self).call(*args)
62
- end
63
- end
64
-
65
53
  # Wrap a method with Fiber yield and resume logic. The method must yield
66
54
  # its result to a block. This makes it easier to write asynchronous
67
- # implementations of +authenticate+, +find_user+, and +save_user+ that
55
+ # implementations of `authenticate`, `find_user`, and `save_user` that
68
56
  # block and return a result rather than yielding.
69
57
  #
70
- # For example:
71
- # def find_user(jid)
72
- # http = EM::HttpRequest.new(url).get
73
- # http.callback { yield build_user_from_http_response(http) }
74
- # end
75
- # fiber :find_user
58
+ # Examples
59
+ #
60
+ # def find_user(jid)
61
+ # http = EM::HttpRequest.new(url).get
62
+ # http.callback { yield build_user_from_http_response(http) }
63
+ # end
64
+ # fiber :find_user
76
65
  #
77
- # Because +find_user+ has been wrapped in Fiber logic, we can call it
66
+ # Because `find_user` has been wrapped in Fiber logic, we can call it
78
67
  # synchronously even though it uses asynchronous EventMachine calls.
79
68
  #
80
- # user = storage.find_user('alice@wonderland.lit')
81
- # puts user.nil?
69
+ # user = storage.find_user('alice@wonderland.lit')
70
+ # puts user.nil?
71
+ #
72
+ # Returns nothing.
82
73
  def self.fiber(method)
83
74
  old = instance_method(method)
84
75
  define_method method do |*args|
@@ -90,114 +81,162 @@ module Vines
90
81
  end
91
82
  end
92
83
 
93
- # Return +true+ if users are authenticated against an LDAP directory.
94
- def ldap?
95
- !!ldap
96
- end
97
-
98
- # Validate the username and password pair and return a +Vines::User+ object
99
- # on success. Return +nil+ on failure.
84
+ # Validate the username and password pair.
85
+ #
86
+ # username - The String login JID to verify.
87
+ # password - The String password the user presented to the server.
100
88
  #
101
- # For example:
102
- # user = storage.authenticate('alice@wonderland.lit', 'secr3t')
103
- # puts user.nil?
89
+ # Examples
90
+ #
91
+ # user = storage.authenticate('alice@wonderland.lit', 'secr3t')
92
+ # puts user.nil?
104
93
  #
105
94
  # This default implementation validates the password against a bcrypt hash
106
95
  # of the password stored in the database. Sub-classes not using bcrypt
107
96
  # passwords must override this method.
97
+ #
98
+ # Returns a Vines::User object on success, nil on failure.
108
99
  def authenticate(username, password)
109
100
  user = find_user(username)
110
101
  hash = BCrypt::Password.new(user.password) rescue nil
111
102
  (hash && hash == password) ? user : nil
112
103
  end
113
- wrap_ldap :authenticate
114
104
 
115
- # Return the +Vines::User+ associated with the JID. Return +nil+ if the user
116
- # could not be found. JID may be +nil+, a +String+, or a +Vines::JID+
117
- # object. It may be a bare JID or a full JID. Implementations of this method
118
- # must convert the JID to a bare JID before searching for the user in the
119
- # database.
105
+ # Find the user in the storage database by their unique JID.
106
+ #
107
+ # jid - The String or JID of the user, possibly nil. This may be either a
108
+ # bare JID or full JID. Implementations of this method must convert
109
+ # the JID to a bare JID before searching for the user in the database.
120
110
  #
121
- # user = storage.find_user('alice@wonderland.lit')
122
- # puts user.nil?
111
+ # Examples
112
+ #
113
+ # # Bare JID lookup.
114
+ # user = storage.find_user('alice@wonderland.lit')
115
+ # puts user.nil?
116
+ #
117
+ # # Full JID lookup.
118
+ # user = storage.find_user('alice@wonderland.lit/tea')
119
+ # puts user.nil?
120
+ #
121
+ # Returns the User identified by the JID, nil if not found.
123
122
  def find_user(jid)
124
123
  raise 'subclass must implement'
125
124
  end
126
125
 
127
- # Persist the +Vines::User+ object to the database and return when the save
128
- # is complete.
126
+ # Persist the user to the database, and return when the save is complete.
127
+ #
128
+ # user - The User to persist.
129
+ #
130
+ # Examples
131
+ #
132
+ # alice = Vines::User.new(jid: 'alice@wonderland.lit')
133
+ # storage.save_user(alice)
134
+ # puts 'saved'
129
135
  #
130
- # alice = Vines::User.new(:jid => 'alice@wonderland.lit')
131
- # storage.save_user(alice)
132
- # puts 'saved'
136
+ # Returns nothing.
133
137
  def save_user(user)
134
138
  raise 'subclass must implement'
135
139
  end
136
140
 
137
- # Return the Nokogiri::XML::Node for the vcard stored for this JID. Return
138
- # nil if the vcard could not be found. JID may be +nil+, a +String+, or a
139
- # +Vines::JID+ object. It may be a bare JID or a full JID. Implementations
140
- # of this method must convert the JID to a bare JID before searching for the
141
- # vcard in the database.
141
+ # Find the user's vcard by their unique JID.
142
142
  #
143
- # card = storage.find_vcard('alice@wonderland.lit')
144
- # puts card.nil?
143
+ # jid - The String or JID of the user, possibly nil. This may be either a
144
+ # bare JID or full JID. Implementations of this method must convert
145
+ # the JID to a bare JID before searching for the vcard in the database.
146
+ #
147
+ # Examples
148
+ #
149
+ # card = storage.find_vcard('alice@wonderland.lit')
150
+ # puts card.nil?
151
+ #
152
+ # Returns the vcard's Nokogiri::XML::Node, nil if not found.
145
153
  def find_vcard(jid)
146
154
  raise 'subclass must implement'
147
155
  end
148
156
 
149
- # Save the vcard to the database and return when the save is complete. JID
150
- # may be a +String+ or a +Vines::JID+ object. It may be a bare JID or a
151
- # full JID. Implementations of this method must convert the JID to a bare
152
- # JID before saving the vcard. Card is a +Nokogiri::XML::Node+ object.
157
+ # Save the vcard to the database, and return when the save is complete.
158
+ #
159
+ # jid - The String or JID of the user, possibly nil. This may be either a
160
+ # bare JID or full JID. Implementations of this method must convert
161
+ # the JID to a bare JID before saving the vcard.
162
+ # card - The vcard's Nokogiri::XML::Node.
163
+ #
164
+ # Examples
165
+ #
166
+ # card = Nokogiri::XML('<vCard>...</vCard>').root
167
+ # storage.save_vcard('alice@wonderland.lit', card)
168
+ # puts 'saved'
153
169
  #
154
- # card = Nokogiri::XML('<vCard>...</vCard>').root
155
- # storage.save_vcard('alice@wonderland.lit', card)
156
- # puts 'saved'
170
+ # Returns nothing.
157
171
  def save_vcard(jid, card)
158
172
  raise 'subclass must implement'
159
173
  end
160
174
 
161
- # Return the Nokogiri::XML::Node for the XML fragment stored for this JID.
162
- # Return nil if the fragment could not be found. JID may be +nil+, a
163
- # +String+, or a +Vines::JID+ object. It may be a bare JID or a full JID.
164
- # Implementations of this method must convert the JID to a bare JID before
165
- # searching for the fragment in the database.
166
- #
167
- # Private XML storage uniquely identifies fragments by JID, root element name,
175
+ # Find the private XML fragment previously stored by the user. Private
176
+ # XML storage uniquely identifies fragments by JID, root element name,
168
177
  # and root element namespace.
169
178
  #
170
- # root = Nokogiri::XML('<custom xmlns="urn:custom:ns"/>').root
171
- # fragment = storage.find_fragment('alice@wonderland.lit', root)
172
- # puts fragment.nil?
179
+ # jid - The String or JID of the user, possibly nil. This may be either a
180
+ # bare JID or full JID. Implementations of this method must convert
181
+ # the JID to a bare JID before searching for the fragment in the database.
182
+ # node - The XML::Node that uniquely identifies the fragment by element
183
+ # name and namespace.
184
+ #
185
+ # Examples
186
+ #
187
+ # root = Nokogiri::XML('<custom xmlns="urn:custom:ns"/>').root
188
+ # fragment = storage.find_fragment('alice@wonderland.lit', root)
189
+ # puts fragment.nil?
190
+ #
191
+ # Returns the fragment's Nokogiri::XML::Node or nil if not found.
173
192
  def find_fragment(jid, node)
174
193
  raise 'subclass must implement'
175
194
  end
176
195
 
177
- # Save the XML fragment to the database and return when the save is complete.
178
- # JID may be a +String+ or a +Vines::JID+ object. It may be a bare JID or a
179
- # full JID. Implementations of this method must convert the JID to a bare
180
- # JID before saving the fragment. Fragment is a +Nokogiri::XML::Node+ object.
196
+ # Save the XML fragment to the database, and return when the save is complete.
197
+ #
198
+ # jid - The String or JID of the user, possibly nil. This may be
199
+ # either a bare JID or full JID. Implementations of this method
200
+ # must convert the JID to a bare JID before searching for the
201
+ # fragment.
202
+ # fragment - The XML::Node to save.
203
+ #
204
+ # Examples
181
205
  #
182
- # fragment = Nokogiri::XML('<custom xmlns="urn:custom:ns">some data</custom>').root
183
- # storage.save_fragment('alice@wonderland.lit', fragment)
184
- # puts 'saved'
206
+ # fragment = Nokogiri::XML('<custom xmlns="urn:custom:ns">some data</custom>').root
207
+ # storage.save_fragment('alice@wonderland.lit', fragment)
208
+ # puts 'saved'
209
+ #
210
+ # Returns nothing.
185
211
  def save_fragment(jid, fragment)
186
212
  raise 'subclass must implement'
187
213
  end
188
214
 
189
215
  private
190
216
 
191
- # Return true if any of the arguments are nil or empty strings.
192
- # For example:
193
- # username, password = 'alice@wonderland.lit', ''
194
- # empty?(username, password) #=> true
217
+ # Determine if any of the arguments are nil or empty strings.
218
+ #
219
+ # Examples
220
+ #
221
+ # username, password = 'alice@wonderland.lit', ''
222
+ # empty?(username, password) #=> true
223
+ #
224
+ # Returns true if any of the arguments are nil or empty strings.
195
225
  def empty?(*args)
196
226
  args.flatten.any? {|arg| (arg || '').strip.empty? }
197
227
  end
198
228
 
199
- # Return a +proc+ suitable for running on the +EM.defer+ thread pool that traps
200
- # and logs any errors thrown by the provided block.
229
+ # Create a proc suitable for running on the EM.defer thread pool, that
230
+ # traps and logs any errors thrown by the provided block.
231
+ #
232
+ # block - The block to wrap in error handling.
233
+ #
234
+ # Examples
235
+ #
236
+ # op = operation { do_something_on_thread_pool() }
237
+ # EM.defer(op)
238
+ #
239
+ # Returns a Proc.
201
240
  def operation
202
241
  proc do
203
242
  begin
@@ -208,32 +247,5 @@ module Vines
208
247
  end
209
248
  end
210
249
  end
211
-
212
- # Return a +Vines::User+ object if we are able to bind to the LDAP server
213
- # using the username and password. Return +nil+ if authentication failed. If
214
- # authentication succeeds, but the user is not yet stored in our database,
215
- # save the user to the database.
216
- def authenticate_with_ldap(username, password, &block)
217
- op = operation { ldap.authenticate(username, password) }
218
- cb = proc {|user| save_ldap_user(user, &block) }
219
- EM.defer(op, cb)
220
- end
221
- fiber :authenticate_with_ldap
222
-
223
- # Save missing users to the storage database after they're authenticated with
224
- # LDAP. This allows admins to define users once in LDAP and have them sync
225
- # to the chat database the first time they successfully sign in.
226
- def save_ldap_user(user, &block)
227
- Fiber.new do
228
- if user.nil?
229
- block.call
230
- elsif found = find_user(user.jid)
231
- block.call(found)
232
- else
233
- save_user(user)
234
- block.call(user)
235
- end
236
- end.resume
237
- end
238
250
  end
239
251
  end