=====""FudLogin"" Mod===== This is a try for an advanced "Single Login System" for Wikka Wiki in combination with an [[http://fudforum.org/forum/ | FUDForum]] based forum installation. It will allow anyone to log in with his forum login and password. On the first login, a user has to choose his WikiName, he likes to use. I had the following goals in mind, when developing this mod: - Simple installation - Has to work with different databases for forum and wiki - Has to work even if the wiki already has several [[WikiName]]s, pages, ACLs, UserPages, ... After the change to the new login system, any forum user has to be able to get back his old WikiName - Even if the user has a "non CamelCase" nick in the forum, he has to be able to choose a "real WikiName" for the Wiki. To install this mod, you at first have to specify the path to your forum in your wikka.config.php in the following way: %%(php;1) "fudlogin_forumpath" => "../FUDForum" // Replace with relative path to your "non HTTP reachable" forum files (backend). %% Then **replace** the file actions/usersettings.php with the version at the end of this page. After doing so, any user is immediately able to login with his forum login data. Users, which already had a WikiName, will be able to enter the old WikiName on the first login. This will migrate the old WikiName to the new login system. Users, which didn't already have a WikiName, will just choose a new one, which hasn't been already taken by someone else and isn't already in use as name for a page on your wiki. This is the replacement for actions/usersettings.php: %%(php;1) WikiName:"); if (!defined('LOGIN_BUTTON_LABEL')) define('LOGIN_BUTTON_LABEL', "Login"); if (!defined('LOGOUT_BUTTON_LABEL')) define('LOGOUT_BUTTON_LABEL', "Logout"); if (!defined('FUD_LOGIN_HEADING')) define('FUD_LOGIN_HEADING', "===Login==="); if (!defined('FUD_REGISTER_HEADING')) define('FUD_REGISTER_HEADING', "===Register==="); if (!defined('FUD_REGISTER_LABEL')) define('FUD_REGISTER_LABEL', "Any forum login may be used to login here. If you don't have one, then get one for free"); if (!defined('FUD_REGISTERED_USER_LOGIN_LABEL')) define('FUD_REGISTERED_USER_LOGIN_LABEL', "You may use your Forum login data, to log in here."); if (!defined('FUD_LOGINNAME_LABEL')) define('FUD_LOGINNAME_LABEL', "Your Forum Login Name:"); if (!defined('FUD_PASSWORD_LABEL')) define('FUD_PASSWORD_LABEL', "Password:"); if (!defined('FUD_NEW_USER_REGISTER_LABEL')) define('FUD_NEW_USER_REGISTER_LABEL', "If you log in in for the first time, then you have to set your WikiName here. The WikiName will be used instead of your login name, to identify changes and contributions with you. It may be the best to just \"reformat\" your login name, to be in valid WikiName syntax."); if (!defined('FUD_ERROR_WRONG_LOGIN_PASSWORD')) define('FUD_ERROR_WRONG_LOGIN_PASSWORD', "You entered a wrong username or password"); if (!defined('FUD_ERROR_UNCONFIRMED_ACCOUNT')) define('FUD_ERROR_UNCONFIRMED_ACCOUNT', "Your account has not been activated by an administrator, so far."); if (!defined('FUD_ERROR_UNCONFIRMED_MAIL')) define('FUD_ERROR_UNCONFIRMED_MAIL', "You have not confirmed your account via mail, so far."); if (!defined('FUD_ERROR_WIKINAME')) define('FUD_ERROR_WIKINAME', "Username must be formatted as a ##\"\"WikiName\"\"##, e.g. ##\"\"JohnDoe\"\"##."); if (!defined('FUD_ERROR_EMPTY_WIKINAME')) define('FUD_ERROR_EMPTY_WIKINAME', "This is your first Wiki login, so you have to choose a valid \"\"WikiName\"\"."); if (!defined('FUD_ERROR_RESERVED_PAGENAME')) define('FUD_ERROR_RESERVED_PAGENAME', "Sorry, this \"\"WikiName\"\" is reserved for a page. Please choose a different name."); if (!defined('FUD_ERROR_RESERVED_WIKINAME')) define('FUD_ERROR_RESERVED_WIKINAME', "Sorry, this WikiName is already taken by someone else."); //initialize variables $params = ''; $url = ''; $email = ''; $wikkauser = ''; $doubleclickedit = ''; $show_comments = ''; $revisioncount = ''; $changescount = ''; $username_highlight = ''; $wikiname_highlight = ''; $revisioncount_highlight = ''; $changescount_highlight = ''; // // "Installation" of FUDLogin. This will create the DB table, if not // already there // @mysql_query( "CREATE TABLE ".$this->config["table_prefix"]."fudlogintranslate (". "wikkauser varchar(75) NOT NULL default '',". "fuduser varchar(50) NOT NULL default '',". "PRIMARY KEY (fuduser),". "UNIQUE (wikkauser)" . ") TYPE=MyISAM;", $this->dblink ); $err = mysql_errno(); // Ignore error "Table already exists", but exit for all other errors! if ($err && $err != 1050) die(mysql_error()); // // Start of FUDForum connection code. // // Returns the FUDForum configuration settings by parsing "GLOBALS.php". The // settings are returned as array, so we don't get into conflict with other // variables. function fudforum_get_cfg($wikkaref) { if (!isset($wikkaref->config["fudlogin_forumpath"])) die('Please set "fudlogin_forumpath" in your "wikka.config.php" file'); $cfg_path = $wikkaref->config["fudlogin_forumpath"]; $cfg_path .= "/include/GLOBALS.php"; if (!file_exists($cfg_path)) die('Path in "fudlogin_forumpath" seems to be invalid! The file "' . $cfg_path . '" doesn\'t exist!'); $code = file_get_contents($cfg_path); $tokens = token_get_all($code); $fudcfg = array(); $varname = false; foreach ($tokens as $token) { if (!is_array($token)) continue; switch($token[0]) { case(T_VARIABLE): $varname = $token[1]; $varname = str_replace("$", "", $varname); break; case(T_CONSTANT_ENCAPSED_STRING): // Drop the quotes on string values $token[1] = substr($token[1], 1, strlen($token[1]) - 2); case(T_LNUMBER): if ($varname) { $fudcfg[$varname] = $token[1]; $varname = false; } break; } } return $fudcfg; } // Returns a data object for valid login, returns "false" for invalid login. function fudforum_fetch_user($wikkaref, $login, $passwd) { $fudcfg = fudforum_get_cfg($wikkaref); // Connect to the forum DB. PHP will reuse "$this->dblink", if forum and // wiki are on the same DB! $fud_dblink = mysql_connect($fudcfg["DBHOST"], $fudcfg["DBHOST_USER"], $fudcfg["DBHOST_PASSWORD"]); if (!$fud_dblink || !mysql_select_db($fudcfg["DBHOST_DBNAME"], $fud_dblink)) die("Failed to open forum database!"); // Query for user data. Use the password in the query, so a wrong password // will return an empty query $result = mysql_query(sprintf( "SELECT id, email, users_opt FROM %s WHERE login = '%s' AND passwd = '%s'", $fudcfg["DBHOST_TBL_PREFIX"] . "users", mysql_real_escape_string($login), md5($passwd) ), $fud_dblink); if (mysql_num_rows($result) != 1) return false; $data = mysql_fetch_object($result); // MySQL-Part is now finished, so it's time to clean up // We *don't* close the connection on "$fud_dblink", as this is the same as // "$this->dblink", if forum and wiki are on the same DB! // The only thing, we do, is to re-select the right DB for "$this->dblink". mysql_select_db($wikkaref->config['mysql_database'], $wikkaref->dblink); // Anonymous users may not log in! if ($data->id < 2) return false; unset($data->id); // Decode the parts of "users_opt", we need. $flags = $data->users_opt; $data->mailconfirmed = ($flags & 131072); $data->banned = ($flags & 65536); $data->acctconfirmed = !($flags & 2097152); unset($data->users_opt); return $data; } // Returns link to forum function fudforum_get_forumlink($wikkaref) { $fudcfg = fudforum_get_cfg($wikkaref); return $fudcfg["WWW_ROOT"] . "index.php"; } // // End of FUDForum connection code. // //create URL $url = $this->config['base_url'].$this->tag; // append URL params depending on rewrite_mode $params = ($this->config['rewrite_mode'] == 1) ? '?' : '&'; // BEGIN *** Logout *** // is user trying to log out? if (isset($_POST['logout']) && $_POST['logout'] == LOGOUT_BUTTON_LABEL) { $this->LogoutUser(); $params .= 'out=true'; $this->Redirect($url.$params); } // END *** Logout *** // BEGIN *** Usersettings *** // user is still logged in else if ($user = $this->GetUser()) { // is user trying to update user settings? if (isset($_POST['action']) && ($_POST['action'] == 'update')) { // get POST parameters $doubleclickedit = $this->GetSafeVar('doubleclickedit', 'post'); $show_comments = $this->GetSafeVar('show_comments', 'post'); $revisioncount = (int) $this->GetSafeVar('revisioncount', 'post'); $changescount = (int) $this->GetSafeVar('changescount', 'post'); // validate form input switch (TRUE) { case (($revisioncount < REVISION_DISPLAY_LIMIT_MIN) || ($revisioncount > REVISION_DISPLAY_LIMIT_MAX)): //invalid revision display limit $error = sprintf(ERROR_INVALID_REVISION_DISPLAY_LIMIT, REVISION_DISPLAY_LIMIT_MAX); $revisioncount_highlight = INPUT_ERROR_STYLE; break; case (($changescount < RECENTCHANGES_DISPLAY_LIMIT_MIN) || ($changescount > RECENTCHANGES_DISPLAY_LIMIT_MAX)): //invalid recentchanges display limit $error = sprintf(ERROR_INVALID_RECENTCHANGES_DISPLAY_LIMIT, RECENTCHANGES_DISPLAY_LIMIT_MAX); $changescount_highlight = INPUT_ERROR_STYLE; break; default: // input is valid $this->Query('UPDATE '.$this->config['table_prefix'].'users SET '. "doubleclickedit = '".mysql_real_escape_string($doubleclickedit)."', ". "show_comments = '".mysql_real_escape_string($show_comments)."', ". "revisioncount = '".mysql_real_escape_string($revisioncount)."', ". "changescount = '".mysql_real_escape_string($changescount)."' ". "WHERE name = '".$user['name']."' LIMIT 1"); $this->SetUser($this->LoadUser($user["name"])); // forward $params .= 'stored=true'; $this->Redirect($url.$params); } } //user just logged in else { // get stored settings $email = $user['email']; $doubleclickedit = $user['doubleclickedit']; $show_comments = $user['show_comments']; $revisioncount = $user['revisioncount']; $changescount = $user['changescount']; } // display user settings form echo '

'.USER_SETTINGS_HEADING.'

'; echo $this->FormOpen(); ?> '."\n"; break; case (isset($success)): echo ''."\n"; break; default: } ?>
  Hello, Link($user['name']) ?>!
'.$this->Format($error).'
'.$this->Format($success).'
htmlspecialchars_ent($email) ?>
/>
/>
name="revisioncount" value="htmlspecialchars_ent($revisioncount) ?>" size="40" />
name="changescount" value="htmlspecialchars_ent($changescount) ?>" size="40" />
 
FormClose(); //close user settings form echo '
'."\n"; echo '
'.QUICK_LINKS_HEADING.'
'."\n"; echo $this->Format(QUICK_LINKS); } // user is not logged in else { // print confirmation message on successful logout if (isset($_GET['out']) && ($_GET['out'] == 'true')) { $success = USER_LOGGED_OUT; } // is user trying to log in? $email = false; if (isset($_POST['name']) && isset($_POST['password'])) { $data = fudforum_fetch_user($this, trim($_POST['name']), $_POST['password']); if (!$data) { $error = FUD_ERROR_WRONG_LOGIN_PASSWORD; $username_highlight = INPUT_ERROR_STYLE; } else if (!$data->mailconfirmed) $error = FUD_ERROR_UNCONFIRMED_MAIL; else if (!$data->acctconfirmed) $error = FUD_ERROR_UNCONFIRMED_ACCOUNT; else $email = $data->email; } // Valid Login (means, we fetched a valid email for the user from // FUDForum login DB) if ($email) { $in_name = trim($_POST['name']); $in_wikiname = trim($_POST["wikiname"]); // Try to fetch wiki name for user. If there is none in our DB and // the user-supplied wikiname is valid, then store the wikiname to // the DB and continue with it. $wikkauser = false; $result = $this->Query(sprintf( "SELECT wikkauser FROM %s WHERE fuduser = '%s'", $this->config["table_prefix"]."fudlogintranslate", mysql_real_escape_string($in_name) )); if (mysql_num_rows($result) == 1) { $obj = mysql_fetch_object($result); $wikkauser = $obj->wikkauser; } else { switch(TRUE) { case (strlen($in_wikiname) == 0): $error = FUD_ERROR_EMPTY_WIKINAME; $wikiname_highlight = INPUT_ERROR_STYLE; break; case (!$this->IsWikiName($in_wikiname)): $error = FUD_ERROR_WIKINAME; $wikiname_highlight = INPUT_ERROR_STYLE; break; // Only match for "real" pages and not for UserPages (would // block users with UserPage from migrating) case ($this->ExistsPage($in_wikiname) && !$this->LoadUser($in_wikiname)): $error = FUD_ERROR_RESERVED_PAGENAME; $wikiname_highlight = INPUT_ERROR_STYLE; break; default: //valid input // Query for the newly chosen Wiki name $result = $this->Query(sprintf( "SELECT wikkauser FROM %s WHERE wikkauser = '%s'", $this->config["table_prefix"]."fudlogintranslate", mysql_real_escape_string($in_wikiname) )); // If the name is taken, then send error if (mysql_num_rows($result) == 1) { $error = FUD_ERROR_RESERVED_WIKINAME; $wikiname_highlight = INPUT_ERROR_STYLE; } // Name not taken -> link it to the login name else { $this->Query(sprintf( "INSERT INTO %s SET wikkauser = '%s', fuduser = '%s'", $this->config["table_prefix"]."fudlogintranslate", mysql_real_escape_string($in_wikiname), mysql_real_escape_string($in_name) )); $wikkauser = $in_wikiname; } } } // If we have a valid Wikka user now, then create an account for // the WikiName or update the existing one if ($wikkauser) { $existingUser = $this->LoadUser($wikkauser); if (!$existingUser) { $this->Query(sprintf( "INSERT INTO %s SET signuptime = now(), name = '%s', email = '%s', password = '%s'", $this->config['table_prefix']."users", mysql_real_escape_string($wikkauser), mysql_real_escape_string($email), md5($_POST['password']) )); } else { $this->Query(sprintf( "UPDATE %s SET email = '%s', password = '%s' WHERE name = '%s'", $this->config['table_prefix']."users", mysql_real_escape_string($email), md5($_POST['password']), mysql_real_escape_string($wikkauser) )); } $this->SetUser($this->LoadUser($wikkauser)); $this->Redirect($url, ''); } } // BEGIN *** Login/Register *** print($this->FormOpen()); ?> '."\n"; break; case (isset($success)): echo ''."\n"; break; } ?>
Format(FUD_LOGIN_HEADING) ?>  
  Format(FUD_REGISTERED_USER_LOGIN_LABEL); ?>
'. $this->Format($error) .'
'. $this->Format($success) .'
name="name" size="40" value="GetSafeVar('name', 'post'); ?>" />
type="password" name="password" size="40" />
 
 
name="wikiname" size="40" />
 
Format(FUD_REGISTER_HEADING) ?>  
 
FormClose()); // END *** Login/Register *** } ?>
Login powered by FudLogin written by Manuel Reimer.
%% ---- CategoryUserContributions