public function handleRequest(AphrontRequest $request)
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($request->isFormPost()) {
         $log = PhabricatorUserLog::initializeNewLog($user, $user->getPHID(), PhabricatorUserLog::ACTION_LOGOUT);
         $log->save();
         // Destroy the user's session in the database so logout works even if
         // their cookies have some issues. We'll detect cookie issues when they
         // try to login again and tell them to clear any junk.
         $phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
         if (strlen($phsid)) {
             $session = id(new PhabricatorAuthSessionQuery())->setViewer($user)->withSessionKeys(array($phsid))->executeOne();
             if ($session) {
                 $session->delete();
             }
         }
         $request->clearCookie(PhabricatorCookies::COOKIE_SESSION);
         return id(new AphrontRedirectResponse())->setURI('/auth/loggedout/');
     }
     if ($user->getPHID()) {
         $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Log out of Phabricator?'))->appendChild(pht('Are you sure you want to log out?'))->addSubmitButton(pht('Logout'))->addCancelButton('/');
         return id(new AphrontDialogResponse())->setDialog($dialog);
     }
     return id(new AphrontRedirectResponse())->setURI('/');
 }
 private function logFailure(ConduitAPIRequest $request, PhabricatorConduitCertificateToken $info = null)
 {
     $log = PhabricatorUserLog::initializeNewLog($request->getUser(), $info ? $info->getUserPHID() : '-', PhabricatorUserLog::ACTION_CONDUIT_CERTIFICATE_FAILURE)->save();
 }
 private function processDelete(AphrontRequest $request)
 {
     $viewer = $request->getUser();
     $user = $this->getUser();
     $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($viewer, $request, $this->getPanelURI());
     $factor = id(new PhabricatorAuthFactorConfig())->loadOneWhere('id = %d AND userPHID = %s', $request->getInt('delete'), $user->getPHID());
     if (!$factor) {
         return new Aphront404Response();
     }
     if ($request->isFormPost()) {
         $factor->delete();
         $log = PhabricatorUserLog::initializeNewLog($viewer, $user->getPHID(), PhabricatorUserLog::ACTION_MULTI_REMOVE);
         $log->save();
         $user->updateMultiFactorEnrollment();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI());
     }
     $dialog = id(new AphrontDialogView())->setUser($viewer)->addHiddenInput('delete', $factor->getID())->setTitle(pht('Delete Authentication Factor'))->appendParagraph(pht('Really remove the authentication factor %s from your account?', phutil_tag('strong', array(), $factor->getFactorName())))->addSubmitButton(pht('Remove Factor'))->addCancelButton($this->getPanelURI());
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 /**
  * Upgrade a session to have all legalpad documents signed.
  *
  * @param PhabricatorUser User whose session should upgrade.
  * @param array LegalpadDocument objects
  * @return void
  * @task partial
  */
 public function signLegalpadDocuments(PhabricatorUser $viewer, array $docs)
 {
     if (!$viewer->hasSession()) {
         throw new Exception(pht('Signing session legalpad documents of user with no session!'));
     }
     $session = $viewer->getSession();
     if ($session->getSignedLegalpadDocuments()) {
         throw new Exception(pht('Session has already signed required legalpad documents!'));
     }
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $session->setSignedLegalpadDocuments(1);
     queryfx($session->establishConnection('w'), 'UPDATE %T SET signedLegalpadDocuments = %d WHERE id = %d', $session->getTableName(), 1, $session->getID());
     if (!empty($docs)) {
         $log = PhabricatorUserLog::initializeNewLog($viewer, $viewer->getPHID(), PhabricatorUserLog::ACTION_LOGIN_LEGALPAD);
         $log->save();
     }
     unset($unguarded);
 }
 public function processLoginRequest(PhabricatorAuthLoginController $controller)
 {
     $request = $controller->getRequest();
     $viewer = $request->getUser();
     $require_captcha = false;
     $captcha_valid = false;
     if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) {
         $failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP(PhabricatorUserLog::ACTION_LOGIN_FAILURE, 60 * 15);
         if (count($failed_attempts) > 5) {
             $require_captcha = true;
             $captcha_valid = AphrontFormRecaptchaControl::processCaptcha($request);
         }
     }
     $response = null;
     $account = null;
     $log_user = null;
     if ($request->isFormPost()) {
         if (!$require_captcha || $captcha_valid) {
             $username_or_email = $request->getStr('username');
             if (strlen($username_or_email)) {
                 $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username_or_email);
                 if (!$user) {
                     $user = PhabricatorUser::loadOneWithEmailAddress($username_or_email);
                 }
                 if ($user) {
                     $envelope = new PhutilOpaqueEnvelope($request->getStr('password'));
                     if ($user->comparePassword($envelope)) {
                         $account = $this->loadOrCreateAccount($user->getPHID());
                         $log_user = $user;
                         // If the user's password is stored using a less-than-optimal
                         // hash, upgrade them to the strongest available hash.
                         $hash_envelope = new PhutilOpaqueEnvelope($user->getPasswordHash());
                         if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
                             $user->setPassword($envelope);
                             $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
                             $user->save();
                             unset($unguarded);
                         }
                     }
                 }
             }
         }
     }
     if (!$account) {
         if ($request->isFormPost()) {
             $log = PhabricatorUserLog::initializeNewLog(null, $log_user ? $log_user->getPHID() : null, PhabricatorUserLog::ACTION_LOGIN_FAILURE);
             $log->save();
         }
         $request->clearCookie(PhabricatorCookies::COOKIE_USERNAME);
         $response = $controller->buildProviderPageResponse($this, $this->renderPasswordLoginForm($request, $require_captcha, $captcha_valid));
     }
     return array($account, $response);
 }
 /**
  * Upgrade a partial session to a full session.
  *
  * @param PhabricatorAuthSession Session to upgrade.
  * @return void
  * @task partial
  */
 public function upgradePartialSession(PhabricatorUser $viewer)
 {
     if (!$viewer->hasSession()) {
         throw new Exception(pht('Upgrading partial session of user with no session!'));
     }
     $session = $viewer->getSession();
     if (!$session->getIsPartial()) {
         throw new Exception(pht('Session is not partial!'));
     }
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $session->setIsPartial(0);
     queryfx($session->establishConnection('w'), 'UPDATE %T SET isPartial = %d WHERE id = %d', $session->getTableName(), 0, $session->getID());
     $log = PhabricatorUserLog::initializeNewLog($viewer, $viewer->getPHID(), PhabricatorUserLog::ACTION_LOGIN_FULL);
     $log->save();
     unset($unguarded);
 }
 /**
  * Verify a user's email address.
  *
  * This verifies an individual email address. If the address is the user's
  * primary address and their account was not previously verified, their
  * account is marked as email verified.
  *
  * @task email
  */
 public function verifyEmail(PhabricatorUser $user, PhabricatorUserEmail $email)
 {
     $actor = $this->requireActor();
     if (!$user->getID()) {
         throw new Exception('User has not been created yet!');
     }
     if (!$email->getID()) {
         throw new Exception('Email has not been created yet!');
     }
     $user->openTransaction();
     $user->beginWriteLocking();
     $user->reload();
     $email->reload();
     if ($email->getUserPHID() != $user->getPHID()) {
         throw new Exception(pht('User does not own email!'));
     }
     if (!$email->getIsVerified()) {
         $email->setIsVerified(1);
         $email->save();
         $log = PhabricatorUserLog::initializeNewLog($actor, $user->getPHID(), PhabricatorUserLog::ACTION_EMAIL_VERIFY);
         $log->setNewValue($email->getAddress());
         $log->save();
     }
     if (!$user->getIsEmailVerified()) {
         // If the user just verified their primary email address, mark their
         // account as email verified.
         $user_primary = $user->loadPrimaryEmail();
         if ($user_primary->getID() == $email->getID()) {
             $user->setIsEmailVerified(1);
             $user->save();
         }
     }
     $user->endWriteLocking();
     $user->saveTransaction();
 }
 /**
  * Reassign an unverified email address.
  */
 public function reassignEmail(PhabricatorUser $user, PhabricatorUserEmail $email)
 {
     $actor = $this->requireActor();
     if (!$user->getID()) {
         throw new Exception(pht('User has not been created yet!'));
     }
     if (!$email->getID()) {
         throw new Exception(pht('Email has not been created yet!'));
     }
     $user->openTransaction();
     $user->beginWriteLocking();
     $user->reload();
     $email->reload();
     $old_user = $email->getUserPHID();
     if ($old_user != $user->getPHID()) {
         if ($email->getIsVerified()) {
             throw new Exception(pht('Verified email addresses can not be reassigned.'));
         }
         if ($email->getIsPrimary()) {
             throw new Exception(pht('Primary email addresses can not be reassigned.'));
         }
         $email->setUserPHID($user->getPHID());
         $email->save();
         $log = PhabricatorUserLog::initializeNewLog($actor, $user->getPHID(), PhabricatorUserLog::ACTION_EMAIL_REASSIGN);
         $log->setNewValue($email->getAddress());
         $log->save();
     }
     $user->endWriteLocking();
     $user->saveTransaction();
 }