public function doRun()
 {
     if (!class_exists('RenameuserSQL')) {
         throw new Exception('Extension:Renameuser is not installed');
     }
     $from = $this->params['from'];
     $to = $this->params['to'];
     $this->updateStatus('inprogress');
     if (isset($this->params['force']) && $this->params['force']) {
         // If we're dealing with an invalid username, load the data ourselves to avoid
         // any normalization at all done by User or Title.
         $row = wfGetDB(DB_MASTER)->selectRow('user', User::selectFields(), array('user_name' => $from), __METHOD__);
         $oldUser = User::newFromRow($row);
     } else {
         $oldUser = User::newFromName($from);
     }
     $rename = new RenameuserSQL($from, $to, $oldUser->getId(), $this->getRenameUser(), array('checkIfUserExists' => false, 'debugPrefix' => 'GlobalRename', 'reason' => $this->params['reason']));
     if (!$rename->rename()) {
         // This should never happen!
         // If it does happen, the user will be locked out of their account
         // until a sysadmin intervenes...
         throw new Exception('RenameuserSQL::rename returned false.');
     }
     if ($this->params['movepages']) {
         $this->movePages($oldUser);
     }
     if ($this->params['promotetoglobal']) {
         $this->promoteToGlobal();
     }
     $this->done();
 }
 /**
  * Get all sandboxed users.
  * @return UserArray List of users.
  */
 public static function getUsers()
 {
     $dbw = wfGetDB(DB_MASTER);
     $tables = array('user', 'user_groups');
     $fields = User::selectFields();
     $conds = array('ug_group' => 'translate-sandboxed', 'ug_user = user_id');
     $res = $dbw->select($tables, $fields, $conds, __METHOD__);
     return UserArray::newFromResult($res);
 }
Example #3
0
 /**
  * @param $ids array
  * @return UserArrayFromResult
  */
 static function newFromIDs($ids)
 {
     $ids = array_map('intval', (array) $ids);
     // paranoia
     if (!$ids) {
         // Database::select() doesn't like empty arrays
         return new ArrayIterator(array());
     }
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('user', User::selectFields(), array('user_id' => array_unique($ids)), __METHOD__);
     return self::newFromResult($res);
 }
Example #4
0
 /**
  * @since 1.25
  * @param array $names
  * @return UserArrayFromResult
  */
 static function newFromNames($names)
 {
     $names = array_map('strval', (array) $names);
     // paranoia
     if (!$names) {
         // Database::select() doesn't like empty arrays
         return new ArrayIterator([]);
     }
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('user', User::selectFields(), ['user_name' => array_unique($names)], __METHOD__);
     return self::newFromResult($res);
 }
 protected function preprocessResults($results)
 {
     $names = array();
     foreach ($results as $result) {
         $names[] = $result->utr_name;
     }
     if (!$names) {
         return;
     }
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select(array('user', 'ipblocks'), User::selectFields(), array('user_name' => array_unique($names), 'ipb_deleted IS NULL OR ipb_deleted = 0'), __METHOD__, array(), array('ipblocks' => array('LEFT JOIN', 'user_id = ipb_user')));
     $userArray = UserArray::newFromResult($res);
     $lb = new LinkBatch();
     foreach ($userArray as $user) {
         $this->users[$user->getName()] = $user;
         $lb->addObj($user->getUserPage());
         $lb->addObj($user->getTalkPage());
     }
     $lb->execute();
 }
