public function execute() { $user = $this->getUser(); $params = $this->extractRequestParams(); // If we're in JSON callback mode, no tokens can be obtained if ($this->lacksSameOriginSecurity()) { $this->dieUsage('Cannot obtain a centralauthtoken when using a callback', 'hascallback'); } if ($user->isAnon()) { $this->dieUsage('Anonymous users cannot obtain a centralauthtoken', 'notloggedin'); } if (CentralAuthHooks::hasApiToken()) { $this->dieUsage('Cannot obtain a centralauthtoken when using centralauthtoken', 'norecursion'); } $centralUser = CentralAuthUser::getInstance($user); if (!$centralUser->exists() || !$centralUser->isAttached()) { $this->dieUsage('Cannot obtain a centralauthtoken without an attached global account', 'notattached'); } $data = array('userName' => $user->getName(), 'token' => $centralUser->getAuthToken()); global $wgMemc; $loginToken = MWCryptRand::generateHex(32) . dechex($centralUser->getId()); $key = CentralAuthUser::memcKey('api-token', $loginToken); $wgMemc->add($key, $data, 60); $this->getResult()->addValue(null, $this->getModuleName(), array('centralauthtoken' => $loginToken)); }
public function crypt($plaintext) { if (count($this->args) == 0) { $this->args[] = MWCryptRand::generateHex(8); } $this->hash = md5($this->args[0] . '-' . md5($plaintext)); }
static function lqtThread($parser, $args, $parser, $frame) { $pout = $parser->getOutput(); // Prepare information. $title = Title::newFromText($args['thread']); $thread = null; if ($args['thread']) { if (is_numeric($args['thread'])) { $thread = Threads::withId($args['thread']); } elseif ($title) { $article = new Article($title, 0); $thread = Threads::withRoot($article); } } if (is_null($thread)) { return ''; } $data = array('type' => 'thread', 'args' => $args, 'thread' => $thread->id(), 'title' => $thread->title()); if (!isset($pout->mLqtReplacements)) { $pout->mLqtReplacements = array(); } // Generate a token $tok = MWCryptRand::generateHex(32); $text = '<!--LQT-THREAD-' . $tok . '-->'; $pout->mLqtReplacements[$text] = $data; return $text; }
/** * Serialize and save data to memcache * * Note that it also sets a time to live for the * cached version set to self::TTL * * @param string $cacheKey Cache key * @param mixed $data Data to send to memcached, will use serialize(); * * @return null */ private function memcacheSave($data) { $url_friendly_key = MWCryptRand::generateHex(16); $key = wfMemcKey($url_friendly_key, 'wpdsso'); $this->memcache->set($key, json_encode($data), self::TTL); return $url_friendly_key; }
public function crypt($plaintext) { if (count($this->args) == 0) { $this->args[] = MWCryptRand::generateHex(8); } $this->hash = md5($this->args[0] . '-' . md5($plaintext)); if (!is_string($this->hash) || strlen($this->hash) < 32) { throw new PasswordError('Error when hashing password.'); } }
protected function setUp() { // Needs to be before setup since this gets cached $this->mergeMwGlobalArrayValue('wgGroupPermissions', array('sysop' => array('deleterevision' => true))); parent::setUp(); // Make a few edits for us to play with for ($i = 1; $i <= 5; $i++) { self::editPage(self::$page, MWCryptRand::generateHex(10), 'summary'); $this->revs[] = Title::newFromText(self::$page)->getLatestRevID(Title::GAID_FOR_UPDATE); } }
protected static function getPreloadId($create_if_not_exists) { global $wgUser, $wgRequest; if (!$wgUser->isAnon()) { return ModerationPreload::User_to_PreloadId($wgUser); } $anon_id = $wgRequest->getSessionData('anon_id'); if (!$anon_id) { if (!$create_if_not_exists) { return false; } $anon_id = MWCryptRand::generateHex(32); $wgRequest->setSessionData('anon_id', $anon_id); } return ModerationPreload::AnonId_to_PreloadId($anon_id); }
/** * Handle redirection when the user needs to (re)authenticate. * * Send the user to the login form if needed; in case the request was a POST, stash in the * session and simulate it once the user gets back. * * @param string $subPage * @return bool False if execution should be stopped. * @throws ErrorPageError When the user is not allowed to use this page. */ protected function handleReauthBeforeExecute($subPage) { $authManager = AuthManager::singleton(); $request = $this->getRequest(); $key = 'AuthManagerSpecialPage:reauth:' . $this->getName(); $securityLevel = $this->getLoginSecurityLevel(); if ($securityLevel) { $securityStatus = AuthManager::singleton()->securitySensitiveOperationStatus($securityLevel); if ($securityStatus === AuthManager::SEC_REAUTH) { $queryParams = array_diff_key($request->getQueryValues(), ['title' => true]); if ($request->wasPosted()) { // unique ID in case the same special page is open in multiple browser tabs $uniqueId = MWCryptRand::generateHex(6); $key = $key . ':' . $uniqueId; $queryParams = ['authUniqueId' => $uniqueId] + $queryParams; $authData = array_diff_key($request->getValues(), $this->getPreservedParams(false), ['title' => 1]); $authManager->setAuthenticationSessionData($key, $authData); } $title = SpecialPage::getTitleFor('Userlogin'); $url = $title->getFullURL(['returnto' => $this->getFullTitle()->getPrefixedDBkey(), 'returntoquery' => wfArrayToCgi($queryParams), 'force' => $securityLevel], false, PROTO_HTTPS); $this->getOutput()->redirect($url); return false; } elseif ($securityStatus !== AuthManager::SEC_OK) { throw new ErrorPageError('cannotauth-not-allowed-title', 'cannotauth-not-allowed'); } } $uniqueId = $request->getVal('authUniqueId'); if ($uniqueId) { $key = $key . ':' . $uniqueId; $authData = $authManager->getAuthenticationSessionData($key); if ($authData) { $authManager->removeAuthenticationSessionData($key); $this->setRequest($authData, true); } } return true; }
private function printFooterThings() { // prepare login token: $loginToken = MWCryptRand::generateHex(32); if ($this->getSkin()->getTitle()->getText() != 'UserLogin') { // Skin userlogin page to avoid collision if (session_id() == '') { wfSetupSession(); } $this->getSkin()->getRequest()->setSessionData('wsLoginToken', $loginToken); } ?> <div class="why-sign-up-popup mobile-form-popup"> <h3> <?php echo wfMessage('settlein-skin-modal-whysignup-title')->plain(); ?> </h3> <?php echo wfMessage('settlein-skin-modal-whysignup-text')->plain(); ?> </div> <!-- Login popup form & wrapper --> <div id="login-popup-wrapper"> </div> <div class="login-popup-form mobile-form-popup"> <h3> <?php echo wfMessage('settlein-skin-modal-login-title')->plain(); ?> </h3> <p> <?php echo wfMessage('settlein-skin-modal-login-subtitle')->plain(); ?> </p> <form class="" method="post" action="<?php echo SpecialPage::getSafeTitleFor('UserLogin')->getFullURL('action=submitlogin&type=login'); ?> "> <div class="form-group"> <input type="text" class="form-control" placeholder="<?php echo wfMessage('settlein-skin-modal-login-email-placeholder')->plain(); ?> " name="wpName" /> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="<?php echo wfMessage('settlein-skin-modal-login-password-placeholder')->plain(); ?> " name="wpPassword" /> </div> <input type="hidden" name="wpLoginToken" value="<?php echo $loginToken; ?> " /> <input type="hidden" name="wpRemember" value="1" /> <div class="form-group"> <input type="submit" name="wpLoginAttempt" class="btn btn-primary" value="<?php echo wfMessage('settlein-skin-modal-login-login-button')->plain(); ?> "/> <a href="<?php echo SpecialPage::getSafeTitleFor('Userlogin')->getFullURL('type=signup'); ?> " class="btn btn-cyanide"> <?php echo wfMessage('settlein-skin-modal-login-signup-button')->plain(); ?> </a> <a href="<?php echo SpecialPage::getSafeTitleFor('PasswordReset')->getFullURL(); ?> " class="pull-right"> <?php echo wfMessage('settlein-skin-modal-login-reset-password')->plain(); ?> </a> </div> </form> </div> <!-- Add new article popup form & wrapper --> <div id="add-new-article-popup-wrapper"> </div> <div class="add-new-article-popup-form"> <h3> <?php echo wfMessage('settlein-skin-add-new-article-window-title')->plain(); ?> </h3> <p> <?php echo wfMessage('settlein-skin-add-new-article-window-description')->plain(); ?> </p> <form class="" method="post" action="" > <div class="form-group"> <label for="new_pageTitle"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-title')->plain(); ?> </label> <input type="text" class="form-control" placeholder="" name="Card[Title]" id="new_pageTitle" /> </div> <div class="form-group"> <label for="new_pageCategory"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-category')->plain(); ?> </label> <select class="form-control" name="Card[Tags]" id="new_pageCategory"> <option></option> <?php foreach ($this->categoriesList as $category) { ?> <option value="<?php echo $category; ?> "><?php echo $category; ?> </option> <?php } ?> </select> </div> <div class="form-group settle-geo-input" data-geo-type="country" data-state-input-name="new_pageState" data-city-input-name="new_pageCity"> <label for="new_pageCountry"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-country')->plain(); ?> </label> <select class="form-control" name="Card[Country]" id="new_pageCountry"> <option></option> <?php foreach ($this->countriesList as $val) { ?> <option data-geo-id="<?php echo $val['geonamesCode']; ?> " value="<?php echo $val['name']; ?> "><?php echo $val['name']; ?> </option> <?php } ?> </select> </div> <div class="form-group settle-geo-input" data-geo-type="state" data-city-input-name="new_pageCity"> <label for="new_pageState"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-state')->plain(); ?> </label> <select class="form-control" name="Card[State]" id="new_pageState"></select> </div> <div class="form-group settle-geo-input" data-geo-type="city"> <label for="new_pageCity"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-city')->plain(); ?> </label> <select class="form-control" name="Card[City]" id="new_pageCity"></select> </div> <div class="form-group"> <label for="new_pageLanguage"><?php echo wfMessage('settlein-skin-add-new-article-window-form-field-language')->plain(); ?> </label> <select class="form-control" name="pageLanguage" id="new_pageLanguage" style="display: none;"> <?php foreach ($this->connectedLanguagesList as $langCode => $langText) { ?> <option value="<?php echo $langCode; ?> "><?php echo $langText; ?> </option> <?php } ?> </select> <span style="display: block;"> <?php echo wfMessage('settlein-skin-add-new-article-window-form-other-languages')->plain(); ?> <?php global $wgSettleTranslateDomains; $shiftedLangs = array_splice($this->connectedLanguagesList, 1); ?> <?php foreach ($shiftedLangs as $langCode => $langText) { ?> <a target="_blank" href="//<?php echo $wgSettleTranslateDomains[$langCode]; ?> "><?php echo $langText; ?> </a> <?php } ?> </span> </div> <div class="new_page_suggestions"> <p></p> <ul> </ul> </div> <div class="form-group pull-right"> <a id="newpage_btn_cancel" href="#" class="btn btn-concrete"><?php echo wfMessage('settlein-skin-add-new-article-window-form-btn-cancel')->plain(); ?> </a> <a href="#" id="newpage_btn_submit" class="disabled btn btn-primary"><?php echo wfMessage('settlein-skin-add-new-article-window-form-btn-submit')->plain(); ?> </a> </div> </form> </div> <?php }
/** * Randomly generate a new createaccount token and attach it to the current session */ public static function setCreateaccountToken() { global $wgRequest; $wgRequest->setSessionData('wsCreateaccountToken', MWCryptRand::generateHex(32)); }
/** * Return an RFC4122 compliant v4 UUID * * @param $flags integer Bitfield (supports UIDGenerator::QUICK_RAND) * @return string * @throws MWException */ public static function newUUIDv4( $flags = 0 ) { $hex = ( $flags & self::QUICK_RAND ) ? wfRandomString( 31 ) : MWCryptRand::generateHex( 31 ); return sprintf( '%s-%s-%s-%s-%s', // "time_low" (32 bits) substr( $hex, 0, 8 ), // "time_mid" (16 bits) substr( $hex, 8, 4 ), // "time_hi_and_version" (16 bits) '4' . substr( $hex, 12, 3 ), // "clk_seq_hi_res (8 bits, variant is binary 10x) and "clk_seq_low" (8 bits) dechex( 0x8 | ( hexdec( $hex[15] ) & 0x3 ) ) . $hex[16] . substr( $hex, 17, 2 ), // "node" (48 bits) substr( $hex, 19, 12 ) ); }
/** * Renew the user's session id, using strong entropy */ private function renewSessionId() { global $wgSecureLogin, $wgCookieSecure; if ($wgSecureLogin && !$this->mStickHTTPS) { $wgCookieSecure = false; } // If either we don't trust PHP's entropy, or if we need // to change cookie settings when logging in because of // wpStickHTTPS, then change the session ID manually. $cookieParams = session_get_cookie_params(); if (wfCheckEntropy() && $wgCookieSecure == $cookieParams['secure']) { session_regenerate_id(false); } else { $tmp = $_SESSION; session_destroy(); wfSetupSession(MWCryptRand::generateHex(32)); $_SESSION = $tmp; } }
/** * Execute * @param $par Parameter passed to the page */ function execute($par) { global $wgRCShowWatchingUsers, $wgEnotifWatchlist, $wgShowUpdatedMarker; $user = $this->getUser(); $output = $this->getOutput(); # Anons don't get a watchlist if ($user->isAnon()) { $output->setPageTitle($this->msg('watchnologin')); $output->setRobotPolicy('noindex,nofollow'); $llink = Linker::linkKnown(SpecialPage::getTitleFor('Userlogin'), $this->msg('loginreqlink')->escaped(), array(), array('returnto' => $this->getTitle()->getPrefixedText())); $output->addHTML($this->msg('watchlistanontext')->rawParams($llink)->parse()); return; } // Add feed links $wlToken = $user->getOption('watchlisttoken'); if (!$wlToken) { $wlToken = MWCryptRand::generateHex(40); $user->setOption('watchlisttoken', $wlToken); $user->saveSettings(); } $this->addFeedLinks(array('action' => 'feedwatchlist', 'allrev' => 'allrev', 'wlowner' => $user->getName(), 'wltoken' => $wlToken)); $this->setHeaders(); $this->outputHeader(); $output->addSubtitle($this->msg('watchlistfor2', $user->getName())->rawParams(SpecialEditWatchlist::buildTools(null))); $request = $this->getRequest(); $mode = SpecialEditWatchlist::getMode($request, $par); if ($mode !== false) { # TODO: localise? switch ($mode) { case SpecialEditWatchlist::EDIT_CLEAR: $mode = 'clear'; break; case SpecialEditWatchlist::EDIT_RAW: $mode = 'raw'; break; default: $mode = null; } $title = SpecialPage::getTitleFor('EditWatchlist', $mode); $output->redirect($title->getLocalUrl()); return; } $nitems = $this->countItems(); if ($nitems == 0) { $output->addWikiMsg('nowatchlist'); return; } // @TODO: use FormOptions! $defaults = array('days' => floatval($user->getOption('watchlistdays')), 'hideMinor' => (int) $user->getBoolOption('watchlisthideminor'), 'hideBots' => (int) $user->getBoolOption('watchlisthidebots'), 'hideAnons' => (int) $user->getBoolOption('watchlisthideanons'), 'hideLiu' => (int) $user->getBoolOption('watchlisthideliu'), 'hidePatrolled' => (int) $user->getBoolOption('watchlisthidepatrolled'), 'hideOwn' => (int) $user->getBoolOption('watchlisthideown'), 'namespace' => 'all', 'invert' => false, 'associated' => false); $this->customFilters = array(); wfRunHooks('SpecialWatchlistFilters', array($this, &$this->customFilters)); foreach ($this->customFilters as $key => $params) { $defaults[$key] = $params['msg']; } # Extract variables from the request, falling back to user preferences or # other default values if these don't exist $prefs['days'] = floatval($user->getOption('watchlistdays')); $prefs['hideminor'] = $user->getBoolOption('watchlisthideminor'); $prefs['hidebots'] = $user->getBoolOption('watchlisthidebots'); $prefs['hideanons'] = $user->getBoolOption('watchlisthideanons'); $prefs['hideliu'] = $user->getBoolOption('watchlisthideliu'); $prefs['hideown'] = $user->getBoolOption('watchlisthideown'); $prefs['hidepatrolled'] = $user->getBoolOption('watchlisthidepatrolled'); # Get query variables $values = array(); $values['days'] = $request->getVal('days', $prefs['days']); $values['hideMinor'] = (int) $request->getBool('hideMinor', $prefs['hideminor']); $values['hideBots'] = (int) $request->getBool('hideBots', $prefs['hidebots']); $values['hideAnons'] = (int) $request->getBool('hideAnons', $prefs['hideanons']); $values['hideLiu'] = (int) $request->getBool('hideLiu', $prefs['hideliu']); $values['hideOwn'] = (int) $request->getBool('hideOwn', $prefs['hideown']); $values['hidePatrolled'] = (int) $request->getBool('hidePatrolled', $prefs['hidepatrolled']); foreach ($this->customFilters as $key => $params) { $values[$key] = (int) $request->getBool($key); } # Get namespace value, if supplied, and prepare a WHERE fragment $nameSpace = $request->getIntOrNull('namespace'); $invert = $request->getBool('invert'); $associated = $request->getBool('associated'); if (!is_null($nameSpace)) { $eq_op = $invert ? '!=' : '='; $bool_op = $invert ? 'AND' : 'OR'; $nameSpace = intval($nameSpace); // paranioa if (!$associated) { $nameSpaceClause = "rc_namespace {$eq_op} {$nameSpace}"; } else { $associatedNS = MWNamespace::getAssociated($nameSpace); $nameSpaceClause = "rc_namespace {$eq_op} {$nameSpace} " . $bool_op . " rc_namespace {$eq_op} {$associatedNS}"; } } else { $nameSpace = ''; $nameSpaceClause = ''; } $values['namespace'] = $nameSpace; $values['invert'] = $invert; $values['associated'] = $associated; if (is_null($values['days']) || !is_numeric($values['days'])) { $big = 1000; /* The magical big */ if ($nitems > $big) { # Set default cutoff shorter $values['days'] = $defaults['days'] = 12.0 / 24.0; # 12 hours... } else { $values['days'] = $defaults['days']; # default cutoff for shortlisters } } else { $values['days'] = floatval($values['days']); } // Dump everything here $nondefaults = array(); foreach ($defaults as $name => $defValue) { wfAppendToArrayIfNotDefault($name, $values[$name], $defaults, $nondefaults); } if (($wgEnotifWatchlist || $wgShowUpdatedMarker) && $request->getVal('reset') && $request->wasPosted()) { $user->clearAllNotifications(); $output->redirect($this->getTitle()->getFullUrl($nondefaults)); return; } $dbr = wfGetDB(DB_SLAVE, 'watchlist'); # Possible where conditions $conds = array(); if ($values['days'] > 0) { $conds[] = "rc_timestamp > '" . $dbr->timestamp(time() - intval($values['days'] * 86400)) . "'"; } # If the watchlist is relatively short, it's simplest to zip # down its entirety and then sort the results. # If it's relatively long, it may be worth our while to zip # through the time-sorted page list checking for watched items. # Up estimate of watched items by 15% to compensate for talk pages... # Toggles if ($values['hideOwn']) { $conds[] = 'rc_user != ' . $user->getId(); } if ($values['hideBots']) { $conds[] = 'rc_bot = 0'; } if ($values['hideMinor']) { $conds[] = 'rc_minor = 0'; } if ($values['hideLiu']) { $conds[] = 'rc_user = 0'; } if ($values['hideAnons']) { $conds[] = 'rc_user != 0'; } if ($user->useRCPatrol() && $values['hidePatrolled']) { $conds[] = 'rc_patrolled != 1'; } if ($nameSpaceClause) { $conds[] = $nameSpaceClause; } # Toggle watchlist content (all recent edits or just the latest) if ($user->getOption('extendwatchlist')) { $limitWatchlist = intval($user->getOption('wllimit')); $usePage = false; } else { # Top log Ids for a page are not stored $conds[] = 'rc_this_oldid=page_latest OR rc_type=' . RC_LOG; $limitWatchlist = 0; $usePage = true; } # Show a message about slave lag, if applicable $lag = wfGetLB()->safeGetLag($dbr); if ($lag > 0) { $output->showLagWarning($lag); } # Create output form $form = Xml::fieldset($this->msg('watchlist-options')->text(), false, array('id' => 'mw-watchlist-options')); # Show watchlist header $form .= $this->msg('watchlist-details')->numParams($nitems)->parse(); if ($user->getOption('enotifwatchlistpages') && $wgEnotifWatchlist) { $form .= $this->msg('wlheader-enotif')->parseAsBlock() . "\n"; } if ($wgShowUpdatedMarker) { $form .= Xml::openElement('form', array('method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-resetbutton')) . $this->msg('wlheader-showupdated')->parse() . ' ' . Xml::submitButton($this->msg('enotif_reset')->text(), array('name' => 'dummy')) . Html::hidden('reset', 'all'); foreach ($nondefaults as $key => $value) { $form .= Html::hidden($key, $value); } $form .= Xml::closeElement('form'); } $form .= '<hr />'; $tables = array('recentchanges', 'watchlist'); $fields = RecentChange::selectFields(); $join_conds = array('watchlist' => array('INNER JOIN', array('wl_user' => $user->getId(), 'wl_namespace=rc_namespace', 'wl_title=rc_title'))); $options = array('ORDER BY' => 'rc_timestamp DESC'); if ($wgShowUpdatedMarker) { $fields[] = 'wl_notificationtimestamp'; } if ($limitWatchlist) { $options['LIMIT'] = $limitWatchlist; } $rollbacker = $user->isAllowed('rollback'); if ($usePage || $rollbacker) { $tables[] = 'page'; $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id'); if ($rollbacker) { $fields[] = 'page_latest'; } } ChangeTags::modifyDisplayQuery($tables, $fields, $conds, $join_conds, $options, ''); wfRunHooks('SpecialWatchlistQuery', array(&$conds, &$tables, &$join_conds, &$fields)); $res = $dbr->select($tables, $fields, $conds, __METHOD__, $options, $join_conds); $numRows = $res->numRows(); /* Start bottom header */ $lang = $this->getLanguage(); $wlInfo = ''; if ($values['days'] > 0) { $timestamp = wfTimestampNow(); $wlInfo = $this->msg('wlnote')->numParams($numRows, round($values['days'] * 24))->params($lang->userDate($timestamp, $user), $lang->userTime($timestamp, $user))->parse() . '<br />'; } $cutofflinks = "\n" . $this->cutoffLinks($values['days'], $nondefaults) . "<br />\n"; # Spit out some control panel links $filters = array('hideMinor' => 'rcshowhideminor', 'hideBots' => 'rcshowhidebots', 'hideAnons' => 'rcshowhideanons', 'hideLiu' => 'rcshowhideliu', 'hideOwn' => 'rcshowhidemine', 'hidePatrolled' => 'rcshowhidepatr'); foreach ($this->customFilters as $key => $params) { $filters[$key] = $params['msg']; } // Disable some if needed if (!$user->useNPPatrol()) { unset($filters['hidePatrolled']); } $links = array(); foreach ($filters as $name => $msg) { $links[] = $this->showHideLink($nondefaults, $msg, $name, $values[$name]); } # Namespace filter and put the whole form together. $form .= $wlInfo; $form .= $cutofflinks; $form .= $lang->pipeList($links); $form .= Xml::openElement('form', array('method' => 'post', 'action' => $this->getTitle()->getLocalUrl(), 'id' => 'mw-watchlist-form-namespaceselector')); $form .= '<hr /><p>'; $form .= Html::namespaceSelector(array('selected' => $nameSpace, 'all' => '', 'label' => $this->msg('namespace')->text()), array('name' => 'namespace', 'id' => 'namespace', 'class' => 'namespaceselector')) . ' '; $form .= Xml::checkLabel($this->msg('invert')->text(), 'invert', 'nsinvert', $invert, array('title' => $this->msg('tooltip-invert')->text())) . ' '; $form .= Xml::checkLabel($this->msg('namespace_association')->text(), 'associated', 'associated', $associated, array('title' => $this->msg('tooltip-namespace_association')->text())) . ' '; $form .= Xml::submitButton($this->msg('allpagessubmit')->text()) . '</p>'; $form .= Html::hidden('days', $values['days']); foreach ($filters as $key => $msg) { if ($values[$key]) { $form .= Html::hidden($key, 1); } } $form .= Xml::closeElement('form'); $form .= Xml::closeElement('fieldset'); $output->addHTML($form); # If there's nothing to show, stop here if ($numRows == 0) { $output->addWikiMsg('watchnochange'); return; } /* End bottom header */ /* Do link batch query */ $linkBatch = new LinkBatch(); foreach ($res as $row) { $userNameUnderscored = str_replace(' ', '_', $row->rc_user_text); if ($row->rc_user != 0) { $linkBatch->add(NS_USER, $userNameUnderscored); } $linkBatch->add(NS_USER_TALK, $userNameUnderscored); $linkBatch->add($row->rc_namespace, $row->rc_title); } $linkBatch->execute(); $dbr->dataSeek($res, 0); $list = ChangesList::newFromContext($this->getContext()); $list->setWatchlistDivs(); $s = $list->beginRecentChangesList(); $counter = 1; foreach ($res as $obj) { # Make RC entry $rc = RecentChange::newFromRow($obj); $rc->counter = $counter++; if ($wgShowUpdatedMarker) { $updated = $obj->wl_notificationtimestamp; } else { $updated = false; } if ($wgRCShowWatchingUsers && $user->getOption('shownumberswatching')) { $rc->numberofWatchingusers = $dbr->selectField('watchlist', 'COUNT(*)', array('wl_namespace' => $obj->rc_namespace, 'wl_title' => $obj->rc_title), __METHOD__); } else { $rc->numberofWatchingusers = 0; } $s .= $list->recentChangesLine($rc, $updated, $counter); } $s .= $list->endRecentChangesList(); $output->addHTML($s); }
/** * Renew the user's session id, using strong entropy */ private function renewSessionId() { if (wfCheckEntropy()) { session_regenerate_id(false); } else { //If we don't trust PHP's entropy, we have to replace the session manually $tmp = $_SESSION; session_unset(); session_write_close(); session_id(MWCryptRand::generateHex(32)); session_start(); $_SESSION = $tmp; } }
/** * @return Title */ function scratchTitle() { return Title::makeTitle(NS_LQT_THREAD, MWCryptRand::generateHex(32)); }
/** * Make a new-style password hash * * @param $password String Plain-text password * @param bool|string $salt Optional salt, may be random or the user ID. * If unspecified or false, will generate one automatically * @return String Password hash */ public static function crypt($password, $salt = false) { global $wgPasswordSalt; $hash = ''; if (!wfRunHooks('UserCryptPassword', array(&$password, &$salt, &$wgPasswordSalt, &$hash))) { return $hash; } if ($wgPasswordSalt) { if ($salt === false) { $salt = MWCryptRand::generateHex(8); } return ':B:' . $salt . ':' . md5($salt . '-' . md5($password)); } else { return ':A:' . md5($password); } }
/** * Fetch the secret keys for self::setSecret() and self::getSecret(). * @return string[] Encryption key, HMAC key */ private function getSecretKeys() { global $wgSessionSecret, $wgSecretKey; $wikiSecret = $wgSessionSecret ?: $wgSecretKey; $userSecret = $this->get('wsSessionSecret', null); if ($userSecret === null) { $userSecret = \MWCryptRand::generateHex(32); $this->set('wsSessionSecret', $userSecret); } $keymats = hash_pbkdf2('sha256', $wikiSecret, $userSecret, 10001, 64, true); return [substr($keymats, 0, 32), substr($keymats, 32, 32)]; }
/** * Save the BotPassword to the database * @param string $operation 'update' or 'insert' * @param Password|null $password Password to set. * @return bool Success */ public function save($operation, Password $password = null) { $conds = array('bp_user' => $this->centralId, 'bp_app_id' => $this->appId); $fields = array('bp_token' => MWCryptRand::generateHex(User::TOKEN_LENGTH), 'bp_restrictions' => $this->restrictions->toJson(), 'bp_grants' => FormatJson::encode($this->grants)); if ($password !== null) { $fields['bp_password'] = $password->toString(); } elseif ($operation === 'insert') { $fields['bp_password'] = PasswordFactory::newInvalidPassword()->toString(); } $dbw = self::getDB(DB_MASTER); switch ($operation) { case 'insert': $dbw->insert('bot_passwords', $fields + $conds, __METHOD__, array('IGNORE')); break; case 'update': $dbw->update('bot_passwords', $fields, $conds, __METHOD__); break; default: return false; } $ok = (bool) $dbw->affectedRows(); if ($ok) { $this->token = $dbw->selectField('bot_passwords', 'bp_token', $conds, __METHOD__); $this->isSaved = true; } return $ok; }
/** * Generate a random string suitable for a password * * @param int $minLength Minimum length of password to generate * @return string */ public static function generateRandomPasswordString($minLength = 10) { // Decide the final password length based on our min password length, // stopping at a minimum of 10 chars. $length = max(10, $minLength); // Multiply by 1.25 to get the number of hex characters we need // Generate random hex chars $hex = MWCryptRand::generateHex(ceil($length * 1.25)); // Convert from base 16 to base 32 to get a proper password like string return substr(Wikimedia\base_convert($hex, 16, 32, $length), -$length); }
/** * Create an API centralauth token * @return string|bool Token */ static function getApiCentralAuthToken() { global $wgUser; if (!$wgUser->isAnon() && !self::hasApiToken()) { $centralUser = CentralAuthUser::getInstance($wgUser); if ($centralUser->exists() && $centralUser->isAttached()) { $data = array('userName' => $wgUser->getName(), 'token' => $centralUser->getAuthToken()); global $wgMemc; $loginToken = MWCryptRand::generateHex(32) . dechex($centralUser->getId()); $key = CentralAuthUser::memcKey('api-token', $loginToken); $wgMemc->add($key, $data, 60); return $loginToken; } } return false; }
/** * Render Login-ext */ function renderLoginExt($skin, $context) { global $wgUser, $wgRequest, $wgScript, $wgTweekiReturnto; if (session_id() == '') { wfSetupSession(); } //build path for form action $returnto = $skin->getSkin()->getTitle()->getFullText(); if ($returnto == SpecialPage::getTitleFor('UserLogin') || $returnto == SpecialPage::getTitleFor('UserLogout')) { $returnto = Title::newMainPage()->getFullText(); } $returnto = $wgRequest->getVal('returnto', $returnto); if (isset($wgTweekiReturnto) && $returnto == Title::newMainPage()->getFullText()) { $returnto = $wgTweekiReturnto; } $action = $wgScript . '?title=special:userlogin&action=submitlogin&type=login&returnto=' . $returnto; //create login token if it doesn't exist if (!$wgRequest->getSessionData('wsLoginToken')) { $wgRequest->setSessionData('wsLoginToken', MWCryptRand::generateHex(32)); } $wgUser->setCookies(); $dropdown['class'] = ' dropdown-toggle'; $dropdown['data-toggle'] = 'dropdown'; $dropdown['text'] = $this->getMsg('userlogin')->text(); $dropdown['html'] = $dropdown['text'] . ' <b class="caret"></b>'; $dropdown['href'] = '#'; $dropdown['type'] = 'button'; $dropdown['id'] = 'n-login-ext'; $renderedDropdown = TweekiHooks::makeLink($dropdown); echo '<li class="nav"> ' . $renderedDropdown . ' <ul class="dropdown-menu" role="menu" aria-labelledby="' . $this->getMsg('userlogin')->text() . '" id="loginext"> <form action="' . $action . '" method="post" name="userloginext" class="clearfix"> <div class="form-group"> <label for="wpName2" class="hidden-xs"> ' . $this->getMsg('userlogin-yourname')->text() . ' </label>'; echo Html::input('wpName', null, 'text', array('class' => 'form-control', 'id' => 'wpName2', 'tabindex' => '101', 'placeholder' => $this->getMsg('userlogin-yourname-ph')->text())); echo '</div> <div class="form-group"> <label for="wpPassword2" class="hidden-xs"> ' . $this->getMsg('userlogin-yourpassword')->text() . ' </label>'; echo Html::input('wpPassword', null, 'password', array('class' => 'form-control', 'id' => 'wpPassword2', 'tabindex' => '102', 'placeholder' => $this->getMsg('userlogin-yourpassword-ph')->text())); echo '</div> <div class="form-group"> <button type="submit" name="wpLoginAttempt" tabindex="103" id="wpLoginAttempt2" class="pull-right btn btn-default btn-block"> ' . $this->getMsg('pt-login-button')->text() . ' </button> </div> <input type="hidden" value="' . $wgRequest->getSessionData('wsLoginToken') . '" name="wpLoginToken"> </form>'; if ($wgUser->isAllowed('createaccount')) { echo '<div> <a href="' . $wgScript . '?title=special:userlogin&type=signup" class="btn btn-link center-block"> ' . $this->getMsg('createaccount')->text() . ' </a> </div>'; } echo ' </ul> </li>'; echo '<script> $( document ).ready( function() { $( "#n-login" ).click( function() { if( ! $( this ).parent().hasClass( "open" ) ) { setTimeout( \'$( "#wpName2" ).focus();\', 500 ); } }); }); </script>'; }
/** * Return an RFC4122 compliant v4 UUID * * @param int $flags Bitfield (supports UIDGenerator::QUICK_RAND) * @return string * @throws MWException */ public static function newUUIDv4($flags = 0) { $hex = $flags & self::QUICK_RAND ? wfRandomString(31) : MWCryptRand::generateHex(31); return sprintf('%s-%s-%s-%s-%s', substr($hex, 0, 8), substr($hex, 8, 4), '4' . substr($hex, 12, 3), dechex(0x8 | hexdec($hex[15]) & 0x3) . $hex[16] . substr($hex, 17, 2), substr($hex, 19, 12)); }
/** * Generate, store, and return a new e-mail confirmation code. * A hash (unsalted, since it's used as a key) is stored. * * @note Call saveSettings() after calling this function to commit * this change to the database. * * @param string &$expiration Accepts the expiration time * @return string New token */ protected function confirmationToken(&$expiration) { global $wgUserEmailConfirmationTokenExpiry; $now = time(); $expires = $now + $wgUserEmailConfirmationTokenExpiry; $expiration = wfTimestamp(TS_MW, $expires); $this->load(); $token = MWCryptRand::generateHex(32); $hash = md5($token); $this->mEmailToken = $hash; $this->mEmailTokenExpires = $expiration; return $token; }
/** * Set the central session data * * $refreshId can have three values: * - True : refresh the SessionID when setting the cookie to a new random ID. * - String : refresh the SessionID when setting the cookie to the given ID. * - False : use the SessionID of the client cookie (make a new one if there is none). * * @param $data Array * @param $refreshId Bool|String * @param bool $secure * true: Force setting the secure attribute when setting the cookie * false: Force NOT setting the secure attribute when setting the cookie * null (default): Use the default ($wgCookieSecure) to set the secure attribute * @return string Session ID */ static function setSession($data, $refreshId = false, $secure = null) { global $wgCentralAuthCookies, $wgCentralAuthCookiePrefix, $wgMemc; if (!$wgCentralAuthCookies) { return null; } if ($refreshId || !isset($_COOKIE[$wgCentralAuthCookiePrefix . 'Session'])) { $id = is_string($refreshId) ? $refreshId : MWCryptRand::generateHex(32); self::setCookie('Session', $id, 0, $secure); } else { $id = $_COOKIE[$wgCentralAuthCookiePrefix . 'Session']; } $data['sessionId'] = $id; $key = self::memcKey('session', $id); $wgMemc->set($key, $data, 86400); return $id; }
/** * Reset the session_id * * @since 1.22 */ function wfResetSessionID() { global $wgCookieSecure; $oldSessionId = session_id(); $cookieParams = session_get_cookie_params(); if (wfCheckEntropy() && $wgCookieSecure == $cookieParams['secure']) { session_regenerate_id(false); } else { $tmp = $_SESSION; session_destroy(); wfSetupSession(MWCryptRand::generateHex(32)); $_SESSION = $tmp; } $newSessionId = session_id(); Hooks::run('ResetSessionID', array($oldSessionId, $newSessionId)); }
/** * Gets a 32 character alphanumeric random string to be used for stats. * @return string */ private static function getEditingStatsId() { if (self::$statsId) { return self::$statsId; } return self::$statsId = MWCryptRand::generateHex(32); }
/** * Generate a secret value for variables using our CryptRand generator. * Produce a warning if the random source was insecure. * * @param $keys Array * @return Status */ protected function doGenerateKeys($keys) { $status = Status::newGood(); $strong = true; foreach ($keys as $name => $length) { $secretKey = MWCryptRand::generateHex($length, true); if (!MWCryptRand::wasStrong()) { $strong = false; } $this->setVar($name, $secretKey); } if (!$strong) { $names = array_keys($keys); $names = preg_replace('/^(.*)$/', '\\$$1', $names); global $wgLang; $status->warning('config-insecure-keys', $wgLang->listToText($names), count($names)); } return $status; }
/** * Override session_id before session startup if php's built-in * session generation code is not secure. */ function wfFixSessionID() { // If the cookie or session id is already set we already have a session and should abort if (isset($_COOKIE[session_name()]) || session_id()) { return; } // PHP's built-in session entropy is enabled if: // - entropy_file is set or you're on Windows with php 5.3.3+ // - AND entropy_length is > 0 // We treat it as disabled if it doesn't have an entropy length of at least 32 $entropyEnabled = (wfIsWindows() && version_compare(PHP_VERSION, '5.3.3', '>=') || ini_get('session.entropy_file')) && intval(ini_get('session.entropy_length')) >= 32; // If built-in entropy is not enabled or not sufficient override php's built in session id generation code if (!$entropyEnabled) { wfDebug(__METHOD__ . ": PHP's built in entropy is disabled or not sufficient, overriding session id generation using our cryptrand source.\n"); session_id(MWCryptRand::generateHex(32)); } }
/** * Generate a new random session ID * @return string */ public function generateSessionId() { do { $id = wfBaseConvert(\MWCryptRand::generateHex(40), 16, 32, 32); $key = wfMemcKey('MWSession', $id); } while (isset($this->allSessionIds[$id]) || is_array($this->store->get($key))); return $id; }
/** * Get a unique, stable identifier for this wiki * * If the identifier does not already exist, create it and save it in the * database. The identifier is randomly-generated. * * @return string 32-character hex string */ private function getOrCreatePingbackId() { if (!$this->id) { $id = wfGetDB(DB_REPLICA)->selectField('updatelog', 'ul_value', ['ul_key' => 'PingBack']); if ($id == false) { $id = MWCryptRand::generateHex(32); $dbw = wfGetDB(DB_MASTER); $dbw->insert('updatelog', ['ul_key' => 'PingBack', 'ul_value' => $id], __METHOD__, 'IGNORE'); if (!$dbw->affectedRows()) { $id = $dbw->selectField('updatelog', 'ul_value', ['ul_key' => 'PingBack']); } } $this->id = $id; } return $this->id; }