blur 2.1.3 → 2.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Blur
4
4
  class Client
@@ -24,85 +24,98 @@ module Blur
24
24
  # # RPL_WHOISUSER
25
25
  # # <nick> <user> <host> * :<real name>
26
26
  # def got_whois_user network, message
27
- # puts "nick: #{message.parameters[0]} user: #{message.parameters[1]} host: #{message.parameters[2]} "
27
+ # puts "nick: #{message.parameters[0]} user: #{message.parameters[1]} host: #{message.parameters[2]} ..."
28
28
  # end
29
- #
29
+ #
30
30
  # @see http://www.irchelp.org/irchelp/rfc/chapter6.html
31
31
  module Handling
32
-
33
32
  # Called when the MOTD was received, which also means it is ready.
34
33
  #
35
34
  # == Callbacks:
36
35
  # Emits +:connection_ready+ with the parameter +network+.
37
36
  #
38
37
  # Automatically joins the channels specified in +:channels+.
39
- def got_end_of_motd network, message
38
+ def got_end_of_motd network, _message
40
39
  emit :connection_ready, network
41
-
40
+
42
41
  network.options['channels'].each do |channel|
43
42
  network.join channel
44
43
  end
45
44
  end
46
-
45
+
47
46
  # Called when the namelist of a channel was received.
48
47
  def got_name_reply network, message
49
48
  name = message.parameters[2] # Channel name.
50
49
  nicks = message.parameters[3].split.map do |nick|
51
50
  # Slice the nick if the first character is a user mode prefix.
52
- if network.user_prefixes.include? nick.chr
53
- nick.slice! 0
54
- end
51
+ nick.slice! 0 if network.user_prefixes.include? nick.chr
55
52
 
56
53
  nick
57
54
  end
58
-
59
- if channel = find_or_create_channel(name, network)
60
- users = nicks.map{|nick| find_or_create_user nick, network }
61
- users.each do |user|
62
- user.channels << channel
63
- channel.users << user unless channel.users.include? user
64
- end
65
55
 
66
- emit :channel_who_reply, channel
56
+ return unless (channel = find_or_create_channel(name, network))
57
+
58
+ users = nicks.map { |nick| find_or_create_user nick, network }
59
+ users.each do |user|
60
+ user.channels << channel
61
+ channel.users << user unless channel.users.include? user
67
62
  end
63
+
64
+ emit :channel_who_reply, channel
68
65
  end
69
-
66
+
70
67
  # Called when a channel topic was changed.
71
68
  #
72
69
  # == Callbacks:
73
70
  # Emits :topic_change with the parameters +channel+ and +topic+.
74
71
  def got_channel_topic network, message
75
72
  _, channel_name, topic = message.parameters
76
-
77
- if channel = find_or_create_channel(channel_name, network)
78
- emit :channel_topic, channel, topic
79
73
 
80
- channel.topic = topic
81
- end
74
+ return unless (channel = find_or_create_channel(channel_name, network))
75
+
76
+ emit :channel_topic, channel, topic
77
+
78
+ channel.topic = topic
82
79
  end
83
-
80
+
84
81
  # Called when the server needs to verify that we're alive.
85
82
  def got_ping network, message
83
+ network.last_pong_time = Time.now
86
84
  network.transmit :PONG, message.parameters[0]
87
85
 
88
- emit :network_ping, message.parameters[0]
86
+ emit :network_ping, network, message.parameters[0]
87
+ end
88
+
89
+ # Called when the server reponds to our periodic PINGs.
90
+ def got_pong network, message
91
+ network.last_pong_time = Time.now
92
+
93
+ emit :network_pong, network, message.parameters[0]
89
94
  end
90
-
95
+
91
96
  # Called when a user changed nickname.
92
97
  #
93
98
  # == Callbacks:
94
99
  # Emits :user_rename with the parameters +channel+, +user+ and +new_nick+
95
100
  def got_nick network, message
96
101
  old_nick = message.prefix.nick
97
-
98
- if user = network.users.delete(old_nick)
102
+
103
+ # Update or own nickname if has been changed by the server
104
+ if network.nickname == old_nick
99
105
  new_nick = message.parameters[0]