Example #6
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     if (!is_null($params['prop'])) {
         $this->prop = array_flip($params['prop']);
     } else {
         $this->prop = [];
     }
     $users = (array) $params['users'];
     $goodNames = $done = [];
     $result = $this->getResult();
     // Canonicalize user names
     foreach ($users as $u) {
         $n = User::getCanonicalName($u);
         if ($n === false || $n === '') {
             $vals = ['name' => $u, 'invalid' => true];
             $fit = $result->addValue(['query', $this->getModuleName()], null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('users', implode('|', array_diff($users, $done)));
                 $goodNames = [];
                 break;
             }
             $done[] = $u;
         } else {
             $goodNames[] = $n;
         }
     }
     $result = $this->getResult();
     if (count($goodNames)) {
         $this->addTables('user');
         $this->addFields(User::selectFields());
         $this->addWhereFld('user_name', $goodNames);
         $this->showHiddenUsersAddBlockInfo(isset($this->prop['blockinfo']));
         $data = [];
         $res = $this->select(__METHOD__);
         $this->resetQueryParams();
         // get user groups if needed
         if (isset($this->prop['groups']) || isset($this->prop['rights'])) {
             $userGroups = [];
             $this->addTables('user');
             $this->addWhereFld('user_name', $goodNames);
             $this->addTables('user_groups');
             $this->addJoinConds(['user_groups' => ['INNER JOIN', 'ug_user=user_id']]);
             $this->addFields(['user_name', 'ug_group']);
             $userGroupsRes = $this->select(__METHOD__);
             foreach ($userGroupsRes as $row) {
                 $userGroups[$row->user_name][] = $row->ug_group;
             }
         }
         foreach ($res as $row) {
             // create user object and pass along $userGroups if set
             // that reduces the number of database queries needed in User dramatically
             if (!isset($userGroups)) {
                 $user = User::newFromRow($row);
             } else {
                 if (!isset($userGroups[$row->user_name]) || !is_array($userGroups[$row->user_name])) {
                     $userGroups[$row->user_name] = [];
                 }
                 $user = User::newFromRow($row, ['user_groups' => $userGroups[$row->user_name]]);
             }
             $name = $user->getName();
             $data[$name]['userid'] = $user->getId();
             $data[$name]['name'] = $name;
             if (isset($this->prop['editcount'])) {
                 $data[$name]['editcount'] = $user->getEditCount();
             }
             if (isset($this->prop['registration'])) {
                 $data[$name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $user->getRegistration());
             }
             if (isset($this->prop['groups'])) {
                 $data[$name]['groups'] = $user->getEffectiveGroups();
             }
             if (isset($this->prop['implicitgroups'])) {
                 $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
             }
             if (isset($this->prop['rights'])) {
                 $data[$name]['rights'] = $user->getRights();
             }
             if ($row->ipb_deleted) {
                 $data[$name]['hidden'] = true;
             }
             if (isset($this->prop['blockinfo']) && !is_null($row->ipb_by_text)) {
                 $data[$name]['blockid'] = (int) $row->ipb_id;
                 $data[$name]['blockedby'] = $row->ipb_by_text;
                 $data[$name]['blockedbyid'] = (int) $row->ipb_by;
                 $data[$name]['blockedtimestamp'] = wfTimestamp(TS_ISO_8601, $row->ipb_timestamp);
                 $data[$name]['blockreason'] = $row->ipb_reason;
                 $data[$name]['blockexpiry'] = $row->ipb_expiry;
             }
             if (isset($this->prop['emailable'])) {
                 $data[$name]['emailable'] = $user->canReceiveEmail();
             }
             if (isset($this->prop['gender'])) {
                 $gender = $user->getOption('gender');
                 if (strval($gender) === '') {
                     $gender = 'unknown';
                 }
                 $data[$name]['gender'] = $gender;
             }
             if (isset($this->prop['centralids'])) {
                 $data[$name] += ApiQueryUserInfo::getCentralUserInfo($this->getConfig(), $user, $params['attachedwiki']);
             }
             if (!is_null($params['token'])) {
                 $tokenFunctions = $this->getTokenFunctions();
                 foreach ($params['token'] as $t) {
                     $val = call_user_func($tokenFunctions[$t], $user);
                     if ($val === false) {
                         $this->setWarning("Action '{$t}' is not allowed for the current user");
                     } else {
                         $data[$name][$t . 'token'] = $val;
                     }
                 }
             }
         }
     }
     $context = $this->getContext();
     // Second pass: add result data to $retval
     foreach ($goodNames as $u) {
         if (!isset($data[$u])) {
             $data[$u] = ['name' => $u];
             $urPage = new UserrightsPage();
             $urPage->setContext($context);
             $iwUser = $urPage->fetchUser($u);
             if ($iwUser instanceof UserRightsProxy) {
                 $data[$u]['interwiki'] = true;
                 if (!is_null($params['token'])) {
                     $tokenFunctions = $this->getTokenFunctions();
                     foreach ($params['token'] as $t) {
                         $val = call_user_func($tokenFunctions[$t], $iwUser);
                         if ($val === false) {
                             $this->setWarning("Action '{$t}' is not allowed for the current user");
                         } else {
                             $data[$u][$t . 'token'] = $val;
                         }
                     }
                 }
             } else {
                 $data[$u]['missing'] = true;
                 if (isset($this->prop['cancreate'])) {
                     $status = MediaWiki\Auth\AuthManager::singleton()->canCreateAccount($u);
                     $data[$u]['cancreate'] = $status->isGood();
                     if (!$status->isGood()) {
                         $data[$u]['cancreateerror'] = $this->getErrorFormatter()->arrayFromStatus($status);
                     }
                 }
             }
         } else {
             if (isset($this->prop['groups']) && isset($data[$u]['groups'])) {
                 ApiResult::setArrayType($data[$u]['groups'], 'array');
                 ApiResult::setIndexedTagName($data[$u]['groups'], 'g');
             }
             if (isset($this->prop['implicitgroups']) && isset($data[$u]['implicitgroups'])) {
                 ApiResult::setArrayType($data[$u]['implicitgroups'], 'array');
                 ApiResult::setIndexedTagName($data[$u]['implicitgroups'], 'g');
             }
             if (isset($this->prop['rights']) && isset($data[$u]['rights'])) {
                 ApiResult::setArrayType($data[$u]['rights'], 'array');
                 ApiResult::setIndexedTagName($data[$u]['rights'], 'r');
             }
         }
         $fit = $result->addValue(['query', $this->getModuleName()], null, $data[$u]);
         if (!$fit) {
             $this->setContinueEnumParameter('users', implode('|', array_diff($users, $done)));
             break;
         }
         $done[] = $u;
     }
     $result->addIndexedTagName(['query', $this->getModuleName()], 'user');
 }
 /**
  * Process the form.  At this point we know that the user passes all the criteria in
  * userCanExecute(), and if the data array contains 'Username', etc, then Username
  * resets are allowed.
  * @param $data array
  * @throws MWException
  * @throws ThrottledError|PermissionsError
  * @return Bool|Array
  */
 public function onSubmit(array $data)
 {
     global $wgAuth;
     if (isset($data['Domain'])) {
         if ($wgAuth->validDomain($data['Domain'])) {
             $wgAuth->setDomain($data['Domain']);
         } else {
             $wgAuth->setDomain('invaliddomain');
         }
     }
     if (isset($data['Capture']) && !$this->getUser()->isAllowed('passwordreset')) {
         // The user knows they don't have the passwordreset permission,
         // but they tried to spoof the form. That's naughty
         throw new PermissionsError('passwordreset');
     }
     /**
      * @var $firstUser User
      * @var $users User[]
      */
     if (isset($data['Username']) && $data['Username'] !== '') {
         $method = 'username';
         $users = array(User::newFromName($data['Username']));
     } elseif (isset($data['Email']) && $data['Email'] !== '' && Sanitizer::validateEmail($data['Email'])) {
         $method = 'email';
         $res = wfGetDB(DB_SLAVE)->select('user', User::selectFields(), array('user_email' => $data['Email']), __METHOD__);
         if ($res) {
             $users = array();
             foreach ($res as $row) {
                 $users[] = User::newFromRow($row);
             }
         } else {
             // Some sort of database error, probably unreachable
             throw new MWException('Unknown database error in ' . __METHOD__);
         }
     } else {
         // The user didn't supply any data
         return false;
     }
     // Check for hooks (captcha etc), and allow them to modify the users list
     $error = array();
     if (!wfRunHooks('SpecialPasswordResetOnSubmit', array(&$users, $data, &$error))) {
         return array($error);
     }
     if (count($users) == 0) {
         if ($method == 'email') {
             // Don't reveal whether or not an email address is in use
             return true;
         } else {
             return array('noname');
         }
     }
     $firstUser = $users[0];
     if (!$firstUser instanceof User || !$firstUser->getID()) {
         // Don't parse username as wikitext (bug 65501)
         return array(array('nosuchuser', wfEscapeWikiText($data['Username'])));
     }
     // Check against the rate limiter
     if ($this->getUser()->pingLimiter('mailpassword')) {
         throw new ThrottledError();
     }
     // Check against password throttle
     foreach ($users as $user) {
         if ($user->isPasswordReminderThrottled()) {
             global $wgPasswordReminderResendTime;
             # Round the time in hours to 3 d.p., in case someone is specifying
             # minutes or seconds.
             return array(array('throttled-mailpassword', round($wgPasswordReminderResendTime, 3)));
         }
     }
     global $wgNewPasswordExpiry;
     // All the users will have the same email address
     if ($firstUser->getEmail() == '') {
         // This won't be reachable from the email route, so safe to expose the username
         return array(array('noemail', wfEscapeWikiText($firstUser->getName())));
     }
     // We need to have a valid IP address for the hook, but per bug 18347, we should
     // send the user's name if they're logged in.
     $ip = $this->getRequest()->getIP();
     if (!$ip) {
         return array('badipaddress');
     }
     $caller = $this->getUser();
     wfRunHooks('User::mailPasswordInternal', array(&$caller, &$ip, &$firstUser));
     $username = $caller->getName();
     $msg = IP::isValid($username) ? 'passwordreset-emailtext-ip' : 'passwordreset-emailtext-user';
     // Send in the user's language; which should hopefully be the same
     $userLanguage = $firstUser->getOption('language');
     $passwords = array();
     foreach ($users as $user) {
         $password = $user->randomPassword();
         $user->setNewpassword($password);
         $user->saveSettings();
         $passwords[] = $this->msg('passwordreset-emailelement', $user->getName(), $password)->inLanguage($userLanguage)->text();
         // We'll escape the whole thing later
     }
     $passwordBlock = implode("\n\n", $passwords);
     $this->email = $this->msg($msg)->inLanguage($userLanguage);
     $this->email->params($username, $passwordBlock, count($passwords), '<' . Title::newMainPage()->getCanonicalURL() . '>', round($wgNewPasswordExpiry / 86400));
     $title = $this->msg('passwordreset-emailtitle');
     $this->result = $firstUser->sendMail($title->text(), $this->email->text());
     if (isset($data['Capture']) && $data['Capture']) {
         // Save the user, will be used if an error occurs when sending the email
         $this->firstUser = $firstUser;
     } else {
         // Blank the email if the user is not supposed to see it
         $this->email = null;
     }
     if ($this->result->isGood()) {
         return true;
     } elseif (isset($data['Capture']) && $data['Capture']) {
         // The email didn't send, but maybe they knew that and that's why they captured it
         return true;
     } else {
         // @todo FIXME: The email wasn't sent, but we have already set
         // the password throttle timestamp, so they won't be able to try
         // again until it expires...  :(
         return array(array('mailerror', $this->result->getMessage()));
     }
 }
