logo

IMAP Authentication for WordPress

logo

UPDATE 2/13/09: There is a newer version of the IMAP Authentication plugin for WordPress 2.7.1.

It seems like IMAP authentication would be a pretty basic plugin to find for WordPress. A google search doesn’t turn up much. I found this one which was apparently written for an older version of WordPress. Never having written a WordPress plugin before, naturally I decided to fix it to work with version 2.6.

Below is the result of my efforts. I started with Norman’s code, and modified it until it worked with version 2.6. I apologize if it is written poorly or if I missed something terribly obvious; I’ve never written a WordPress plugin before.

Download imap-authentication2.php

<?php
/*
Plugin Name: IMAP Authentication
Version: 0.1
Plugin URI: http://blog.neverusethisfont.com/2008/08/imap-authentication-for-wordpress/
Description: Authenticate users using IMAP authentication.
Author: Aaron Parecki
Author URI: http://www.aaronparecki.com
 
Assumes a successful login against the IMAP server is a valid user, and auto-creates
the user in Wordpress if they don't already exist.
 
 
 
Copyright 2007 by Aaron Parecki  (email : aaron@parecki.com)
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
*/
 
add_action('admin_menu', array('IMAPAuthentication', 'admin_menu'));
add_action('lost_password', array('IMAPAuthentication', 'disable_password'));
add_action('retrieve_password', array('IMAPAuthentication', 'disable_password'));
add_action('password_reset', array('IMAPAuthentication', 'disable_password'));
add_filter('show_password_fields', array('IMAPAuthentication', 'show_password_fields'));
 
 
if( is_plugin_page() ) {
    $mailbox = IMAPAuthentication::get_mailbox();
    $user_suffix = IMAPAuthentication::get_user_suffix();
?>
<div class="wrap">
  <h2>IMAP Authentication Options</h2>
  <form name="imapauthenticationoptions" method="post" action="options.php">
    <?php wp_nonce_field('update-options'); ?>
    <input type="hidden" name="action" value="update" />
    <input type="hidden" name="page_options" value="imap_authentication_mailbox,imap_authentication_user_suffix" />
    <fieldset class="options">
      <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
        <tr valign="top">
        <th width="33%" scope="row"><label for="imap_authentication_mailbox">Mailbox</label></th>
        <td><input name="imap_authentication_mailbox" type="text" id="imap_authentication_mailbox" value="<?php echo htmlspecialchars($mailbox) ?>" size="80" /><br />eg: {mail.example.com/readonly}INBOX or {mail.example.com:993/ssl/novalidate-cert/readonly}INBOX</td>
        </tr>
        <tr valign="top">
        <th scope="row"><label for="imap_authentication_user_suffix">User Suffix</label></th>
        <td><input name="imap_authentication_user_suffix" type="text" id="imap_authentication_user_suffix" value="<?php echo htmlspecialchars($user_suffix) ?>" size="50" /><br />A suffix to add to usernames (typically used to automatically add the domain part of the login).<br />eg: @example.com</td>
        </tr>
      </table>
    </fieldset>
    <p class="submit">
      <input type="submit" name="Submit" value="<?php _e('Save Changes') ?>" />
    </p>
  </form>
</div>
<?php
}
 
