Trabe ya no escribe aquí. Puedes encontrarnos en nuestra publicación en Medium: medium.com/trabe.

4Trabes Historias de una empresa en 100 metros cuadrados

El blog de Trabe Soluciones

Net::IMAP y autenticación PLAIN con Ruby 1.8.7

| | Comentarios

Hace poco tuvimos que recuperar correos de un servidor utilizando IMAP (con conexión segura) desde una aplicación legacy que corre sobre Ruby 1.8.7. En principio, era una tarea sencilla, sólo teníamos que usar net/imap: conectarnos, autenticarnos, recuperar los correos y listo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ irb -r
>> require 'net/imap'
=> true
>> session = Net::IMAP.new("mail.server.com", 993, true)
=> #<Net::IMAP:0x19fb2c0 @tagno=0, @continuation_request=nil, ...

>> session.capability
=> ["ACL", "BINARY", "CATENATE", "CHILDREN", "CONDSTORE", "ENABLE", "ESEARCH", "ID", "IDLE", 
    "IMAP4REV1", "LIST-EXTENDED", "LITERAL+", "MULTIAPPEND", "NAMESPACE", "QRESYNC", "QUOTA", 
    "RIGHTS=EKTX", "SASL-IR", "SEARCHRES", "UIDPLUS", "UNSELECT", "WITHIN", "ESORT", "I18NLEVEL=1", 
    "SORT", "THREAD=ORDEREDSUBJECT", "AUTH=PLAIN"]

>> session.authenticate('PLAIN', "user", "plain_password")
ArgumentError: unknown auth type - "PLAIN"
  from /home/david/.rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/net/imap.rb:359:in `authenticate'
  from (irb):4

¡Ups!. Consultando la documentación observamos que la librería sólo soporta los métodos de autenticación, LOGIN y CRAM-MD5. Ningún problema. net/imap permite registrar mecanismos de autenticación adicionales.

1
2
3
4
5
6
7
8
9
10
11
12
class ImapPlainAuthenticator
  def initialize(user, password)
    @user = user
    @password = password
  end

  def process(data)
    return "#{@user}\0#{@user}\0#{@password}"
  end
end

Net::IMAP::add_authenticator('PLAIN', ImapPlainAuthenticator)
1
2
3
4
5
6
7
$ irb -r
>> require 'net/imap'
>> require 'imap_plain_authenticator.rb'
>> session = Net::IMAP.new("mail.udc.es", 993, true
=> #<Net::IMAP:0x1b0edb0 @tagno=0, @continuation_request=nil, ...
>> session.authenticate('PLAIN', "user", "plain_password")
=> #<struct Net::IMAP::TaggedResponse tag="RUBY0001", name="OK", ...

Voilà, C’est fini.

¿Qué pasa con Ruby 1.9.x?

En la documentación no lo indica, pero si utilizáis Ruby 1.9.x veréis que sí incorpora soporte AUTH=PLAIN y no es necesario que registréis esta extensión.

Comments