public function execute(PhutilArgumentParser $args) { $can_recover = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withIsAdmin(true)->execute(); if (!$can_recover) { throw new PhutilArgumentUsageException(pht('This Phabricator installation has no recoverable administrator ' . 'accounts. You can use `bin/accountadmin` to create a new ' . 'administrator account or make an existing user an administrator.')); } $can_recover = mpull($can_recover, 'getUsername'); sort($can_recover); $can_recover = implode(', ', $can_recover); $usernames = $args->getArg('username'); if (!$usernames) { throw new PhutilArgumentUsageException(pht('You must specify the username of the account to recover.')); } else { if (count($usernames) > 1) { throw new PhutilArgumentUsageException(pht('You can only recover the username for one account.')); } } $username = head($usernames); $user = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withUsernames(array($username))->executeOne(); if (!$user) { throw new PhutilArgumentUsageException(pht('No such user "%s". Recoverable administrator accounts are: %s.', $username, $can_recover)); } if (!$user->getIsAdmin()) { throw new PhutilArgumentUsageException(pht('You can only recover administrator accounts, but %s is not an ' . 'administrator. Recoverable administrator accounts are: %s.', $username, $can_recover)); } $engine = new PhabricatorAuthSessionEngine(); $onetime_uri = $engine->getOneTimeLoginURI($user, null, PhabricatorAuthSessionEngine::ONETIME_RECOVER); $console = PhutilConsole::getConsole(); $console->writeOut(pht('Use this link to recover access to the "%s" account from the web ' . 'interface:', $username)); $console->writeOut("\n\n"); $console->writeOut(' %s', $onetime_uri); $console->writeOut("\n\n"); $console->writeOut(pht('After logging in, you can use the "Auth" application to add or ' . 'restore authentication providers and allow normal logins to ' . 'succeed.') . "\n"); return 0; }
public function sendUsernameChangeEmail(PhabricatorUser $admin, $old_username) { $admin_username = $admin->getUserName(); $admin_realname = $admin->getRealName(); $new_username = $this->getUserName(); $password_instructions = null; if (PhabricatorPasswordAuthProvider::getPasswordProvider()) { $engine = new PhabricatorAuthSessionEngine(); $uri = $engine->getOneTimeLoginURI($this, null, PhabricatorAuthSessionEngine::ONETIME_USERNAME); $password_instructions = <<<EOTXT If you use a password to login, you'll need to reset it before you can login again. You can reset your password by following this link: {$uri} And, of course, you'll need to use your new username to login from now on. If you use OAuth to login, nothing should change. EOTXT; } $body = <<<EOBODY {$admin_username} ({$admin_realname}) has changed your Phabricator username. Old Username: {$old_username} New Username: {$new_username} {$password_instructions} EOBODY; $mail = id(new PhabricatorMetaMTAMail())->addTos(array($this->getPHID()))->setForceDelivery(true)->setSubject('[Phabricator] Username Changed')->setBody($body)->saveAndSend(); }
public function handleRequest(AphrontRequest $request) { if (!PhabricatorPasswordAuthProvider::getPasswordProvider()) { return new Aphront400Response(); } $e_email = true; $e_captcha = true; $errors = array(); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); if ($request->isFormPost()) { $e_email = null; $e_captcha = pht('Again'); $captcha_ok = AphrontFormRecaptchaControl::processCaptcha($request); if (!$captcha_ok) { $errors[] = pht('Captcha response is incorrect, try again.'); $e_captcha = pht('Invalid'); } $email = $request->getStr('email'); if (!strlen($email)) { $errors[] = pht('You must provide an email address.'); $e_email = pht('Required'); } if (!$errors) { // NOTE: Don't validate the email unless the captcha is good; this makes // it expensive to fish for valid email addresses while giving the user // a better error if they goof their email. $target_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email); $target_user = null; if ($target_email) { $target_user = id(new PhabricatorUser())->loadOneWhere('phid = %s', $target_email->getUserPHID()); } if (!$target_user) { $errors[] = pht('There is no account associated with that email address.'); $e_email = pht('Invalid'); } // If this address is unverified, only send a reset link to it if // the account has no verified addresses. This prevents an opportunistic // attacker from compromising an account if a user adds an email // address but mistypes it and doesn't notice. // (For a newly created account, all the addresses may be unverified, // which is why we'll send to an unverified address in that case.) if ($target_email && !$target_email->getIsVerified()) { $verified_addresses = id(new PhabricatorUserEmail())->loadAllWhere('userPHID = %s AND isVerified = 1', $target_email->getUserPHID()); if ($verified_addresses) { $errors[] = pht('That email address is not verified. You can only send ' . 'password reset links to a verified address.'); $e_email = pht('Unverified'); } } if (!$errors) { $engine = new PhabricatorAuthSessionEngine(); $uri = $engine->getOneTimeLoginURI($target_user, null, PhabricatorAuthSessionEngine::ONETIME_RESET); if ($is_serious) { $body = pht("You can use this link to reset your Phabricator password:"******"\n\n %s\n", $uri); } else { $body = pht("Condolences on forgetting your password. You can use this " . "link to reset it:\n\n" . " %s\n\n" . "After you set a new password, consider writing it down on a " . "sticky note and attaching it to your monitor so you don't " . "forget again! Choosing a very short, easy-to-remember password " . "like \"cat\" or \"1234\" might also help.\n\n" . "Best Wishes,\nPhabricator\n", $uri); } $mail = id(new PhabricatorMetaMTAMail())->setSubject(pht('[Phabricator] Password Reset'))->setForceDelivery(true)->addRawTos(array($target_email->getAddress()))->setBody($body)->saveAndSend(); return $this->newDialog()->setTitle(pht('Check Your Email'))->setShortTitle(pht('Email Sent'))->appendParagraph(pht('An email has been sent with a link you can use to login.'))->addCancelButton('/', pht('Done')); } } } $error_view = null; if ($errors) { $error_view = new PHUIInfoView(); $error_view->setErrors($errors); } $email_auth = new PHUIFormLayoutView(); $email_auth->appendChild($error_view); $email_auth->setUser($request->getUser())->setFullWidth(true)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Email'))->setName('email')->setValue($request->getStr('email'))->setError($e_email))->appendChild(id(new AphrontFormRecaptchaControl())->setLabel(pht('Captcha'))->setError($e_captcha)); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Reset Password')); $dialog = new AphrontDialogView(); $dialog->setUser($request->getUser()); $dialog->setTitle(pht('Forgot Password / Email Login')); $dialog->appendChild($email_auth); $dialog->addSubmitButton(pht('Send Email')); $dialog->setSubmitURI('/login/email/'); return $this->buildApplicationPage(array($crumbs, $dialog), array('title' => pht('Forgot Password'))); }
public function sendUsernameChangeEmail(PhabricatorUser $admin, $old_username) { $admin_username = $admin->getUserName(); $admin_realname = $admin->getRealName(); $new_username = $this->getUserName(); $password_instructions = null; if (PhabricatorPasswordAuthProvider::getPasswordProvider()) { $engine = new PhabricatorAuthSessionEngine(); $uri = $engine->getOneTimeLoginURI($this, null, PhabricatorAuthSessionEngine::ONETIME_USERNAME); $password_instructions = sprintf("%s\n\n %s\n\n%s\n", pht("If you use a password to login, you'll need to reset it " . "before you can login again. You can reset your password by " . "following this link:"), $uri, pht("And, of course, you'll need to use your new username to login " . "from now on. If you use OAuth to login, nothing should change.")); } $body = sprintf("%s\n\n %s\n %s\n\n%s", pht('%s (%s) has changed your Phabricator username.', $admin_username, $admin_realname), pht('Old Username: %s', $old_username), pht('New Username: %s', $new_username), $password_instructions); $mail = id(new PhabricatorMetaMTAMail())->addTos(array($this->getPHID()))->setForceDelivery(true)->setSubject(pht('[Phabricator] Username Changed'))->setBody($body)->saveAndSend(); }