100
- emit :user_rename, user, new_nick
101
- user.nick = new_nick
102
- network.users[new_nick] = user
106
+
107
+ emit :nick, new_nick
108
+ network.nickname = new_nick
103
109
  end
110
+
111
+ return unless (user = network.users.delete(old_nick))
112
+
113
+ new_nick = message.parameters[0]
114
+ emit :user_rename, user, new_nick
115
+ user.nick = new_nick
116
+ network.users[new_nick] = user
104
117
  end
105
-
118
+
106
119
  # Called when a message was received (both channel and private messages).
107
120
  #
108
121
  # == Callbacks:
@@ -114,10 +127,11 @@ module Blur
114
127
  # @note Messages are contained as strings.
115
128
  def got_privmsg network, message
116
129
  return unless message.prefix.nick # Ignore all server privmsgs
130
+
117
131
  name, msg = message.parameters
118
132
 
119
- if channel = network.channels[name]
120
- unless user = network.users[message.prefix.nick]
133
+ if (channel = network.channels[name])
134
+ unless (user = network.users[message.prefix.nick])
121
135
  user = User.new message.prefix.nick, network
122
136
  end
123
137
 
@@ -126,7 +140,7 @@ module Blur
126
140
 
127
141
  emit :message, user, channel, msg
128
142
  else # This is a private message
129
- unless user = network.users[message.prefix.nick]
143
+ unless (user = network.users[message.prefix.nick])
130
144
  user = User.new message.prefix.nick, network
131
145
  user.name = message.prefix.user
132
146
  user.host = message.prefix.host
@@ -135,7 +149,7 @@ module Blur
135
149
  emit :private_message, user, msg
136
150
  end
137
151
  end
138
-
152
+
139
153
  # Called when a user joined a channel.
140
154
  #
141
155
  # == Callbacks:
@@ -146,30 +160,29 @@ module Blur
146
160
  user = find_or_create_user message.prefix.nick, network
147
161
  user.name = message.prefix.user
148
162
  user.host = message.prefix.host
149
-
150
- if channel = find_or_create_channel(channel_name, network)
151
- _user_join_channel user, channel
152
163
 
153
- emit :user_entered, channel, user
154
- end
164
+ return unless (channel = find_or_create_channel(channel_name, network))
165
+
166
+ _user_join_channel user, channel
167
+
168
+ emit :user_entered, channel, user
155
169
  end
156
-
170
+
157
171
  # Called when a user left a channel.
158
172
  #
159
173
  # == Callbacks:
160
174
  # Emits +:user_left+ with the parameters +channel+ and +user+.
161
175
  def got_part network, message
162
176
  channel_name = message.parameters[0]
163
-
164
- if channel = network.channels[channel_name]
165
- if user = network.users[message.prefix.nick]
166
- _user_part_channel user, channel
167
-
168
- emit :user_left, channel, user
169
- end
170
- end
177
+
178
+ return unless (channel = network.channels[channel_name])
179
+ return unless (user = network.users[message.prefix.nick])
180
+
181
+ _user_part_channel user, channel
182
+
183
+ emit :user_left, channel, user
171
184
  end
172
-
185
+
173
186
  # Called when a user disconnected from a network.
174
187
  #
175
188
  # == Callbacks:
@@ -177,17 +190,17 @@ module Blur
177
190
  def got_quit network, message
178
191
  nick = message.prefix.nick
179
192
  reason = message.parameters[2]
180
-
181
- if user = network.users[nick]
182
- user.channels.each do |channel|
183
- channel.users.delete user
184
- end
185
193
 
186
- emit :user_quit, user, reason
187
- network.users.delete nick
194
+ return unless (user = network.users[nick])
195
+
196
+ user.channels.each do |channel|
197
+ channel.users.delete user
188
198
  end
199
+
200
+ emit :user_quit, user, reason
201
+ network.users.delete nick
189
202
  end
190
-
203
+
191
204
  # Called when a user was kicked from a channel.
192
205
  #
193
206
  # == Callbacks:
@@ -197,32 +210,30 @@ module Blur
197
210
  # +kicker+ is the user that kicked +kickee+.
198
211
  def got_kick network, message
199
212
  name, target, reason = message.parameters
