/** * TODO: Document me */ private function getUpdateOptions($userinfo) { global $wgRequest; // Build an array of attributes to update $updateOptions = array(); foreach (FacebookUser::$availableUserUpdateOptions as $option) { // Translate the MW parameter into a FB parameter $value = FacebookUser::getOptionFromInfo($option, $userinfo); // If no corresponding value was received from Facebook, then continue if (!$value) { continue; } // Check to see if the option was checked on a previous page (default to true) $checked = $wgRequest->getText("wpUpdateUserInfo{$option}", '0') != '1'; // Build the list item for the update option $item = '<li>'; $item .= '<input name="wpUpdateUserInfo' . $option . '" type="checkbox" ' . 'value="1" id="wpUpdateUserInfo' . $option . '" ' . ($checked ? 'checked="checked" ' : '') . '/>'; $item .= '<label for="wpUpdateUserInfo' . $option . '">' . wfMsgHtml("facebook-{$option}") . wfMsgExt('colon-separator', array('escapenoentities')) . " <i>{$value}</i></label></li>"; $updateOptions[] = $item; } // Implode the update options into an unordered list $updateChoices = ''; if (count($updateOptions) > 0) { $updateChoices .= wfMsgHtml('facebook-updateuserinfo') . "\n"; $updateChoices .= "<ul>\n" . implode("\n", $updateOptions) . "\n</ul>\n"; } return $updateChoices; }
/** * @throws FacebookUserException */ function createUser($username, $domain = '') { global $wgUser, $wgAuth; // Make sure we're not stealing an existing user account (it can't hurt to check twice) if (empty($username) || !FacebookUser::userNameOK($username)) { wfDebug("Facebook: Name not OK: '{$username}'\n"); // TODO: Provide an error message that explains that they need to pick a name or the name is taken. throw new FacebookUserException('connectNewUserView', 'facebook-invalidname'); } /// START OF TYPICAL VALIDATIONS AND RESTRICTIONS ON ACCOUNT-CREATION. /// // Check the restrictions again to make sure that the user can create this account. if (wfReadOnly()) { // Indicate readOnlyPage error throw new FacebookUserException('readonlypage', null); } global $wgFbDisableLogin; if (empty($wgFbDisableLogin)) { // These two permissions don't apply in $wgFbDisableLogin mode because // then technically no users can create accounts if ($wgUser->isBlockedFromCreateAccount()) { wfDebug("Facebook: Blocked user was attempting to create account via Facebook Connect.\n"); throw new FacebookUserException('facebook-error', 'facebook-errortext'); } else { $titleObj = SpecialPage::getTitleFor('Connect'); $permErrors = $titleObj->getUserPermissionsErrors('createaccount', $wgUser, true); if (count($permErrors) > 0) { // Special case for permission errors throw new FacebookUserException($permErrors, 'createaccount'); } } } // If we are not allowing users to login locally, we should be checking // to see if the user is actually able to authenticate to the authenti- // cation server before they create an account (otherwise, they can // create a local account and login as any domain user). We only need // to check this for domains that aren't local. if ($domain != '' && $domain != 'local' && !$wgAuth->canCreateAccounts() && !$wgAuth->userExists($username)) { throw new FacebookUserException('facebook-error', 'wrongpassword'); } // IP-blocking (and open proxy blocking) protection from SpecialUserLogin global $wgEnableSorbs, $wgProxyWhitelist; $ip = wfGetIP(); if ($wgEnableSorbs && !in_array($ip, $wgProxyWhitelist) && $wgUser->inSorbsBlacklist($ip)) { throw new FacebookUserException('facebook-error', 'sorbs_create_account_reason'); } // Run a hook to let custom forms make sure that it is okay to proceed with // processing the form. This hook should only check preconditions and should // not store values. Values should be stored using the hook at the bottom of // this function. Can use 'this' to call // sendPage('chooseNameFormView', 'SOME-ERROR-MSG-CODE-HERE') if some of the // preconditions are invalid. #if (!wfRunHooks( 'SpecialConnect::createUser::validateForm', array( &$this ) )) { # return; #} $user = User::newFromName($username); if (!$user) { wfDebug("Facebook: Error creating new user.\n"); throw new FacebookUserException('facebook-error', 'facebook-error-creating-user'); } // TODO: Make user a Facebook user here: $fbUser = new FacebookUser($user); // Let extensions abort the account creation. // NOTE: Currently this is commented out because it seems that most wikis might have a // handful of restrictions that won't be needed on Facebook Connections. For instance, // requiring a CAPTCHA or age-verification, etc. Having a Facebook account as a pre- // requisite removes the need for that. /* $abortError = ''; if( !wfRunHooks( 'AbortNewAccount', array( $user, &$abortError ) ) ) { // Hook point to add extra creation throttles and blocks wfDebug( "SpecialConnect::createUser: a hook blocked creation\n" ); throw new FacebookUserException('facebook-error', 'facebook-error-user-creation-hook-aborted', array( $abortError )); } */ // Apply account-creation throttles global $wgAccountCreationThrottle, $wgMemc; if ($wgAccountCreationThrottle && $wgUser->isPingLimitable()) { $key = wfMemcKey('acctcreate', 'ip', $ip); $value = $wgMemc->get($key); if (!$value) { $wgMemc->set($key, 0, 86400); } if ($value >= $wgAccountCreationThrottle) { // 'acct_creation_throttle_hit' should actually use 'parseinline' not 'parse' in $wgOut->showErrorPage() throw new FacebookUserException('facebook-error', 'acct_creation_throttle_hit', array($wgAccountCreationThrottle)); } $wgMemc->incr($key); } /// END OF TYPICAL VALIDATIONS AND RESTRICTIONS ON ACCOUNT-CREATION. /// // Fill in the info we know $userinfo = $this->getUserInfo(); $email = FacebookUser::getOptionFromInfo('email', $userinfo); $realName = FacebookUser::getOptionFromInfo('fullname', $userinfo); $pass = ''; // Create the account (locally on main cluster or via $wgAuth on other clusters) // $wgAuth essentially checks to see if these are valid parameters for new users if (!$wgAuth->addUser($user, $pass, $email, $realName)) { wfDebug("Facebook: Error adding new user to database.\n"); throw new FacebookUserException('facebook-error', 'facebook-errortext'); } // Add the user to the local database (regardless of whether $wgAuth was used) // This is a custom version of similar code in SpecialUserLogin's LoginForm // with differences due to the fact that this code doesn't require a password, etc. global $wgExternalAuthType; if ($wgExternalAuthType) { $user = ExternalUser::addUser($user, $pass, $email, $realName); if (is_object($user)) { $extUser = ExternalUser::newFromName($username); $extUser->linkToLocal($user->getId()); $extEmail = $extUser->getPref('emailaddress'); if (!empty($extEmail) && empty($email)) { $user->setEmail($extEmail); } } } else { $user->addToDatabase(); } // Attach the user to their Facebook account in the database. // This must be done up here, because somewhere after this (I'm not too // sure where) the data must be in the database before copy-to-local is // done for shared setups. FacebookDB::addFacebookID($user, $this->id); $this->user = $user; $wgAuth->initUser($this->user, true); // $autocreate == true $wgAuth->updateUser($this->user); // No passwords for Facebook accounts. /* if ( $wgAuth->allowPasswordChange() ) { $this->user->setPassword( $pass ); } */ // Store which fields should be auto-updated from Facebook when the user logs in. global $wgRequest; $updateFormPrefix = 'wpUpdateUserInfo'; foreach (self::$availableUserUpdateOptions as $option) { if ($wgRequest->getVal($updateFormPrefix . $option, '') != '') { $user->setOption("facebook-update-on-login-{$option}", 1); } else { $user->setOption("facebook-update-on-login-{$option}", 0); } } // Process the FacebookPushEvent preference checkboxes if Push Events are enabled global $wgFbEnablePushToFacebook; if (!empty($wgFbEnablePushToFacebook)) { global $wgFbPushEventClasses; if (!empty($wgFbPushEventClasses)) { foreach ($wgFbPushEventClasses as $pushEventClassName) { $pushObj = new $pushEventClassName(); $className = get_class(); $prefName = $pushObj->getUserPreferenceName(); $this->user->setOption($prefName, $wgRequest->getCheck($prefName) ? '1' : '0'); } } // Save the preference for letting user select to never send anything to their newsfeed $prefName = FacebookPushEvent::$PREF_TO_DISABLE_ALL; $this->user->setOption($prefName, $wgRequest->getCheck($prefName) ? '1' : '0'); } // I think this should be done here $this->user->setToken(); // This is done via login() #$this->user->saveSettings(); // Log the user in $this->login(); // Update user count $ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1); $ssUpdate->doUpdate(); wfRunHooks('AddNewAccount', array($this->user)); // Allow custom form processing to store values since this form submission was successful. // This hook should not fail on invalid input, instead check the input using the SpecialConnect::createUser::validateForm hook above. #wfRunHooks( 'SpecialConnect::createUser::postProcessForm', array( &$this ) ); $wgUser->addNewUserLogEntryAutoCreate(); }