58°F

Aaron Parecki

  • Articles
  • Notes
  • Photos
  • IMAP Authentication for Wordpress

    August 28, 2008

    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.

    <?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;
    
    
    ?>
    
    Thu, Aug 28, 2008 1:00am -07:00 #code
    1 mention

    Other Mentions

    • Aaron Parecki aaronparecki.com
      IMAP Authentication for Wordpress 2.7.1
      Fri, Feb 13, 2009 10:36am -08:00
Posted in /articles

Hi, I'm Aaron Parecki, Director of Identity Standards at Okta, and co-founder of IndieWebCamp. I maintain oauth.net, write and consult about OAuth, and participate in the OAuth Working Group at the IETF. I also help people learn about video production and livestreaming. (detailed bio)

I've been tracking my location since 2008 and I wrote 100 songs in 100 days. I've spoken at conferences around the world about owning your data, OAuth, quantified self, and explained why R is a vowel. Read more.

  • Director of Identity Standards at Okta
  • IndieWebCamp Founder
  • OAuth WG Editor
  • OpenID Board Member

  • 🎥 YouTube Tutorials and Reviews
  • 🏠 We're building a triplex!
  • ⭐️ Life Stack
  • ⚙️ Home Automation
  • All
  • Articles
  • Bookmarks
  • Notes
  • Photos
  • Replies
  • Reviews
  • Trips
  • Videos
  • Contact
© 1999-2025 by Aaron Parecki. Powered by p3k. This site supports Webmention.
Except where otherwise noted, text content on this site is licensed under a Creative Commons Attribution 3.0 License.
IndieWebCamp Microformats Webmention W3C HTML5 Creative Commons
WeChat ID
aaronpk_tv