200
-
201
- if channel = network.channels[name]
202
- if kicker = network.users[message.prefix.nick]
203
- if kickee = network.users[target]
204
- _user_part_channel kickee, channel
205
-
206
- emit :user_kicked, kicker, channel, kickee, reason
207
- end
208
- end
209
- end
213
+
214
+ return unless (channel = network.channels[name])
215
+ return unless (kicker = network.users[message.prefix.nick])
216
+ return unless (kickee = network.users[target])
217
+
218
+ _user_part_channel kickee, channel
219
+
220
+ emit :user_kicked, kicker, channel, kickee, reason
210
221
  end
211
-
222
+
212
223
  # Called when a topic was changed for a channel.
213
224
  #
214
225
  # == Callbacks:
215
226
  # Emits :topic with the parameters +user+, +channel+ and +topic+.
216
227
  def got_topic network, message
217
- channel_name, topic = message.parameters
218
-
219
- if channel = network.channels[channel_name]
220
- if user = network.users[message.prefix.nick]
221
- emit :topic, user, channel, topic
222
- end
223
-
224
- channel.topic = topic
228
+ _channel_name, topic = message.parameters
229
+
230
+ return unless (channel = network.channels[channel.name])
231
+
232
+ if (user = network.users[message.prefix.nick])
233
+ emit :topic, user, channel, topic
225
234
  end
235
+
236
+ channel.topic = topic
226
237
  end
227
238
 
228
239
  # Called when a channel or a users flags was altered.
@@ -233,56 +244,69 @@ module Blur
233
244
  # === When it's user modes:
234
245
  # Emits +:user_mode+ with the parameters +user+ and +modes+.
235
246
  def got_mode network, message
236
- name, modes, limit, nick, mask = message.parameters
247
+ name, _modes, _limit, _nick, _mask = message.parameters
237
248
 
238
- if channel = network.channels[name]
239
- # FIXME
240
- end
249
+ return unless (_channel = network.channels[name])
241
250
  end
242
251
 
243
252
  # Called when the network announces its ISUPPORT parameters.
244
253
  def got_005 network, message
245
254
  params = message.parameters[1..-2]
246
255
 
247
- network.isupport.parse *params
256
+ network.isupport.parse(*params)
248
257
  end
249
258
 
250
259
  # Received when the server supports capability negotiation.
260
+ #
261
+ # CAP * LS :multi-prefix sasl
251
262
  def got_cap network, message
252
- id, command = message.parameters[0..1]
263
+ _id, command = message.parameters[0..1]
253
264
 
254
265
  case command
266
+ when 'LS'
267
+ capabilities = message.parameters[2]&.split
268
+ req = []
269
+
270
+ req << 'sasl' if network.sasl? && capabilities.include?('sasl')
271
+ req << 'account-tag' if capabilities.include?('account-tag')
272
+
273
+ network.transmit :CAP, 'REQ', req.join(' ') if req.any?
274
+
275
+ capabilities.each { |name| network.capabilities.push name }
276
+
277
+ emit :network_capabilities, network, capabilities
278
+
255
279
  when 'ACK'
256
280
  capabilities = message.parameters[2]&.split
257
281
 
258
- if capabilities&.include? 'sasl' and network.sasl?
259
- network.transmit :AUTHENTICATE, 'PLAIN'
260
- else
261
- network.cap_end
262
- end
282
+ network.transmit :AUTHENTICATE, 'PLAIN' if capabilities&.include?('sasl') && network.sasl?
283
+
284
+ network.cap_end if network.waiting_for_cap
263
285
  when 'NAK'
264
286
  capabilities = message.parameters[2]&.split
265
287
 
266
- if capabilities&.include? 'sasl' and network.sasl?
288
+ if capabilities&.include?('sasl') && network.sasl?
267
289
  puts "The server does not support SASL, but you've configured it " \
268
- "as such! Disconnecting!"
290
+ 'as such! Disconnecting!'
269
291
 
270
292
  network.disconnect
271
293
  end
272
-
273
294
  end
274
295
  end
275
296
 
276
297
  def got_001 network, message