if( !class_exists('IMAPAuthentication') ) {
    class IMAPAuthentication {
        /*
         * Add an options pane for this plugin.
         */
        function admin_menu() {
            add_options_page('IMAP Authentication', 'IMAP Authentication', 10, __FILE__);
        }
 
        /*
         * Return the mailbox option from the database, creating the option if it doesn't exist.
         */
        function get_mailbox() {
            global $cache_nonexistantoptions;
 
            $mailbox = get_settings('imap_authentication_mailbox');
            if (! $mailbox or $cache_nonexistantoptions['imap_authentication_mailbox']) {
                $mailbox = '{localhost:143}INBOX';
                IMAPAuthentication::add_mailbox_option($mailbox);
            }
 
            return $mailbox;
        }
 
        /*
         * Add the mailbox option to the database.
         */
        function add_mailbox_option($mailbox) {
            add_option('imap_authentication_mailbox', $mailbox, 'The mailbox to try and log into.');
        }
 
        /*
         * Return the user_suffix option from the database, creating the option if it doesn't exist.
         */
        function get_user_suffix() {
            global $cache_nonexistantoptions;
 
            $user_suffix = get_settings('imap_authentication_user_suffix');
            if (! $user_suffix or $cache_nonexistantoptions['imap_authentication_user_suffix']) {
                $user_suffix = '';
                IMAPAuthentication::add_user_suffix_option($user_suffix);
            }
 
            return $user_suffix;
        }
 
        /*
         * Add the user_suffix option to the database.
         */
        function add_user_suffix_option($user_suffix) {
            add_option('imap_authentication_user_suffix', $user_suffix, 'A suffix to add to usernames (typically used to automatically add the domain part of the login).');
        }
 
        // custom error handler
        function eh($type, $msg, $file, $line, $context)
        {
            $error = $error.$msg;
        }
 
        function login($username, $password) {
        	global $wpdb;
 
			$mbox = imap_open(IMAPAuthentication::get_mailbox(), $username.IMAPAuthentication::get_user_suffix(), $password, OP_HALFOPEN) or $error = imap_last_error();
 
			if ($mbox) {
				$user = get_userdatabylogin($username);
 
				if( $user === false ) {
					// the user checked out on the IMAP server, but there was no record in the database. Automatically add it now.
					$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->users (user_login, user_nicename, user_email, display_name) VALUES(%s, %s, %s, %s)", $username, $username, $username.IMAPAuthentication::get_user_suffix(), $username) );
					$user = get_userdatabylogin($username);
 
					$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES(%d, %s, %s)", $user->ID, 'nickname', $username) );
					$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES(%d, %s, %s)", $user->ID, 'rich_editing', 'true') );
					$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES(%d, %s, %s)", $user->ID, 'wp_capabilities', 'a:1:{s:6:"author";b:1;}') );
					$wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES(%d, %s, %s)", $user->ID, 'wp_user_level', '2') );
 
				}
 
				imap_close($mbox);
				return new WP_User($user->ID);
			} else {
				do_action( 'wp_login_failed', $username );
				return new WP_Error('incorrect_password', __('<strong>ERROR</strong>: Incorrect password.'));
			}
        }
 
        /*
         * Used to disable certain login functions, e.g. retrieving a
         * user's password.
         */
        function disable_password() {
            login_header('Login', '<p class="message"><strong>ERROR</strong>: You can\'t do that here. This blog uses the IMAP login mechanism. Your password is set with your email account.</p>', 'error');
			die();
        }
 
        /*
         * Used to disable certain display elements, e.g. password
         * fields on profile screen.
         */
        function show_password_fields($username) {
            return false;
        }
    }
}
 
 
if( !is_plugin_page() ) :
 
function wp_authenticate($username, $password) {
	return IMAPAuthentication::login($username, $password);
}
endif;
 
 
?>

7 Responses to “IMAP Authentication for WordPress”

  1. SpringCreek says:

    Nice! Great programming technique. Quiet useful even for the WordPress experts!

  2. Hey Aaron!

    The web is a small small place. I was just making a new website for the comp sci ACM club (http://acm.cs.uoregon.edu) and I wanted to let people authenticate against their CS email accounts. I finally ran across your plugin and when I actived it I saw your name as the author and was like “what?! are you kidding me!”

    Good times. I just activated it on WP 2.7. Got this error:

    Fatal error: Cannot redeclare wp_authenticate() (previously declared in /Library/WebServer/Documents/wp-includes/pluggable.php:438) in /Library/WebServer/Documents/wp-content/plugins/imap-authentication2.php on line 177

    I’ll play with it for a bit and see if I can make any progress.

  3. aaron says:

    Hey Jeremy,

    Small world indeed! I updated this plugin to work in WordPress 2.7.1. Check it out and let me know if you have problems.

  4. 女子徵信 says:

    Letter of credit information agencies, and professional services grasping evil, for you do expose derailed and immoral act of a third party to help you successfully seek justice for rape caught!

  5. We provide you with the high quality and comfortable Perfect Men Fitflop Hyker Black , the lowest price!Fitflop uk always give you some unexpected originality. You will like to enjoy them and their fashionable style.

  6. We offer the high quality and fashionable UGG 1875 Women’s Sheepskin Cuff Boots,its style is very unique,warm and comfortable,you should not miss them.

  7. Your location is valueble for me. Thanks!?-

logo
logo
Powered by WordPress | Designed by Elegant Themes