Rails Plugin: imap_authenticatable

written by daniel on February 7th, 2007 @ 08:57 PM

Update: Thanks to a suggestion in the comments, the plugin now supports SSL.

Let’s say you are a large organization and want to deploy a web app for your employees without making them remember a new password. Assume you don’t have anything cool like LDAP to act as a single point of authentication. What do you do?

Use IMAP.

This is exactly what I did recently for a organization that wanted their thousands of people to be able to use an application I wrote for them, but didn’t want to bother with a new authentication system.

I whipped up a simple Rails plugin to authenticate against their IMAP server. Anyone in the organization can login, and a user in my app is created the first time they successfully do. We now have it running on three apps in the organization.

Installation

Install the plugin as an SVN external:
./script/plugin install -x http://source.collectiveidea.com/public/rails/plugins/imap_authenticatable
or the “regular” way:
./script/plugin install http://source.collectiveidea.com/public/rails/plugins/imap_authenticatable

The plugin expects a Rails Model with a username column. Then put the simple declaration in and specify your host:

class User < ActiveRecord::Base
  imap_authenticatable :host => 'mail.example.com'

  ...
end

Additional options

:allow_new_users => true
is a true/false setting which changes whether the included < code >authenticate() method calls < code >find_by_username() or < code >find_or_create_by_username()
:default_domain => 'example.com'
is for when your IMAP server (mail.example.com) is not what is in your email addresses (daniel@example.com).
:append_domain => false
is a true/false setting which changes whether to strip or append the :default_domain to/from each username.

Authentication

While this plugin takes care of the actual authentication, it doesn’t provide any interfaces for your users. I’ve been using it with Rick Olson’s restful_authentication plugin. You do have to rip some code out and substitute ‘username’ for ‘login’ in a few places (my personal preference).

Questions?

Any questions? Suggestions? If you find this useful, drop me a line!

Comments

  • John Nunemaker on 07 Feb 23:31

    Good idea.

  • Vincent Palmer on 08 Feb 05:35

    Your “regular” way still includes the -x btw

  • Arash on 17 Feb 19:01

    Installed it, but now am getting an error ”`const_missing’: uninitialized constant Net::IMAP::SSL (NameError)” when I try to script/server Why?

  • Daniel Morrison on 19 Feb 10:26

    @arash: Are you trying to use it with SSL? The code doesn’t currently support this (it should, check back tomorrow, and I’ll package something up).

    As for your error, it could be from OpenSSL not being installed. If you email me the error, I’d be glad to help you out (change the first dot to an @ in my URL).

    @vincent: Thanks, I’ve made the change.

  • Ron Sweeney on 21 Feb 08:13

    Fantastic Idea! Can’t wait to give this a shot…

  • Paul Groves on 07 Feb 12:58

    Brilliant

    Thank You!

  • Daniel Morrison on 08 Feb 17:29

    Paul: Glad you like! Thanks for the comment.

  • Josh Merchant on 18 Apr 00:22

    Awesome idea. Great for pitching enterprise rails apps.

    Added it to my project… however experienced some problems.

    I don’t know how your particular IMAP server responded to your request, however using a standard email one caused some issues. Even though the login credentials were right, it still seemed to return false.

    Wasn’t a big deal to fix.. just thought you might be interested in the solution:

    login = imap.authenticate(‘LOGIN’, username, password) if login[:name] == ‘OK’ if imap_authenicatable_options[:allow_new_users] find_or_create_by_login(username) else find_by_login(username) end else false end rescue false ensure imap.disconnect

    Works like a charm :-)

Post a comment

Options:

Size

Colors