277
- if network.waiting_for_cap
278
- network.abort_cap_neg
279
- end
298
+ network.abort_cap_neg if network.waiting_for_cap
299
+
300
+ # Get our nickname from the server
301
+ nickname = message.parameters[0]
302
+ network.nickname = nickname
280
303
  end
281
304
 
282
305
  def got_authenticate network, message
283
306
  case message.parameters[0]
284
307
  when '+'
285
308
  return unless network.sasl?
309
+
286
310
  sasl = network.options['sasl']
287
311
 
288
312
  response = "#{sasl['username']}\x00#{sasl['username']}\x00#{sasl['password']}"
@@ -292,37 +316,41 @@ module Blur
292
316
 
293
317
  # :server 900 <nick> <nick>!<ident>@<host> <account> :You are now logged in as <user>
294
318
  # RPL_LOGGEDIN SASL
295
- def got_900 network, message
296
- if network.waiting_for_cap
297
- network.cap_end
298
- end
319
+ def got_900 network, _message
320
+ network.cap_end if network.waiting_for_cap
299
321
  end
300
322
 
301
323
  # :server 904 <nick> :SASL authentication failed
302
324
  # ERR_SASLFAIL
303
325
  def got_904 network, message
304
- nick, message = message.parameters
326
+ _nick, _message = message.parameters
305
327
 
306
- puts "SASL authentication failed! Disconnecting!"
328
+ puts 'SASL authentication failed! Disconnecting!'
307
329
 
308
330
  network.disconnect
309
331
  end
310
332
 
311
- alias_method :got_353, :got_name_reply
312
- alias_method :got_422, :got_end_of_motd
313
- alias_method :got_376, :got_end_of_motd
314
- alias_method :got_332, :got_channel_topic
333
+ def got_nickname_in_use network, message
334
+ nickname = network.options['nickname']
335
+ network.transmit :NICK, "#{nickname}_"
336
+ end
337
+
338
+ alias got_353 got_name_reply
339
+ alias got_422 got_end_of_motd
340
+ alias got_376 got_end_of_motd
341
+ alias got_332 got_channel_topic
342
+ alias got_433 got_nickname_in_use
315
343
 
316
- private
344
+ private
317
345
 
318
346
  def _user_part_channel user, channel
319
347
  user.channels.delete channel
320
348
  channel.users.delete user
321
349
 
322
350
  # Forget the user if we no longer share any channels.
323
- if user.channels.empty?
324
- user.network.users.delete user.nick
325
- end
351
+ return unless user.channels.empty?
352
+
353
+ user.network.users.delete user.nick
326
354
  end
327
355
 
328
356
  def _user_join_channel user, channel
@@ -331,7 +359,7 @@ module Blur
331
359
  end
332
360
 
333
361
  def find_or_create_user nick, network
334
- unless user = network.users[nick]
362
+ unless (user = network.users[nick])
335
363
  user = User.new nick, network
336
364
  network.users[nick] = user
337
365
  emit :user_created, user
@@ -341,7 +369,7 @@ module Blur
341
369
  end
342
370
 
343
371
  def find_or_create_channel name, network
344
- unless channel = network.channels[name]
372
+ unless (channel = network.channels[name])
345
373
  channel = Channel.new name, network
346
374
  network.channels[name] = channel
347
375
  emit :channel_created, channel
@@ -350,6 +378,5 @@ module Blur
350
378
  channel
351
379
  end
352
380
  end
353
-
354
381
  end
355
382
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Blur
4
4
  class Network
@@ -13,14 +13,23 @@ module Blur
13
13
  class Connection < EM::Protocols::LineAndTextProtocol
14
14
  SSLValidationError = Class.new StandardError
15
15
 
16
+ # @return [Float] the default connection timeout interval in seconds.
17
+ DEFAULT_CONNECT_TIMEOUT_INTERVAL = 30
18
+
16
19
  # Check whether or not connection is established.
17
- def established?; @connected == true end
20
+ def established?
21
+ @connected == true
22
+ end
18
23
 
19
24
  # EventMachine instantiates this class, and then sends event messages to
20
25
  # that instance.
21
26
  def initialize network
22
27
  @network = network
23
28
  @connected = false
