Ejemplo n.º 1
0
 /**
  * UserLogin: send a confirmation email a new account has been created
  */
 public function sendConfirmationEmail()
 {
     $this->response->setFormat('json');
     $this->response->setCacheValidity(\WikiaResponse::CACHE_DISABLED);
     $this->response->setVal('success', false);
     if ($this->getVal('secret') != $this->wg->TheSchwartzSecretToken) {
         $this->response->setVal('message', 'invalid secret');
         return;
     }
     if (!$this->wg->EmailAuthentication) {
         $this->response->setVal('message', 'email authentication is not required');
         return;
     }
     $username = $this->getVal('username');
     wfWaitForSlaves($this->wg->ExternalSharedDB);
     $user = \User::newFromName($username);
     if (!$user instanceof \User) {
         $this->response->setVal('message', 'unable to create a \\User object from name');
         return;
     }
     if (!$user->getId()) {
         $this->response->setVal('message', 'no such user');
         return;
     }
     if ($user->isEmailConfirmed()) {
         $this->response->setVal('message', 'already confirmed');
         return;
     }
     $userLoginHelper = new \UserLoginHelper();
     $memcKey = $userLoginHelper->getMemKeyConfirmationEmailsSent($user->getId());
     $emailsSent = intval($this->wg->Memc->get($memcKey));
     if ($user->isEmailConfirmationPending() && strtotime($user->mEmailTokenExpires) - strtotime('+6 days') > 0 && $emailsSent >= \UserLoginHelper::LIMIT_EMAILS_SENT) {
         $this->response->setVal('message', 'confirmation emails limit reached');
         return;
     }
     if (!\Sanitizer::validateEmail($user->getEmail())) {
         $this->response->setVal('message', 'invalid email');
         return;
     }
     $langCode = $this->getVal('langCode', 'en');
     $mailTemplate = $this->app->renderView('UserLogin', 'GeneralMail', ['language' => $langCode, 'type' => 'confirmation-email']);
     $lang = \Language::factory($langCode);
     $mailStatus = (new GlobalStateWrapper(['wgLang' => $lang]))->wrap(function () use($user, $mailTemplate, $langCode) {
         return $user->sendConfirmationMail(false, 'ConfirmationMail', 'usersignup-confirmation-email', true, $mailTemplate, $langCode);
     });
     if (!$mailStatus->isGood()) {
         $this->response->setVal('message', 'could not send an email message');
         return;
     }
     $this->response->setVal('success', true);
 }
Ejemplo n.º 2
0
 /**
  * Listens for any user data save events and purges the authentication cache
  *
  * @param \User $user User
  * @return bool true - hook handler
  */
 public static function onUserSave(\User $user)
 {
     self::purgeAuthenticationCache($user->getName());
     return true;
 }
Ejemplo n.º 3
0
 /**
  * Get the User object
  *
  * @return User
  */
 public function getUser()
 {
     // Wikia change - begin - @author: Michał Roszka
     global $wgEnableHeliosExt;
     if ($this->user === null && $wgEnableHeliosExt) {
         $this->user = \Wikia\Helios\User::newFromToken($this->getRequest());
     }
     // Wikia change - end
     // Wikia change - begin - @author: wladek
     global $wgUserForceAnon;
     if ($this->user === null && $wgUserForceAnon) {
         $this->user = new User();
     }
     if ($this->user === null) {
         // Wikia change - end
         $this->user = User::newFromSession($this->getRequest());
     }
     // Replace the user object according to the context, e.g. Piggyback.
     wfRunHooks('RequestContextOverrideUser', [&$this->user, $this->getRequest()]);
     return $this->user;
 }
Ejemplo n.º 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;
     $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;
 }