Example #8
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     if (!is_null($params['prop'])) {
         $this->prop = array_flip($params['prop']);
     } else {
         $this->prop = array();
     }
     $users = (array) $params['users'];
     $goodNames = $done = array();
     $result = $this->getResult();
     // Canonicalize user names
     foreach ($users as $u) {
         $n = User::getCanonicalName($u);
         if ($n === false || $n === '') {
             $vals = array('name' => $u, 'invalid' => '');
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('users', implode('|', array_diff($users, $done)));
                 $goodNames = array();
                 break;
             }
             $done[] = $u;
         } else {
             $goodNames[] = $n;
         }
     }
     $result = $this->getResult();
     if (count($goodNames)) {
         $this->addTables('user');
         $this->addFields(User::selectFields());
         $this->addWhereFld('user_name', $goodNames);
         if (isset($this->prop['groups']) || isset($this->prop['rights'])) {
             $this->addTables('user_groups');
             $this->addJoinConds(array('user_groups' => array('LEFT JOIN', 'ug_user=user_id')));
             $this->addFields('ug_group');
         }
         $this->showHiddenUsersAddBlockInfo(isset($this->prop['blockinfo']));
         $data = array();
         $res = $this->select(__METHOD__);
         foreach ($res as $row) {
             $user = User::newFromRow($row);
             $name = $user->getName();
             $data[$name]['userid'] = $user->getId();
             $data[$name]['name'] = $name;
             if (isset($this->prop['editcount'])) {
                 $data[$name]['editcount'] = intval($user->getEditCount());
             }
             if (isset($this->prop['registration'])) {
                 $data[$name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $user->getRegistration());
             }
             if (isset($this->prop['groups'])) {
                 if (!isset($data[$name]['groups'])) {
                     $data[$name]['groups'] = $user->getAutomaticGroups();
                 }
                 if (!is_null($row->ug_group)) {
                     // This row contains only one group, others will be added from other rows
                     $data[$name]['groups'][] = $row->ug_group;
                 }
             }
             if (isset($this->prop['implicitgroups']) && !isset($data[$name]['implicitgroups'])) {
                 $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
             }
             if (isset($this->prop['rights'])) {
                 if (!isset($data[$name]['rights'])) {
                     $data[$name]['rights'] = User::getGroupPermissions($user->getAutomaticGroups());
                 }
                 if (!is_null($row->ug_group)) {
                     $data[$name]['rights'] = array_unique(array_merge($data[$name]['rights'], User::getGroupPermissions(array($row->ug_group))));
                 }
             }
             if ($row->ipb_deleted) {
                 $data[$name]['hidden'] = '';
             }
             if (isset($this->prop['blockinfo']) && !is_null($row->ipb_by_text)) {
                 $data[$name]['blockid'] = $row->ipb_id;
                 $data[$name]['blockedby'] = $row->ipb_by_text;
                 $data[$name]['blockedbyid'] = $row->ipb_by;
                 $data[$name]['blockreason'] = $row->ipb_reason;
                 $data[$name]['blockexpiry'] = $row->ipb_expiry;
             }
             if (isset($this->prop['emailable']) && $user->canReceiveEmail()) {
                 $data[$name]['emailable'] = '';
             }
             if (isset($this->prop['gender'])) {
                 $gender = $user->getOption('gender');
                 if (strval($gender) === '') {
                     $gender = 'unknown';
                 }
                 $data[$name]['gender'] = $gender;
             }
             if (!is_null($params['token'])) {
                 $tokenFunctions = $this->getTokenFunctions();
                 foreach ($params['token'] as $t) {
                     $val = call_user_func($tokenFunctions[$t], $user);
                     if ($val === false) {
                         $this->setWarning("Action '{$t}' is not allowed for the current user");
                     } else {
                         $data[$name][$t . 'token'] = $val;
                     }
                 }
             }
         }
     }
     // Second pass: add result data to $retval
     foreach ($goodNames as $u) {
         if (!isset($data[$u])) {
             $data[$u] = array('name' => $u);
             $urPage = new UserrightsPage();
             $iwUser = $urPage->fetchUser($u);
             if ($iwUser instanceof UserRightsProxy) {
                 $data[$u]['interwiki'] = '';
                 if (!is_null($params['token'])) {
                     $tokenFunctions = $this->getTokenFunctions();
                     foreach ($params['token'] as $t) {
                         $val = call_user_func($tokenFunctions[$t], $iwUser);
                         if ($val === false) {
                             $this->setWarning("Action '{$t}' is not allowed for the current user");
                         } else {
                             $data[$u][$t . 'token'] = $val;
                         }
                     }
                 }
             } else {
                 $data[$u]['missing'] = '';
             }
         } else {
             if (isset($this->prop['groups']) && isset($data[$u]['groups'])) {
                 $result->setIndexedTagName($data[$u]['groups'], 'g');
             }
             if (isset($this->prop['implicitgroups']) && isset($data[$u]['implicitgroups'])) {
                 $result->setIndexedTagName($data[$u]['implicitgroups'], 'g');
             }
             if (isset($this->prop['rights']) && isset($data[$u]['rights'])) {
                 $result->setIndexedTagName($data[$u]['rights'], 'r');
             }
         }
         $fit = $result->addValue(array('query', $this->getModuleName()), null, $data[$u]);
         if (!$fit) {
             $this->setContinueEnumParameter('users', implode('|', array_diff($users, $done)));
             break;
         }
         $done[] = $u;
     }
     return $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'user');
 }
Example #9
0
 /**
  * @param string $email
  * @return User[]
  * @throws MWException On unexpected database errors
  */
 protected function getUsersByEmail($email)
 {
     $res = wfGetDB(DB_REPLICA)->select('user', User::selectFields(), ['user_email' => $email], __METHOD__);
     if (!$res) {
         // Some sort of database error, probably unreachable
         throw new MWException('Unknown database error in ' . __METHOD__);
     }
     $users = [];
     foreach ($res as $row) {
         $users[] = User::newFromRow($row);
     }
     return $users;
 }