Advertisement
Guest User

Untitled

a guest
Apr 16th, 2012
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.50 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: SMF Bridge Modified By Eoghan Cunningham
  4. Plugin URI: http://code.google.com/p/wp-smf-bridge
  5. Description: User registration and login bridge between Wordpress 3.4 and Simple Machine Forum 2.0.2
  6. Author: Jonathan "JonnyFunFun" Enzinna & Eoghan Cunningham
  7. Version: 0.3.2 beta
  8. Author URI: http://www.juniorwebdevs.co.uk/
  9. */
  10.  
  11. class smf_bridge {
  12.     static $bridge_active = false;
  13.     static $smf_dir = '';
  14.     static $reg_override = 0;
  15.     static $smf_dbopts = array();
  16.     static $smf_settings = array();
  17.  
  18.     /* version
  19.      * @public
  20.      * Returns the current software version
  21.      */
  22.     function version() { return 0.2; }
  23.  
  24.     /* load
  25.      * @public
  26.      * Performs functions needed when we load, such as checking the configuration and
  27.      * including the necessary files for the API
  28.      */
  29.     function load() {
  30.     if (get_option('smf_bridge_setup_complete') == 1) {
  31.         // Load the settings
  32.         self::$smf_dir = ABSPATH.get_option('smf_bridge_smfdir');
  33.         self::$reg_override = (get_option('smf_bridge_regoverride')) ? get_option('smf_bridge_regoverride') : 0;
  34.         if (file_exists(self::$smf_dir."Settings.php"))
  35.         require(self::$smf_dir."Settings.php");
  36.         else {
  37.         delete_option('smf_bridge_setup_complete');
  38.         return false;
  39.         }
  40.         if (!defined('SMF_API'))
  41.            require(dirname(__FILE__)."/smf_1-1_api.php");
  42.         self::$bridge_active = true;
  43.         self::$smf_dbopts['user'] = $db_user;
  44.         self::$smf_dbopts['pass'] = $db_passwd;
  45.         self::$smf_dbopts['host'] = $db_server;
  46.         self::$smf_dbopts['prefix'] = $db_prefix;
  47.         self::$smf_dbopts['name'] = $db_name;
  48.         self::$smf_settings = $smf_settings;
  49.         return true;
  50.     } else return false;
  51.     }
  52.  
  53.     /* uservalid
  54.      * @public [filter]
  55.      * Checks to make sure the desired member_name during registration is not already
  56.      * taken by SMF
  57.      */
  58.     function uservalid($valid,$member_name) {
  59.     if (!self::$bridge_active) return;
  60.     $uname = sanitize_user($member_name);
  61.     if (!$valid)
  62.         return false;
  63.     if ($uname != $member_name)
  64.         return false;
  65.     if (self::getSMFId($uname))
  66.         return false;
  67.     if (self::getSMFId(strtolower($uname)))
  68.         return false;
  69.     return true;
  70.     }
  71.  
  72.     /* add_menu
  73.      * @public
  74.      * Add the admin menu link
  75.      */
  76.     function add_menu() {
  77.     add_submenu_page('options-general.php','SMF Bridge Settings','SMF Bridge',8,__FILE__,array('smf_bridge','settings'));
  78.     }
  79.  
  80.     /* settings
  81.      * @public
  82.      * Draws the settings page to change the bridge configuration
  83.      */
  84.     function settings() {
  85.     $prev_active = self::$bridge_active;
  86.     echo '<div class="wrap"><h2>SMF Bridge Settings</h2></div>';
  87.     if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  88.         // Save settings
  89.         switch ($_POST['action']) {
  90.         case "save":
  91.             if (substr($_POST['smf_relpath'],-1) != '/')
  92.             $_POST['smf_relpath'] = $_POST['smf_relpath'].'/';
  93.             if (!get_option('smf_bridge_smfdir'))
  94.             add_option('smf_bridge_smfdir',$_POST['smf_relpath']);
  95.             else
  96.             update_option('smf_bridge_smfdir',$_POST['smf_relpath']);
  97.             // Double check the bridge dir before activating
  98.             if (file_exists(ABSPATH.get_option('smf_bridge_smfdir')))
  99.             add_option('smf_bridge_setup_complete',1);
  100.             else
  101.             delete_option('smf_bridge_setup_complete');
  102.             echo '<div id="message" class="updated fade">Settings saved!</div>';
  103.             break;
  104.         case "user-sync":
  105.             $x = self::syncusers();
  106.             echo '<div id="message" class="updated fade">'.$x.' Users Synchronized Successfully!</div>';
  107.             break;
  108.         }
  109.         self::load();
  110.         }
  111.     if (!self::$bridge_active) {
  112.         // Let them know we're not fully set up!
  113.         echo '<div id="message" class="updated fade">SMF Bridge has not been configured properly and is not active!</div>';
  114.     } elseif ((self::$bridge_active) && ($_SERVER['REQUEST_METHOD'] == "POST") && (!$prev_active)) {
  115.         echo '<div id="message" class="updated fade">SMF Bridge is now active!</div>';
  116.     }
  117.     if ((get_option('smf_bridge_smfdir')) && (!file_exists(ABSPATH.get_option('smf_bridge_smfdir').'Settings.php')))
  118.         echo '<div id="message" class="updated fade">Your SMF path is invalid - could not locate Settings.php in <em>'.ABSPATH.get_option('smf_bridge_smfdir').'</em></div>';
  119. ?>
  120.     <form action="<?=$_SERVER['REQUEST_URI']?>" method="POST">
  121.     <input type="hidden" name="action" value="save"/>
  122.     <table width="100%" cellspacing="2" cellpadding="5" class="editform">
  123.     <tr>
  124.         <th width="33%" scope="row" valign="top">Forum Path:<br />
  125.         <font style="font-size: 8px;"><em>URI relative to Wordpress root<br />
  126.          i.e - "forum/" places your forums in <?=ABSPATH?>forum/</em></font>
  127.         </th>
  128.         <td>
  129.         <input type="text" name="smf_relpath" value="<?=(get_option('smf_bridge_smfdir')) ? get_option('smf_bridge_smfdir') : ''?>" maxlength="256" style="width: 250px;"/>
  130.         </td>
  131.     </tr>
  132.     <tr><td colspan="2" style="height: 18px;"></td></tr>
  133.     <tr>
  134.         <td>&nbsp;</td>
  135.         <td>
  136.         <input type="submit" value="Save Settings"/>
  137.         </td>
  138.     </tr>
  139.     </table>
  140.     </form><br />
  141.     <legend><em>Maintenance Options</em></legend>
  142.     <table width="100%" cellspacing="2" cellpadding="5" class="editform">
  143.     <tr>
  144.         <th width="33%" valign="top" scope="row">Manual User Sync:</th>
  145.         <td>
  146.         <form action="<?=$_SERVER['REQUEST_URI']?>" method="POST">
  147.             <input type="hidden" name="action" value="user-sync"/>
  148.             <input type="submit" value="Synchronize Users"/>
  149.         </form>
  150.         </td>
  151.     <tr>
  152.     </table>
  153. <? 
  154.     }
  155.  
  156.     /* login
  157.      * @public
  158.      * Occurs when a user logs in to WordPress, crowbars them in to SMF and syncs profiles for sanity
  159.      */
  160.     function login() {    
  161.     if (!self::$bridge_active) return;
  162.     if (!$_POST['wp-submit'] || $_POST['wp-submit'] != 'Log In') return;
  163.     //if (!is_user_logged_in()) return;
  164.     $user = get_userdatabylogin($_POST['log']);
  165.     if ($user) {
  166.         self::crowbar();
  167.         self::syncprofile($user->ID,true);
  168.     } else {
  169.         // update wordpress password if we exist
  170.         if (!$smf_cxn)
  171.                     $smf_cxn = mysql_connect(self::$smf_dbopts['host'],self::$smf_dbopts['user'],self::$smf_dbopts['pass']) or trigger_error(mysql_error(),E_USER_ERROR);
  172.                 $user_exists = $wpdb->get_row("SELECT id FROM $wpdb->users WHERE UPPER(user_login) = UPPER('". $_POST['log'] . "')");      
  173.         if ($user_exists) {
  174.             $SQL = "SELECT passwd, password_salt FROM ".self::$smf_dbopts['prefix']."members WHERE UPPER(member_name) = UPPER('".$_POST['log']."')";
  175.             if (!$rs = mysql_query($SQL,$smf_cxn)) trigger_error(mysql_error(),E_USER_ERROR);
  176.             if (mysql_num_rows($rs) > 0) {
  177.                 list($password,$salt) = mysql_fetch_array($rs, MYSQL_NUM);
  178.                 if (sha1($_POST['pwd'].$sald) == $password) {
  179.                     $newpass = wp_hash_password($_POST['pwd']);
  180.                     $SQL = "UPDATE ".$wpdb->prefix."users SET user_pass='$newpass' WHERE UPPER(user_login)=UPPER('".$_POST['log']."') LIMIT 1";
  181.                 }
  182.             }
  183.         } else {
  184.             self::syncusers();
  185.             $SQL = "SELECT passwd, password_salt FROM ".self::$smf_dbopts['prefix']."members WHERE UPPER(member_name) = UPPER('".$_POST['log']."')";
  186.                         if (!$rs = mysql_query($SQL,$smf_cxn)) trigger_error(mysql_error(),E_USER_ERROR);
  187.                         if (mysql_num_rows($rs) > 0) {
  188.                                 list($password,$salt) = mysql_fetch_array($rs, MYSQL_NUM);
  189.                                 if (sha1($_POST['pwd'].$sald) == $password) {
  190.                     wp_update_user(array(
  191.                         "user_login" => $_POST['log'],
  192.                         "user_pass" => $_POST['pwd']
  193.                     ));
  194.                     $tgt_user = get_userdatabylogin($_POST['log']);
  195.                     if ($tgt_user) wp_set_current_user($tgt_user->ID,$tgt_user->user_login);
  196.                                 }
  197.                         }
  198.         }
  199.     }
  200.     }
  201.  
  202.     /* logout
  203.      * @public
  204.      * Occurs when a use logs out of WordPress, logs them out of SMF, too!
  205.      */
  206.     function logout() {
  207.     if (!self::$bridge_active) return;
  208.     smf_sessionClose();
  209.     smf_setLoginCookie(0,$user->user_login,'',true);   
  210.     }
  211.  
  212.     /* register
  213.      * @public
  214.      * Occurs when a user registers on WordPress - this registers them with SMF
  215.      */
  216.     function register($userID) {       
  217.     if (!self::$bridge_active) return;
  218.     global $user_login,$user_email,$password;
  219.     $user_status = ($smf_settings['registration_method'] == 2) ? 3 : 1;
  220.     $user = get_userdata($userID);
  221.     if (!self::getSMFId($user->user_login))
  222.         smf_registerMember($user->user_login, $user->user_email, $user->user_password, $user_status);
  223.     return true;
  224.     }
  225.  
  226.     /* syncprofile
  227.      * @public
  228.      * Synchronizes the user's profile information by WordPress userID
  229.      */
  230.     function syncprofile($userID,$regularSync=false) {     
  231.     if (!self::$bridge_active) return;
  232.     global $userdata,$smf_user_info;
  233.     get_currentuserinfo();
  234.     $user = get_userdata($userID);
  235.     $smfID = $smf_user_info['id'];
  236.     // Perform only a "regular" sync - just make sure everything coincides - TODO
  237.     if ($regularSync) {
  238.     }
  239.     // We obviously only want to force outbound (to SMF) sync if we're POST'ing
  240.     if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  241.             if (!$smf_cxn)
  242.                     $smf_cxn = mysql_connect(self::$smf_dbopts['host'],self::$smf_dbopts['user'],self::$smf_dbopts['pass']) or trigger_error(mysql_error(),E_USER_ERROR);
  243.         $pass = $_POST['pass1'];
  244.         $SQL = "SELECT passwd, password_salt FROM ".self::$smf_dbopts['prefix']."members WHERE UPPER(member_name) = UPPER('".$user->user_login."')";
  245.         if (!$rs = mysql_query($SQL,$smf_cxn)) trigger_error(mysql_error(),E_USER_ERROR);
  246.         if (mysql_num_rows($rs) > 0) {
  247.             list($password,$salt) = mysql_fetch_array($rs, MYSQL_NUM);
  248.             $pass = sha1($_POST['pass1'] . $salt);
  249.         }
  250.         $SQL = "UPDATE ".self::$smf_dbopts['prefix']."members SET website_url='".addslashes($_POST['url'])."',
  251.         AIM='".addslashes($_POST['aim'])."', YIM='".addslashes($_POST['yim'])."',
  252.         passwd='".$pass."',email_address='".addslashes($_POST['email'])."', real_name='".
  253.         addslashes($_POST['first_name'].' '.$_POST['last_name'])."',
  254.         signature='".addslashes($_POST['description'])."'
  255.         WHERE UPPER(member_name)=UPPER('$user->user_login') LIMIT 1";
  256.         mysql_query($SQL,$smf_cxn) or trigger_error(mysql_error(),E_USER_ERROR);
  257.     }
  258.     }
  259.  
  260.     /* getSMFId
  261.      * @private
  262.      * Returns the member id from the SMF table based on member_name
  263.      */
  264.     private function getSMFId($member_name) {
  265.     if (!self::$bridge_active) return;
  266.     $smf_cxn = mysql_connect(self::$smf_dbopts['host'],self::$smf_dbopts['user'],self::$smf_dbopts['pass']);
  267.     $SQL = "SELECT ID_MEMBER FROM ".self::$smf_dbopts['prefix']."members WHERE UPPER(member_name)=UPPER('$member_name') LIMIT 1";
  268.     if (!$rs = mysql_query($SQL,$smf_cxn)) {
  269.         trigger_error(mysql_error(),E_USER_WARNING);
  270.         return null;
  271.     } else {
  272.         return mysql_fetch_array($rs, MYSQL_ASSOC)->ID_MEMBER;
  273.     }  
  274.     }
  275.  
  276.     /* crowbar
  277.      * @private
  278.      * Performs the login 'crowbar' into SMF
  279.      */
  280.     private function crowbar() {       
  281.     if (!self::$bridge_active) return;
  282.     if (!is_user_logged_in()) return;
  283.     $user = wp_get_current_user();
  284.     // Fetch the password and salt so we can pass the encrypted guy to the
  285.     // cookie setting function...
  286.     $smf_cxn = mysql_connect(self::$smf_dbopts['host'],self::$smf_dbopts['user'],self::$smf_dbopts['pass']);
  287.     $SQL = "SELECT passwd, password_salt FROM ".self::$smf_dbopts['prefix']."members WHERE member_name = '".$user->user_login."'";
  288.     if (!$rs = mysql_query($SQL,$smf_cxn)) trigger_error(mysql_error(),E_USER_ERROR);
  289.     if (mysql_num_rows($rs) > 0) {
  290.         list($password,$salt) = mysql_fetch_array($rs, MYSQL_NUM);
  291.         $passwd = sha1($password . $salt);
  292.     } else {
  293.         // If we didn't find the user, perhaps we need to sync and try again?
  294.         if (self::syncusers() > 0)
  295.         self::crowbar();
  296.         return;
  297.     }
  298.     smf_setLoginCookie(21600,$user->user_login,passwd,true);
  299.     smf_authenticateUser();
  300.     }
  301.  
  302.     /* syncusers
  303.      * @private
  304.      * Synchronizes all users across the two databases
  305.      */
  306.     private function syncusers() {
  307.     global $wpdb;
  308.     if (!self::$bridge_active) return;
  309.     if (!function_exists('wp_update_user'))
  310.         include(ABSPATH.'/wp-includes/registration.php');
  311.     $smf_cxn = mysql_connect(self::$smf_dbopts['host'],self::$smf_dbopts['user'],self::$smf_dbopts['pass']);
  312.     $SQL = "SELECT UPPER(member_name) FROM ".self::$smf_dbopts['prefix']."members";
  313.     if (!$rs = mysql_query($SQL,$smf_cxn)) {
  314.         // Since this is not a critical step, we'll just throw a warning instead
  315.         // of bombing the entire app...
  316.         trigger_error(mysql_error(),E_USER_ERROR);
  317.         return;
  318.     }
  319.     $smf_users = array();
  320.     while ($row = mysql_fetch_array($rs,MYSQL_NUM))
  321.         array_push($smf_users,$row[0]);
  322.     $SQL = "SELECT UPPER(user_login) FROM ".$wpdb->prefix."users";
  323.     $wp_users = $wpdb->get_col($SQL);
  324.     if (sizeof($smf_users) == sizeof($wp_users))   
  325.         return 0;
  326.     $sync_count = 0;
  327.  
  328.     foreach ($wp_users as $usr) {
  329.         if (!in_array($usr,$smf_users)) {
  330.         // Sync this user to SMF!
  331.         $user_status = ($smf_settings['registration_method'] == 2) ? 3 : 1;
  332.         smf_registerMember($user->user_login, $user->user_email, $user->user_password, $user_status);
  333.         self::syncprofile($user->user_id, true);
  334.         ++$sync_count;
  335.         }
  336.     }
  337.     foreach ($smf_users as $usr) {
  338.         if (!in_array($usr,$wp_users)) {
  339.         // Sync this user to WP!
  340.         $SQL = "SELECT emailAddress,realName FROM ".self::$smf_dbopts['prefix']."members WHERE UPPER(member_name)=UPPER('$usr') LIMIT 1";
  341.          if (!$rs = mysql_query($SQL,$smf_cxn)) {
  342.             // Since this is not a critical step, we'll just throw a warning instead
  343.             // of bombing the entire app...
  344.             trigger_error(mysql_error(),E_USER_ERROR);
  345.             return;
  346.         }
  347.         list($email,$name) = mysql_fetch_array($rs);
  348.         list($fname,$lname) = split(" ",$name);
  349.         $email_exists = $wpdb->get_row("SELECT user_email FROM ".$wpdb->users." WHERE user_email = '". $email . "'");
  350.         if (!$email_exists) {
  351.             // import the user since their e-mail doesn't exist
  352.             list($fname,$lname) = split(" ",$usr['realName']);
  353.             $user_id = wp_update_user(array(
  354.                 "user_login" => $usr,
  355.                                 "first_name" => $fname,
  356.                                 "last_name" => $lname,
  357.                                 "user_email" => $email,
  358.                                 "user_pass" => md5(date('s').rand(100,999))//this doesn't work if we're not doing it on login, but it should pick it up when the user logs in
  359.             )
  360.             );
  361.             if ($user_id) ++$sync_count;
  362.             self::syncprofile($user_id, true);
  363.         }      
  364.         }
  365.     }
  366.     return $sync_count;
  367.     }
  368.  
  369.     /* checklogin
  370.      * @public
  371.      * Checks if a user is logged into SMF, and if they are, attempts to log them in to
  372.      * WordPress as well
  373.      */
  374.     function checklogin() {
  375.     if (!self::$bridge_active) return;
  376.     global $smf_user_info,$scheme,$auth_cookie_name;
  377.     if (smf_authenticateUser()) {
  378.         if ($tgt_user = get_userdatabylogin($smf_user_info['member_name']) == false) {
  379.             // The user does not exist in the WP database - let's sync and try again
  380.             if (self::syncusers() > 0)
  381.             $tgt_user = get_userdatabylogin($smf_user_info['member_name']);
  382.         }
  383.         if ($user->ID) {
  384.             wp_set_current_user($tgt_user->ID,$tgt_user->user_login);
  385.             // And set a cookie just in case
  386.             $expiration = time() + 172800;
  387.             $cookie_data = $tgt_user->user_login . '|' . $expiration;
  388.             $key = wp_hash($tgt_user->user_login . '|' . $expiration,'logged_in');
  389.             $cookie_data .= hash_hmac('md5',$tgt_user->user_login . '|' . $expiration,$key);
  390.             $auth_cookie = wp_generate_auth_cookie($tgt_user->ID, $expiration);
  391.             $logged_in_cookie = wp_generate_auth_cookie($tgt_user->ID, $expiration, 'logged_in');
  392.             setcookie($auth_cookie_name, $auth_cookie, $expiration, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN);
  393.             setcookie($auth_cookie_name, $auth_cookie, $expiration, ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
  394.             setcookie(LOGGED_IN_COOKIE, $cookie_data, $expiration, COOKIEPATH, COOKIE_DOMAIN); 
  395.             smf_logOnline('WordPress');
  396.             self::syncprofile($tgt_user->ID,true);
  397.         }
  398.     } else {
  399.         self::login();
  400.     }
  401.     }
  402.  
  403.     /* import_auth
  404.      * @public
  405.      * Syncs passwords on a login attempt both to and from WP - this is because SMF
  406.      * uses an entirely different method of storing passwords...
  407.      */
  408.     function import_auth(&$user, &$pass) {
  409.     global $wpdb;
  410.     $wp_info = get_userdatabylogin($user);
  411.     if (!function_exists('smf_authenticate_password'))
  412.         self::load();
  413.     if (md5($pass) == $wp_info->user_pass AND $wp_info) {
  414.         // Sync the password into SMF if necessary
  415.         if (!smf_authenticate_password($user,$pass))
  416.         smf_ChangePassword($user, $pass);
  417.     } elseif (smf_authenticate_password($user,$pass) AND $wp_info) {
  418.         // Sync the password into WordPress
  419.         $SQL = $wpdb->prepare("UPDATE $wpdb->users SET user_pass = %s WHERE user_login = %s LIMIT 1",md5($pass),$user);
  420.         $wpdb->query($SQL);
  421.     } elseif (smf_authenticate_password($user,$pass)) {
  422.         // This user must not be in WP, let's sync users up and try again
  423.         if (self::syncusers() == 0) return;
  424.         self::import_auth($user,$pass);
  425.     }
  426.     }
  427. }
  428.  
  429. if (!function_exists('add_action')) exit;
  430. /* Associate the necessary action and filter hooks */
  431. add_action('admin_menu',array('smf_bridge','add_menu'));
  432. add_action('user_register',array('smf_bridge','register')); // Takes 1 argument, userID
  433. add_action('profile_update',array('smf_bridge','syncprofile'));
  434. add_action('personal_options_update',array('smf_bridge','syncprofile'));
  435. add_action('plugins_loaded',array('smf_bridge','load'));
  436. add_action('set_current_user',array('smf_bridge','checklogin'));
  437. add_action('wp_authenticate',array('smf_bridge','import_auth'),1,2);
  438. add_filter('validate_member_name',array('smf_bridge','uservalid'),10,2);
  439. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement