/**
  * Get the user object for the user who is doing the renaming
  * "Auto-create" if it doesn't exist yet.
  * @return User
  */
 protected function getRenameUser()
 {
     $user = User::newFromName($this->params['renamer']);
     // If the username is a reserved name, don't worry about the account
     // existing, just use it.
     if (!User::isUsableName($user->getName())) {
         return $user;
     }
     $caUser = CentralAuthUser::getInstance($user);
     // Race condition where the renamer isn't attached here, but
     // someone creates an account in the meantime and then bad
     // stuff could happen...
     // For the meantime, just use a system account
     if (!$caUser->attachedOn(wfWikiID()) && $user->getId() !== 0) {
         return User::newFromName('Global rename script');
     } elseif ($user->getId() == 0) {
         // No local user, lets "auto-create" one
         if (CentralAuthHooks::attemptAddUser($user)) {
             return User::newFromName($user->getName());
             // So the internal cache is reloaded
         } else {
             // Auto-creation didn't work, fallback on the system account.
             return User::newFromName('Global rename script');
         }
     } else {
         // Account is attached and exists, just use it :)
         return $user;
     }
 }
Example #2
0
 /**
  * Blocks the user specified in the parameters for the given expiry, with the
  * given reason, and with all other settings provided in the params. If the block
  * succeeds, produces a result containing the details of the block and notice
  * of success. If it fails, the result will specify the nature of the error.
  */
 public function execute()
 {
     global $wgContLang;
     $user = $this->getUser();
     $params = $this->extractRequestParams();
     if (!$user->isAllowed('block')) {
         $this->dieUsageMsg('cantblock');
     }
     # bug 15810: blocked admins should have limited access here
     if ($user->isBlocked()) {
         $status = SpecialBlock::checkUnblockSelf($params['user'], $user);
         if ($status !== true) {
             $msg = $this->parseMsg($status);
             $this->dieUsage($msg['info'], $msg['code'], 0, ['blockinfo' => ApiQueryUserInfo::getBlockInfo($user->getBlock())]);
         }
     }
     $target = User::newFromName($params['user']);
     // Bug 38633 - if the target is a user (not an IP address), but it
     // doesn't exist or is unusable, error.
     if ($target instanceof User && ($target->isAnon() || !User::isUsableName($target->getName()))) {
         $this->dieUsageMsg(['nosuchuser', $params['user']]);
     }
     if ($params['hidename'] && !$user->isAllowed('hideuser')) {
         $this->dieUsageMsg('canthide');
     }
     if ($params['noemail'] && !SpecialBlock::canBlockEmail($user)) {
         $this->dieUsageMsg('cantblock-email');
     }
     $data = ['PreviousTarget' => $params['user'], 'Target' => $params['user'], 'Reason' => [$params['reason'], 'other', $params['reason']], 'Expiry' => $params['expiry'], 'HardBlock' => !$params['anononly'], 'CreateAccount' => $params['nocreate'], 'AutoBlock' => $params['autoblock'], 'DisableEmail' => $params['noemail'], 'HideUser' => $params['hidename'], 'DisableUTEdit' => !$params['allowusertalk'], 'Reblock' => $params['reblock'], 'Watch' => $params['watchuser'], 'Confirm' => true];
     $retval = SpecialBlock::processForm($data, $this->getContext());
     if ($retval !== true) {
         // We don't care about multiple errors, just report one of them
         $this->dieUsageMsg($retval);
     }
     list($target, ) = SpecialBlock::getTargetAndType($params['user']);
     $res['user'] = $params['user'];
     $res['userID'] = $target instanceof User ? $target->getId() : 0;
     $block = Block::newFromTarget($target, null, true);
     if ($block instanceof Block) {
         $res['expiry'] = $wgContLang->formatExpiry($block->mExpiry, TS_ISO_8601, 'infinite');
         $res['id'] = $block->getId();
     } else {
         # should be unreachable
         $res['expiry'] = '';
         $res['id'] = '';
     }
     $res['reason'] = $params['reason'];
     $res['anononly'] = $params['anononly'];
     $res['nocreate'] = $params['nocreate'];
     $res['autoblock'] = $params['autoblock'];
     $res['noemail'] = $params['noemail'];
     $res['hidename'] = $params['hidename'];
     $res['allowusertalk'] = $params['allowusertalk'];
     $res['watchuser'] = $params['watchuser'];
     $this->getResult()->addValue(null, $this->getModuleName(), $res);
 }
 /**
  * Return a user object
  *
  * Doesn’t add to the database, to keep an instance
  * you have to call addToDatabase(); to your new user.
  *
  *
  * <code>
  * // Expected entered array format
  * $user_array = array(
  *                 'fullName'=>'John Doe',
  *                 'username'=>'jdoe',
  *                 'email'=>'*****@*****.**');
  *
  * // Check if the user can be created (i.e. has no entry in DB).
  *
  * // Then...
  * $user = self::prepareUser($GLOBALS['wgUser'], $user_array);
  *
  * // (poor man) persist —current author badly miss Doctrine2—
  * $user->addToDatabase();
  *
  * // Flag confirmation
  * $user->ConfirmEmail();
  *
  * // When making changes
  * $user->saveSettings();
  *
  * // Replace global scope object with our new one
  * // .. start session ...
  * $GLOBALS['wgUser'] = $user;        // Yep, like that :/
  * $GLOBALS['wgUser']->setCookies();  // ^
  * </code>
  *
  * @param User  &$user      MediaWiki User instance passed as reference
  * @param array $user_array Array of provided by our profile server data to use inside our local user
  *
  * @return void
  */
 public static function prepareUser($user_array)
 {
     $desired_keys = array('fullName', 'email', 'username');
     $input_keys = array_keys($user_array);
     $diff = array_diff($desired_keys, $input_keys);
     if (count($diff) >= 1) {
         throw new Exception(sprintf('Recieved data has required keys that are missing:  %s', implode(', ', $diff)));
     }
     $username = ucfirst($user_array['username']);
     if (!User::isUsableName($username)) {
         throw new Exception(sprintf('Username %s has invalid characters', $username));
     }
     /*
      * Based off of UserLoadFromSession Talk page documentation
      * http://www.mediawiki.org/wiki/Manual_talk:Hooks/UserLoadFromSession
      */
     $user = User::newFromName($username);
     $user->setRealName($user_array['fullName']);
     $user->setEmail($user_array['email']);
     return $user;
 }
Example #4
0
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  *
  * @public
  */
 function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     if ('' == $this->mName) {
         return self::NO_NAME;
     }
     $u = User::newFromName($this->mName);
     if (is_null($u) || !User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     if (0 == $u->getID()) {
         global $wgAuth;
         /**
          * If the external authentication plugin allows it,
          * automatically create a new account for users that
          * are externally defined but have not yet logged in.
          */
         if ($wgAuth->autoCreate() && $wgAuth->userExists($u->getName())) {
             if ($wgAuth->authenticate($u->getName(), $this->mPassword)) {
                 $u = $this->initUser($u);
             } else {
                 return self::WRONG_PLUGIN_PASS;
             }
         } else {
             return self::NOT_EXISTS;
         }
     } else {
         $u->load();
     }
     if (!$u->checkPassword($this->mPassword)) {
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // The e-mailed temporary password should not be used
             // for actual logins; that's a very sloppy habit,
             // and insecure if an attacker has a few seconds to
             // click "search" on someone's open mail reader.
             //
             // Allow it to be used only to reset the password
             // a single time to a new value, which won't be in
             // the user's e-mail archives.
             //
             // For backwards compatibility, we'll still recognize
             // it at the login form to minimize surprises for
             // people who have been logging in with a temporary
             // password for some time.
             //
             // As a side-effect, we can authenticate the user's
             // e-mail address if it's not already done, since
             // the temporary password was sent via e-mail.
             //
             if (!$u->isEmailConfirmed()) {
                 $u->confirmEmail();
             }
             // At this point we just return an appropriate code
             // indicating that the UI should show a password
             // reset form; bot interfaces etc will probably just
             // fail cleanly here.
             //
             return self::RESET_PASS;
         } else {
             return '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         return self::SUCCESS;
     }
 }
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  *
  * @public
  */
 function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     if ('' == $this->mName) {
         return self::NO_NAME;
     }
     global $wgPasswordAttemptThrottle;
     $throttleCount = 0;
     if (is_array($wgPasswordAttemptThrottle)) {
         $throttleKey = wfMemcKey('password-throttle', wfGetIP(), md5($this->mName));
         $count = $wgPasswordAttemptThrottle['count'];
         $period = $wgPasswordAttemptThrottle['seconds'];
         global $wgMemc;
         $throttleCount = $wgMemc->get($throttleKey);
         if (!$throttleCount) {
             $wgMemc->add($throttleKey, 1, $period);
             // start counter
         } else {
             if ($throttleCount < $count) {
                 $wgMemc->incr($throttleKey);
             } else {
                 if ($throttleCount >= $count) {
                     return self::THROTTLED;
                 }
             }
         }
     }
     // Load $wgUser now, and check to see if we're logging in as the same
     // name. This is necessary because loading $wgUser (say by calling
     // getName()) calls the UserLoadFromSession hook, which potentially
     // creates the user in the database. Until we load $wgUser, checking
     // for user existence using User::newFromName($name)->getId() below
     // will effectively be using stale data.
     if ($wgUser->getName() === $this->mName) {
         wfDebug(__METHOD__ . ": already logged in as {$this->mName}\n");
         return self::SUCCESS;
     }
     $u = User::newFromName($this->mName);
     if (is_null($u) || !User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     $isAutoCreated = false;
     if (0 == $u->getID()) {
         $status = $this->attemptAutoCreate($u);
         if ($status !== self::SUCCESS) {
             return $status;
         } else {
             $isAutoCreated = true;
         }
     } else {
         $u->load();
     }
     // Give general extensions, such as a captcha, a chance to abort logins
     $abort = self::ABORTED;
     if (!wfRunHooks('AbortLogin', array($u, $this->mPassword, &$abort))) {
         return $abort;
     }
     if (!$u->checkPassword($this->mPassword)) {
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // The e-mailed temporary password should not be used for actu-
             // al logins; that's a very sloppy habit, and insecure if an
             // attacker has a few seconds to click "search" on someone's o-
             // pen mail reader.
             //
             // Allow it to be used only to reset the password a single time
             // to a new value, which won't be in the user's e-mail ar-
             // chives.
             //
             // For backwards compatibility, we'll still recognize it at the
             // login form to minimize surprises for people who have been
             // logging in with a temporary password for some time.
             //
             // As a side-effect, we can authenticate the user's e-mail ad-
             // dress if it's not already done, since the temporary password
             // was sent via e-mail.
             if (!$u->isEmailConfirmed()) {
                 $u->confirmEmail();
                 $u->saveSettings();
             }
             // At this point we just return an appropriate code/ indicating
             // that the UI should show a password reset form; bot inter-
             // faces etc will probably just fail cleanly here.
             $retval = self::RESET_PASS;
         } else {
             $retval = '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         // Please reset throttle for successful logins, thanks!
         if ($throttleCount) {
             $wgMemc->delete($throttleKey);
         }
         if ($isAutoCreated) {
             // Must be run after $wgUser is set, for correct new user log
             wfRunHooks('AuthPluginAutoCreate', array($wgUser));
         }
         $retval = self::SUCCESS;
     }
     wfRunHooks('LoginAuthenticateAudit', array($u, $this->mPassword, $retval));
     return $retval;
 }
Example #6
0
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  *
  * @public
  */
 function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     if ('' == $this->mName) {
         return self::NO_NAME;
     }
     // XXCHANGED - by Reuben to allow login via Username or Email
     $u = null;
     // Check if $this->mName is actually an email address
     $looksLikeEmail = strpos($this->mName, '@') !== false;
     if ($looksLikeEmail) {
         list($u, $count) = WikihowUser::newFromEmailAddress($this->mName);
     }
     // Only do the username lookup if it didn't look like an email address
     // or the email addresses didn't have exactly 1 account attached
     if (is_null($u)) {
         $u = User::newFromName($this->mName);
         // Show error specific to email addresses if there's no username
         // with an '@' in it either
         if ($looksLikeEmail) {
             if ($count < 1) {
                 return self::NO_EMAIL;
             } elseif ($count > 1) {
                 return self::MULTIPLE_EMAILS;
             }
         }
         if (is_null($u) || !User::isUsableName($u->getName())) {
             return self::ILLEGAL;
         }
     }
     if (0 == $u->getID()) {
         global $wgAuth;
         /**
          * If the external authentication plugin allows it,
          * automatically create a new account for users that
          * are externally defined but have not yet logged in.
          */
         if ($wgAuth->autoCreate() && $wgAuth->userExists($u->getName())) {
             if ($wgAuth->authenticate($u->getName(), $this->mPassword)) {
                 $u = $this->initUser($u, true);
             } else {
                 return self::WRONG_PLUGIN_PASS;
             }
         } else {
             return self::NOT_EXISTS;
         }
     } else {
         $u->load();
     }
     // Give general extensions, such as a captcha, a chance to abort logins
     $abort = self::ABORTED;
     if (!wfRunHooks('AbortLogin', array($u, $this->mPassword, &$abort))) {
         return $abort;
     }
     if (!$u->checkPassword($this->mPassword)) {
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // The e-mailed temporary password should not be used
             // for actual logins; that's a very sloppy habit,
             // and insecure if an attacker has a few seconds to
             // click "search" on someone's open mail reader.
             //
             // Allow it to be used only to reset the password
             // a single time to a new value, which won't be in
             // the user's e-mail archives.
             //
             // For backwards compatibility, we'll still recognize
             // it at the login form to minimize surprises for
             // people who have been logging in with a temporary
             // password for some time.
             //
             // As a side-effect, we can authenticate the user's
             // e-mail address if it's not already done, since
             // the temporary password was sent via e-mail.
             //
             if (!$u->isEmailConfirmed()) {
                 $u->confirmEmail();
             }
             // At this point we just return an appropriate code
             // indicating that the UI should show a password
             // reset form; bot interfaces etc will probably just
             // fail cleanly here.
             //
             $retval = self::RESET_PASS;
         } else {
             $retval = '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         $retval = self::SUCCESS;
     }
     wfRunHooks('LoginAuthenticateAudit', array($u, $this->mPassword, $retval));
     return $retval;
 }
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  * @return int
  */
 public function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     $this->load();
     if ($this->mUsername == '') {
         return self::NO_NAME;
     }
     // We require a login token to prevent login CSRF
     // Handle part of this before incrementing the throttle so
     // token-less login attempts don't count towards the throttle
     // but wrong-token attempts do.
     // If the user doesn't have a login token yet, set one.
     if (!self::getLoginToken()) {
         self::setLoginToken();
         return self::NEED_TOKEN;
     }
     // If the user didn't pass a login token, tell them we need one
     if (!$this->mToken) {
         return self::NEED_TOKEN;
     }
     $throttleCount = self::incLoginThrottle($this->mUsername);
     if ($throttleCount === true) {
         return self::THROTTLED;
     }
     // Validate the login token
     if ($this->mToken !== self::getLoginToken()) {
         return self::WRONG_TOKEN;
     }
     // Load the current user now, and check to see if we're logging in as
     // the same name. This is necessary because loading the current user
     // (say by calling getName()) calls the UserLoadFromSession hook, which
     // potentially creates the user in the database. Until we load $wgUser,
     // checking for user existence using User::newFromName($name)->getId() below
     // will effectively be using stale data.
     if ($this->getUser()->getName() === $this->mUsername) {
         wfDebug(__METHOD__ . ": already logged in as {$this->mUsername}\n");
         return self::SUCCESS;
     }
     $u = User::newFromName($this->mUsername);
     if ($u === false) {
         return self::ILLEGAL;
     }
     $msg = null;
     // Give extensions a way to indicate the username has been updated,
     // rather than telling the user the account doesn't exist.
     if (!Hooks::run('LoginUserMigrated', array($u, &$msg))) {
         $this->mAbortLoginErrorMsg = $msg;
         return self::USER_MIGRATED;
     }
     if (!User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     $isAutoCreated = false;
     if ($u->getID() == 0) {
         $status = $this->attemptAutoCreate($u);
         if ($status !== self::SUCCESS) {
             return $status;
         } else {
             $isAutoCreated = true;
         }
     } else {
         $u->load();
     }
     // Give general extensions, such as a captcha, a chance to abort logins
     $abort = self::ABORTED;
     if (!Hooks::run('AbortLogin', array($u, $this->mPassword, &$abort, &$msg))) {
         $this->mAbortLoginErrorMsg = $msg;
         return $abort;
     }
     global $wgBlockDisablesLogin;
     if (!$u->checkPassword($this->mPassword)) {
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // The e-mailed temporary password should not be used for actu-
             // al logins; that's a very sloppy habit, and insecure if an
             // attacker has a few seconds to click "search" on someone's o-
             // pen mail reader.
             //
             // Allow it to be used only to reset the password a single time
             // to a new value, which won't be in the user's e-mail ar-
             // chives.
             //
             // For backwards compatibility, we'll still recognize it at the
             // login form to minimize surprises for people who have been
             // logging in with a temporary password for some time.
             //
             // As a side-effect, we can authenticate the user's e-mail ad-
             // dress if it's not already done, since the temporary password
             // was sent via e-mail.
             if (!$u->isEmailConfirmed() && !wfReadOnly()) {
                 $u->confirmEmail();
                 $u->saveSettings();
             }
             // At this point we just return an appropriate code/ indicating
             // that the UI should show a password reset form; bot inter-
             // faces etc will probably just fail cleanly here.
             $this->mAbortLoginErrorMsg = 'resetpass-temp-emailed';
             $this->mTempPasswordUsed = true;
             $retval = self::RESET_PASS;
         } else {
             $retval = $this->mPassword == '' ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } elseif ($wgBlockDisablesLogin && $u->isBlocked()) {
         // If we've enabled it, make it so that a blocked user cannot login
         $retval = self::USER_BLOCKED;
     } elseif ($u->getPasswordExpired() == 'hard') {
         // Force reset now, without logging in
         $retval = self::RESET_PASS;
         $this->mAbortLoginErrorMsg = 'resetpass-expired';
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         // This should set it for OutputPage and the Skin
         // which is needed or the personal links will be
         // wrong.
         $this->getContext()->setUser($u);
         // Please reset throttle for successful logins, thanks!
         if ($throttleCount) {
             self::clearLoginThrottle($this->mUsername);
         }
         if ($isAutoCreated) {
             // Must be run after $wgUser is set, for correct new user log
             Hooks::run('AuthPluginAutoCreate', array($u));
         }
         $retval = self::SUCCESS;
     }
     Hooks::run('LoginAuthenticateAudit', array($u, $this->mPassword, $retval));
     return $retval;
 }
 /**
  * @param string $wiki
  * @param DatabaseBase $dbw
  * @return stdClass[]
  */
 protected function findUsers($wiki, DatabaseBase $dbw)
 {
     $rowsToRename = array();
     $updates = new UsersToRenameDatabaseUpdates($dbw);
     $rows = $updates->findUsers($wiki, UsersToRenameDatabaseUpdates::NOTIFIED, $this->mBatchSize);
     foreach ($rows as $row) {
         $user = User::newFromName($row->utr_name);
         $caUser = new CentralAuthUser($row->utr_name);
         if (!$user->getId()) {
             $this->log("'{$row->utr_name}' has been renamed since the last was list generated.");
             $updates->remove($row->utr_name, $row->utr_wiki);
         } elseif ($caUser->attachedOn($row->utr_wiki)) {
             $this->log("'{$row->utr_name}' has become attached to a global account since the list as last generated.");
             $updates->remove($row->utr_name, $row->utr_wiki);
         } elseif (!User::isUsableName($row->utr_name)) {
             // Reserved for a system account, ignore
             $this->log("'{$row->utr_name}' is a reserved username, skipping.");
             $updates->remove($row->utr_name, $row->utr_wiki);
         } else {
             $rowsToRename[] = $row;
         }
     }
     return $rowsToRename;
 }
Example #9
0
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  */
 public function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     if ($this->mName == '') {
         return self::NO_NAME;
     }
     // We require a login token to prevent login CSRF
     // Handle part of this before incrementing the throttle so
     // token-less login attempts don't count towards the throttle
     // but wrong-token attempts do.
     // If the user doesn't have a login token yet, set one.
     if (!self::getLoginToken()) {
         self::setLoginToken();
         return self::NEED_TOKEN;
     }
     // If the user didn't pass a login token, tell them we need one
     if (!$this->mToken) {
         return self::NEED_TOKEN;
     }
     global $wgPasswordAttemptThrottle;
     $throttleCount = 0;
     if (is_array($wgPasswordAttemptThrottle)) {
         $throttleKey = wfMemcKey('password-throttle', wfGetIP(), md5($this->mName));
         $count = $wgPasswordAttemptThrottle['count'];
         $period = $wgPasswordAttemptThrottle['seconds'];
         global $wgMemc;
         $throttleCount = $wgMemc->get($throttleKey);
         if (!$throttleCount) {
             $wgMemc->add($throttleKey, 1, $period);
             // start counter
         } else {
             if ($throttleCount < $count) {
                 $wgMemc->incr($throttleKey);
             } else {
                 if ($throttleCount >= $count) {
                     return self::THROTTLED;
                 }
             }
         }
     }
     // Validate the login token
     if ($this->mToken !== self::getLoginToken()) {
         return self::WRONG_TOKEN;
     }
     // Load $wgUser now, and check to see if we're logging in as the same
     // name. This is necessary because loading $wgUser (say by calling
     // getName()) calls the UserLoadFromSession hook, which potentially
     // creates the user in the database. Until we load $wgUser, checking
     // for user existence using User::newFromName($name)->getId() below
     // will effectively be using stale data.
     if ($wgUser->getName() === $this->mName) {
         wfDebug(__METHOD__ . ": already logged in as {$this->mName}\n");
         return self::SUCCESS;
     }
     $this->mExtUser = ExternalUser::newFromName($this->mName);
     # TODO: Allow some magic here for invalid external names, e.g., let the
     # user choose a different wiki name.
     $u = User::newFromName($this->mName);
     if (!$u instanceof User || !User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     $isAutoCreated = false;
     if (0 == $u->getID()) {
         $status = $this->attemptAutoCreate($u);
         if ($status !== self::SUCCESS) {
             return $status;
         } else {
             $isAutoCreated = true;
         }
     } else {
         global $wgExternalAuthType, $wgAutocreatePolicy;
         if ($wgExternalAuthType && $wgAutocreatePolicy != 'never' && is_object($this->mExtUser) && $this->mExtUser->authenticate($this->mPassword)) {
             # The external user and local user have the same name and
             # password, so we assume they're the same.
             $this->mExtUser->linkToLocal($u->getID());
         }
         $u->load();
     }
     // Give general extensions, such as a captcha, a chance to abort logins
     $abort = self::ABORTED;
     if (!wfRunHooks('AbortLogin', array($u, $this->mPassword, &$abort))) {
         return $abort;
     }
     global $wgBlockDisablesLogin;
     if (!$u->checkPassword($this->mPassword)) {
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // The e-mailed temporary password should not be used for actu-
             // al logins; that's a very sloppy habit, and insecure if an
             // attacker has a few seconds to click "search" on someone's o-
             // pen mail reader.
             //
             // Allow it to be used only to reset the password a single time
             // to a new value, which won't be in the user's e-mail ar-
             // chives.
             //
             // For backwards compatibility, we'll still recognize it at the
             // login form to minimize surprises for people who have been
             // logging in with a temporary password for some time.
             //
             // As a side-effect, we can authenticate the user's e-mail ad-
             // dress if it's not already done, since the temporary password
             // was sent via e-mail.
             if (!$u->isEmailConfirmed()) {
                 $u->confirmEmail();
                 $u->saveSettings();
             }
             // At this point we just return an appropriate code/ indicating
             // that the UI should show a password reset form; bot inter-
             // faces etc will probably just fail cleanly here.
             $retval = self::RESET_PASS;
         } else {
             $retval = $this->mPassword == '' ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } elseif ($wgBlockDisablesLogin && $u->isBlocked()) {
         // If we've enabled it, make it so that a blocked user cannot login
         $retval = self::USER_BLOCKED;
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         // Please reset throttle for successful logins, thanks!
         if ($throttleCount) {
             $wgMemc->delete($throttleKey);
         }
         if ($isAutoCreated) {
             // Must be run after $wgUser is set, for correct new user log
             wfRunHooks('AuthPluginAutoCreate', array($wgUser));
         }
         $retval = self::SUCCESS;
     }
     wfRunHooks('LoginAuthenticateAudit', array($u, $this->mPassword, $retval));
     return $retval;
 }
Example #10
0
 /**
  * Given unvalidated user input, return a canonical username, or false if
  * the username is invalid.
  * @param string $name User input
  * @param string|bool $validate Type of validation to use:
  *   - false        No validation
  *   - 'valid'      Valid for batch processes
  *   - 'usable'     Valid for batch processes and login
  *   - 'creatable'  Valid for batch processes, login and account creation
  *
  * @throws InvalidArgumentException
  * @return bool|string
  */
 public static function getCanonicalName($name, $validate = 'valid')
 {
     // Force usernames to capital
     global $wgContLang;
     $name = $wgContLang->ucfirst($name);
     # Reject names containing '#'; these will be cleaned up
     # with title normalisation, but then it's too late to
     # check elsewhere
     if (strpos($name, '#') !== false) {
         return false;
     }
     // Clean up name according to title rules,
     // but only when validation is requested (bug 12654)
     $t = $validate !== false ? Title::newFromText($name, NS_USER) : Title::makeTitle(NS_USER, $name);
     // Check for invalid titles
     if (is_null($t) || $t->getNamespace() !== NS_USER || $t->isExternal()) {
         return false;
     }
     // Reject various classes of invalid names
     $name = AuthManager::callLegacyAuthPlugin('getCanonicalName', [$t->getText()], $t->getText());
     switch ($validate) {
         case false:
             break;
         case 'valid':
             if (!User::isValidUserName($name)) {
                 $name = false;
             }
             break;
         case 'usable':
             if (!User::isUsableName($name)) {
                 $name = false;
             }
             break;
         case 'creatable':
             if (!User::isCreatableName($name)) {
                 $name = false;
             }
             break;
         default:
             throw new InvalidArgumentException('Invalid parameter value for $validate in ' . __METHOD__);
     }
     return $name;
 }
Example #11
0
// Validate the ticket (checks you have correct permissions on the wiki space and that the ticket is valid)
if (MediaWikiSpace::validate($alfRepository, $alfWikiSpaceNodeRef, "", $alfTicket) == false) {
    // Redirect to the login page, since the ticket is knacked or you don't have permissions
    header("Location: " . $loginURL);
    exit;
}
// Set the configuration values
eval(MediaWikiSpace::getEvaluationString($alfRepository, $alfWikiSpaceNodeRef));
// Make sure the setup is not included later
define(MW_NO_SETUP, true);
require_once "Setup.php";
// Check to see if we should be doing an 'auto' login
if ($doLogin == true) {
    // Authenticate the mediawiki user
    $u = User::newFromName($passedUser);
    if (is_null($u) == false && User::isUsableName($u->getName()) == true) {
        // Check to see if the user already exists
        if (0 == $u->getID()) {
            if ($wgAuth->autoCreate() == true && $wgAuth->userExists($u->getName()) == true) {
                if ($wgAuth->authenticate($u->getName(), $passedTicket) == true) {
                    // Initialise the user
                    $u->addToDatabase();
                    $wgAuth->initUser($u);
                    $u->saveSettings();
                } else {
                    // Can't authenticate the user based on the credentials provided
                    $u = null;
                }
            } else {
                // Unable to auto create the user in media wiki
                $u = null;
Example #12
0
	/**
	 * Blocks the user specified in the parameters for the given expiry, with the
	 * given reason, and with all other settings provided in the params. If the block
	 * succeeds, produces a result containing the details of the block and notice
	 * of success. If it fails, the result will specify the nature of the error.
	 */
	public function execute() {
		$user = $this->getUser();
		$params = $this->extractRequestParams();

		if ( !$user->isAllowed( 'block' ) ) {
			$this->dieUsageMsg( 'cantblock' );
		}

		# bug 15810: blocked admins should have limited access here
		if ( $user->isBlocked() ) {
			$status = SpecialBlock::checkUnblockSelf( $params['user'], $user );
			if ( $status !== true ) {
				$this->dieUsageMsg( array( $status ) );
			}
		}

		$target = User::newFromName( $params['user'] );
		// Bug 38633 - if the target is a user (not an IP address), but it doesn't exist or is unusable, error.
		if ( $target instanceof User && ( $target->isAnon() /* doesn't exist */ || !User::isUsableName( $target->getName() ) ) ) {
			$this->dieUsageMsg( array( 'nosuchuser', $params['user'] ) );
		}

		if ( $params['hidename'] && !$user->isAllowed( 'hideuser' ) ) {
			$this->dieUsageMsg( 'canthide' );
		}
		if ( $params['noemail'] && !SpecialBlock::canBlockEmail( $user ) ) {
			$this->dieUsageMsg( 'cantblock-email' );
		}

		$data = array(
			'PreviousTarget' => $params['user'],
			'Target' => $params['user'],
			'Reason' => array(
				$params['reason'],
				'other',
				$params['reason']
			),
			'Expiry' => $params['expiry'] == 'never' ? 'infinite' : $params['expiry'],
			'HardBlock' => !$params['anononly'],
			'CreateAccount' => $params['nocreate'],
			'AutoBlock' => $params['autoblock'],
			'DisableEmail' => $params['noemail'],
			'HideUser' => $params['hidename'],
			'DisableUTEdit' => !$params['allowusertalk'],
			'Reblock' => $params['reblock'],
			'Watch' => $params['watchuser'],
			'Confirm' => true,
		);

		$retval = SpecialBlock::processForm( $data, $this->getContext() );
		if ( $retval !== true ) {
			// We don't care about multiple errors, just report one of them
			$this->dieUsageMsg( $retval );
		}

		list( $target, /*...*/ ) = SpecialBlock::getTargetAndType( $params['user'] );
		$res['user'] = $params['user'];
		$res['userID'] = $target instanceof User ? $target->getId() : 0;

		$block = Block::newFromTarget( $target );
		if ( $block instanceof Block ) {
			$res['expiry'] = $block->mExpiry == $this->getDB()->getInfinity()
				? 'infinite'
				: wfTimestamp( TS_ISO_8601, $block->mExpiry );
			$res['id'] = $block->getId();
		} else {
			# should be unreachable
			$res['expiry'] = '';
			$res['id'] = '';
		}

		$res['reason'] = $params['reason'];
		if ( $params['anononly'] ) {
			$res['anononly'] = '';
		}
		if ( $params['nocreate'] ) {
			$res['nocreate'] = '';
		}
		if ( $params['autoblock'] ) {
			$res['autoblock'] = '';
		}
		if ( $params['noemail'] ) {
			$res['noemail'] = '';
		}
		if ( $params['hidename'] ) {
			$res['hidename'] = '';
		}
		if ( $params['allowusertalk'] ) {
			$res['allowusertalk'] = '';
		}
		if ( $params['watchuser'] ) {
			$res['watchuser'] = '';
		}

		$this->getResult()->addValue( null, $this->getModuleName(), $res );
	}
Example #13
0
 /**
  * Internally authenticate the login request.
  *
  * This may create a local account as a side effect if the
  * authentication plugin allows transparent local account
  * creation.
  */
 public function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     $this->load();
     /* Wikia change - begin */
     // This might not be needed once we're upgraded to MW 1.19 since that throws new ReadOnlyError in a few spots (test that).
     global $wgOut;
     if (wfReadOnly()) {
         if (is_object($wgOut)) {
             $wgOut->readOnlyPage();
             return false;
         } else {
             $this->mAbortLoginErrorMsg = wfMsg('login-abort-readonly');
             // msg is in languages/messages/wikia/MessagesEn.php if we end up deleting this after the upgrade to MW 1.19
             return self::ABORTED;
         }
     }
     /* Wikia change - end */
     if ($this->mUsername == '') {
         return self::NO_NAME;
     }
     // We require a login token to prevent login CSRF
     // Handle part of this before incrementing the throttle so
     // token-less login attempts don't count towards the throttle
     // but wrong-token attempts do.
     // If the user doesn't have a login token yet, set one.
     if (!self::getLoginToken()) {
         self::setLoginToken();
         return self::NEED_TOKEN;
     }
     // If the user didn't pass a login token, tell them we need one
     if (!$this->mToken) {
         return self::NEED_TOKEN;
     }
     $throttleCount = self::incLoginThrottle($this->mUsername);
     if ($throttleCount === true) {
         return self::THROTTLED;
     }
     // Validate the login token
     if ($this->mToken !== self::getLoginToken()) {
         return self::WRONG_TOKEN;
     }
     // Load the current user now, and check to see if we're logging in as
     // the same name. This is necessary because loading the current user
     // (say by calling getName()) calls the UserLoadFromSession hook, which
     // potentially creates the user in the database. Until we load $wgUser,
     // checking for user existence using User::newFromName($name)->getId() below
     // will effectively be using stale data.
     if ($this->getUser()->getName() === $this->mUsername) {
         wfDebug(__METHOD__ . ": already logged in as {$this->mUsername}\n");
         return self::SUCCESS;
     }
     $this->mExtUser = ExternalUser_Wikia::newFromName($this->mUsername);
     global $wgEnableHeliosExt;
     if ($wgEnableHeliosExt) {
         \Wikia\Helios\User::debugLogin($this->mPassword, __METHOD__);
     }
     global $wgExternalAuthType;
     if ($wgExternalAuthType && is_object($this->mExtUser) && $this->mExtUser->authenticate($this->mPassword)) {
         # The external user and local user have the same name and
         # password, so we assume they're the same.
         $this->mExtUser->linkToLocal($this->mExtUser->getId());
     }
     // Wikia change - begin - author: @wladek
     if ($wgExternalAuthType && is_object($this->mExtUser) && $this->mExtUser->getLastAuthenticationError()) {
         $this->mAbortLoginErrorMsg = $this->mExtUser->getLastAuthenticationError();
         return self::ABORTED;
     }
     // Wikia change - end
     # TODO: Allow some magic here for invalid external names, e.g., let the
     # user choose a different wiki name.
     $u = User::newFromName($this->mUsername);
     if (!$u instanceof User || !User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     $isAutoCreated = false;
     if (0 == $u->getID()) {
         $status = $this->attemptAutoCreate($u);
         if ($status !== self::SUCCESS) {
             return $status;
         } else {
             $isAutoCreated = true;
         }
     }
     // Give general extensions, such as a captcha, a chance to abort logins
     $abort = self::ABORTED;
     if (!wfRunHooks('AbortLogin', array($u, $this->mPassword, &$abort, &$this->mAbortLoginErrorMsg))) {
         return $abort;
     }
     global $wgBlockDisablesLogin;
     $abortedMessageKey = null;
     if (!$u->checkPassword($this->mPassword, $abortedMessageKey)) {
         if ($abortedMessageKey) {
             $this->mAbortLoginErrorMsg = $abortedMessageKey;
             return self::ABORTED;
         }
         if ($u->checkTemporaryPassword($this->mPassword)) {
             // At this point we just return an appropriate code/ indicating
             // that the UI should show a password reset form; bot inter-
             // faces etc will probably just fail cleanly here.
             $retval = self::RESET_PASS;
         } else {
             $retval = $this->mPassword == '' ? self::EMPTY_PASS : self::WRONG_PASS;
         }
     } elseif ($wgBlockDisablesLogin && $u->isBlocked()) {
         // If we've enabled it, make it so that a blocked user cannot login
         $retval = self::USER_BLOCKED;
     } else {
         $retval = self::SUCCESS;
     }
     if (in_array($retval, [self::SUCCESS, self::RESET_PASS])) {
         wfRunHooks('LoginSuccessModifyRetval', [$u->getName(), $this->mPassword, &$retval]);
     }
     switch ($retval) {
         case self::SUCCESS:
             $this->onAuthenticateUserDataSuccess($u, $isAutoCreated, $throttleCount);
             break;
         case self::RESET_PASS:
             $this->onAuthenticateUserDataResetPass($u);
             break;
     }
     wfRunHooks('LoginAuthenticateAudit', array($u, $this->mPassword, $retval));
     return $retval;
 }
function efNetworkAuth_Authenticate()
{
    global $wgUser;
    if (!$wgUser->isLoggedIn()) {
        //echo 'Logged out: ' . $wgUser->getName();
        $u = null;
        $networkAuthUser = efNetworkAuth_checkForNetworkAuthUser();
        if ($networkAuthUser != '') {
            global $wgNetworkAuthUser;
            $wgNetworkAuthUser = $networkAuthUser;
            $u = User::newFromName($wgNetworkAuthUser);
        }
        if (!is_null($u) && User::isUsableName($u->getName()) && !$u->isAnon()) {
            # Finally.
            $u->load();
            $wgUser = $u;
            # Since we're not really logged in, just pretending - force a logout
            # before the page gets displayed.
            global $wgHooks;
            $wgHooks['BeforePageDisplay'][] = 'efNetworkAuth_ForceLogout';
            # Add a display message to the personal URLs
            $wgHooks['PersonalUrls'][] = 'efNetworkAuth_PersonalUrls';
        }
    }
    return true;
}
Example #15
0
 /**
  * Given unvalidated user input, return a canonical username, or false if
  * the username is invalid.
  * @param $name String User input
  * @param $validate String|Bool type of validation to use:
  *                - false        No validation
  *                - 'valid'      Valid for batch processes
  *                - 'usable'     Valid for batch processes and login
  *                - 'creatable'  Valid for batch processes, login and account creation
  *
  * @return bool|string
  */
 public static function getCanonicalName($name, $validate = 'valid')
 {
     # Force usernames to capital
     global $wgContLang;
     $name = $wgContLang->ucfirst($name);
     # Reject names containing '#'; these will be cleaned up
     # with title normalisation, but then it's too late to
     # check elsewhere
     if (strpos($name, '#') !== false) {
         return false;
     }
     # Clean up name according to title rules
     $t = $validate === 'valid' ? Title::newFromText($name) : Title::makeTitle(NS_USER, $name);
     # Check for invalid titles
     if (is_null($t)) {
         return false;
     }
     # Reject various classes of invalid names
     global $wgAuth;
     $name = $wgAuth->getCanonicalName($t->getText());
     switch ($validate) {
         case false:
             break;
         case 'valid':
             if (!User::isValidUserName($name)) {
                 $name = false;
             }
             break;
         case 'usable':
             if (!User::isUsableName($name)) {
                 $name = false;
             }
             break;
         case 'creatable':
             if (!User::isCreatableName($name)) {
                 $name = false;
             }
             break;
         default:
             throw new MWException('Invalid parameter value for $validate in ' . __METHOD__);
     }
     return $name;
 }
Example #16
0
 /**
  * Given unvalidated user input, return a canonical username, or false if 
  * the username is invalid.
  * @param string $name
  * @param mixed $validate Type of validation to use:
  *                         false        No validation
  *                         'valid'      Valid for batch processes
  *                         'usable'     Valid for batch processes and login
  *                         'creatable'  Valid for batch processes, login and account creation
  */
 static function getCanonicalName($name, $validate = 'valid')
 {
     # Force usernames to capital
     global $wgContLang;
     $name = $wgContLang->ucfirst($name);
     # Clean up name according to title rules
     $t = Title::newFromText($name);
     if (is_null($t)) {
         return false;
     }
     # Reject various classes of invalid names
     $name = $t->getText();
     global $wgAuth;
     $name = $wgAuth->getCanonicalName($t->getText());
     switch ($validate) {
         case false:
             break;
         case 'valid':
             if (!User::isValidUserName($name)) {
                 $name = false;
             }
             break;
         case 'usable':
             if (!User::isUsableName($name)) {
                 $name = false;
             }
             break;
         case 'creatable':
             if (!User::isCreatableName($name)) {
                 $name = false;
             }
             break;
         default:
             throw new MWException('Invalid parameter value for $validate in ' . __METHOD__);
     }
     return $name;
 }
 /**
  * Hooked function, if a SAML assertion exist,
  * log in the corresponding MediaWiki user or logout from SAML.
  *
  * @link http://www.mediawiki.org/wiki/Manual:Hooks/UserLoadFromSession
  *
  * @param $user User MediaWiki User object
  * @param $result boolean a user is logged in
  *
  * @return boolean|string true on success, false on silent error, string on verbose error
  */
 public static function hookLoadSession($user, &$result)
 {
     if (!self::init()) {
         return true;
     }
     global $wgSamlRequirement;
     global $wgSamlUsernameAttr;
     global $wgBlockDisablesLogin;
     global $wgContLang;
     if ($result) {
         // Another hook already logged in
         self::disarm();
         return true;
     }
     if ($wgSamlRequirement >= SAML_REQUIRED) {
         self::$as->requireAuth();
     }
     if (self::$as->isAuthenticated()) {
         $attr = self::$as->getAttributes();
         if (!User::isUsableName($wgContLang->ucfirst(reset($attr[$wgSamlUsernameAttr])))) {
             return 'Illegal username: ' . reset($attr[$wgSamlUsernameAttr]);
         }
         self::loadUser($user, $attr);
         if ($wgBlockDisablesLogin && $user->isBlocked()) {
             $block = $this->getUser()->getBlock();
             throw new UserBlockedError($block);
         } else {
             $result = true;
             return true;
         }
     }
     return true;
 }
Example #18
0
 /**
  * @private
  */
 function authenticateUserData()
 {
     global $wgUser, $wgAuth;
     if ('' == $this->mName) {
         return self::NO_NAME;
     }
     $u = User::newFromName($this->mName);
     if (is_null($u) || !User::isUsableName($u->getName())) {
         return self::ILLEGAL;
     }
     if (0 == $u->getID()) {
         global $wgAuth;
         /**
          * If the external authentication plugin allows it,
          * automatically create a new account for users that
          * are externally defined but have not yet logged in.
          */
         if ($wgAuth->autoCreate() && $wgAuth->userExists($u->getName())) {
             if ($wgAuth->authenticate($u->getName(), $this->mPassword)) {
                 $u =& $this->initUser($u);
             } else {
                 return self::WRONG_PLUGIN_PASS;
             }
         } else {
             return self::NOT_EXISTS;
         }
     } else {
         $u->loadFromDatabase();
     }
     if (!$u->checkPassword($this->mPassword)) {
         return '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS;
     } else {
         $wgAuth->updateUser($u);
         $wgUser = $u;
         return self::SUCCESS;
     }
 }