29
+ connect_timeout = network.options.fetch 'connect_timeout',
30
+ DEFAULT_CONNECT_TIMEOUT_INTERVAL
31
+
32
+ self.pending_connect_timeout = connect_timeout
24
33
 
25
34
  super
26
35
  end
@@ -28,11 +37,10 @@ module Blur
28
37
  # Called when a new connection is being set up, all we're going to use
29
38
  # it for is to enable SSL/TLS on our connection.
30
39
  def post_init
31
- if @network.secure?
32
- verify_peer = (@network.options[:ssl_no_verify] ? false : true)
40
+ return unless @network.secure?
33
41
 
34
- start_tls verify_peer: verify_peer
35
- end
42
+ verify_peer = (@network.options[:ssl_no_verify] ? false : true)
43
+ start_tls verify_peer: verify_peer
36
44
  end
37
45
 
38
46
  # Called when a line was received, the connection sends it to the network
@@ -61,12 +69,8 @@ module Blur
61
69
  ssl_cert_file = @network.options[:ssl_cert_file]
62
70
  peer_certificate = OpenSSL::X509::Certificate.new peer_cert
63
71
 
64
- if ssl_cert_file
65
- unless File.readable? ssl_cert_file
66
- raise SSLValidationError, "Could not read the CA certificate file."
67
-
68
- return false
69
- end
72
+ if ssl_cert_file && !File.readable?(ssl_cert_file)
73
+ raise SSLValidationError, 'Could not read the CA certificate file.'
70
74
  end
71
75
 
72
76
  if fingerprint_verification?
@@ -75,9 +79,7 @@ module Blur
75
79
 
76
80
  if fingerprint != peer_fingerprint
77
81
  raise SSLValidationError,
78
- "Expected fingerprint '#{fingerprint}', but got '#{peer_fingerprint}'"
79
-
80
- return false
82
+ "Expected fingerprint '#{fingerprint}', but got '#{peer_fingerprint}'"
81
83
  end
82
84
  end
83
85
 
@@ -85,11 +87,7 @@ module Blur
85
87
  ca_certificate = OpenSSL::X509::Certificate.new File.read ssl_cert_file
86
88
  valid_signature = peer_certificate.verify ca_certificate.public_key
87
89
 
88
- if not valid_signature
89
- raise SSLValidationError, "Certificate verify failed"
90
-
91
- return false
92
- end
90
+ raise SSLValidationError, 'Certificate verify failed' unless valid_signature
93
91
  end
94
92
 
95
93
  true
@@ -98,9 +96,7 @@ module Blur
98
96
  # Called once the connection is finally established.
99
97
  def connection_completed
100
98
  # We aren't completely connected yet if the connection is encrypted.
101
- unless @network.secure?
102
- connected!
103
- end
99
+ connected! unless @network.secure?
104
100
  end
105
101
 
106
102
  # Called just as the connection is being terminated, either by remote or
@@ -112,7 +108,8 @@ module Blur
112
108
  super
113
109
  end
114
110
 
115
- private
111
+ private
112
+
116
113
  # Called when connection has been established.
117
114
  def connected!
118
115
  @connected = true
@@ -122,12 +119,12 @@ module Blur
122
119
 
123
120
  # Returns true if we're expected to verify the certificate fingerprint.
124
121
  def fingerprint_verification?
125
- not @network.options[:ssl_fingerprint].nil?
122
+ !@network.options[:ssl_fingerprint].nil?
126
123
  end
127
124
 
128
125
  # Returns true if we should verify the peer certificate.
129
126
  def certificate_verification?
130
- not @network.options[:ssl_cert_file].nil?
127
+ !@network.options[:ssl_cert_file].nil?
131
128
  end
132
129
 
133
130
  # Get the hexadecimal representation of the certificates public key.
@@ -143,9 +140,8 @@ module Blur
143
140
  fingerprint = @network.options[:ssl_fingerprint]
144
141
 
145
142
  raise SSLValidationError,
146
- "Expected fingerprint '#{fingerprint}' but got '#{peer_fingerprint}'"
143
+ "Expected fingerprint '#{fingerprint}' but got '#{peer_fingerprint}'"
147
144
  end
148
-
149
145
  end
150
146
  end
151
147
  end