Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php
index a525e7b930..28b7e69593 100644
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberDisableController.php
@@ -1,88 +1,91 @@
<?php
final class PhabricatorAuthContactNumberDisableController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
- $number = id(new PhabricatorAuthContactNumberQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
- if (!$number) {
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ $number = id(new PhabricatorAuthContactNumberQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ }
+ if (!isset($number) || !$number) {
return new Aphront404Response();
}
$is_disable = ($request->getURIData('action') == 'disable');
$id = $number->getID();
$cancel_uri = $number->getURI();
if ($request->isFormOrHisecPost()) {
$xactions = array();
if ($is_disable) {
$new_status = PhabricatorAuthContactNumber::STATUS_DISABLED;
} else {
$new_status = PhabricatorAuthContactNumber::STATUS_ACTIVE;
}
$xactions[] = id(new PhabricatorAuthContactNumberTransaction())
->setTransactionType(
PhabricatorAuthContactNumberStatusTransaction::TRANSACTIONTYPE)
->setNewValue($new_status);
$editor = id(new PhabricatorAuthContactNumberEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->setCancelURI($cancel_uri);
try {
$editor->applyTransactions($number, $xactions);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
// This happens when you enable a number which collides with another
// number.
return $this->newDialog()
->setTitle(pht('Changing Status Failed'))
->setValidationException($ex)
->addCancelButton($cancel_uri);
}
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
}
$number_display = phutil_tag(
'strong',
array(),
$number->getDisplayName());
if ($is_disable) {
$title = pht('Disable Contact Number');
$body = pht(
'Disable the contact number %s?',
$number_display);
$button = pht('Disable Number');
} else {
$title = pht('Enable Contact Number');
$body = pht(
'Enable the contact number %s?',
$number_display);
$button = pht('Enable Number');
}
return $this->newDialog()
->setTitle($title)
->appendParagraph($body)
->addSubmitButton($button)
->addCancelButton($cancel_uri);
}
}
diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php
index 95764496da..c012ca3581 100644
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberEditController.php
@@ -1,12 +1,17 @@
<?php
final class PhabricatorAuthContactNumberEditController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
- return id(new PhabricatorAuthContactNumberEditEngine())
- ->setController($this)
- ->buildResponse();
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ return id(new PhabricatorAuthContactNumberEditEngine())
+ ->setController($this)
+ ->buildResponse();
+ } else {
+ return new Aphront404Response();
+ }
}
}
diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php
index cad1bbf3fc..63ba5ad883 100644
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberPrimaryController.php
@@ -1,88 +1,91 @@
<?php
final class PhabricatorAuthContactNumberPrimaryController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
- $number = id(new PhabricatorAuthContactNumberQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
- if (!$number) {
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ $number = id(new PhabricatorAuthContactNumberQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ }
+ if (!isset($number) || !$number) {
return new Aphront404Response();
}
$id = $number->getID();
$cancel_uri = $number->getURI();
if ($number->isDisabled()) {
return $this->newDialog()
->setTitle(pht('Number Disabled'))
->appendParagraph(
pht(
'You can not make a disabled number your primary contact number.'))
->addCancelButton($cancel_uri);
}
if ($number->getIsPrimary()) {
return $this->newDialog()
->setTitle(pht('Number Already Primary'))
->appendParagraph(
pht(
'This contact number is already your primary contact number.'))
->addCancelButton($cancel_uri);
}
if ($request->isFormOrHisecPost()) {
$xactions = array();
$xactions[] = id(new PhabricatorAuthContactNumberTransaction())
->setTransactionType(
PhabricatorAuthContactNumberPrimaryTransaction::TRANSACTIONTYPE)
->setNewValue(true);
$editor = id(new PhabricatorAuthContactNumberEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->setCancelURI($cancel_uri);
try {
$editor->applyTransactions($number, $xactions);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
// This happens when you try to make a number into your primary
// number, but you have contact number MFA on your account.
return $this->newDialog()
->setTitle(pht('Unable to Make Primary'))
->setValidationException($ex)
->addCancelButton($cancel_uri);
}
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
}
$number_display = phutil_tag(
'strong',
array(),
$number->getDisplayName());
return $this->newDialog()
->setTitle(pht('Set Primary Contact Number'))
->appendParagraph(
pht(
'Designate %s as your primary contact number?',
$number_display))
->addSubmitButton(pht('Make Primary'))
->addCancelButton($cancel_uri);
}
}
diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php
index f8c8b013bf..a991c34a6d 100644
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberTestController.php
@@ -1,64 +1,67 @@
<?php
final class PhabricatorAuthContactNumberTestController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
- $number = id(new PhabricatorAuthContactNumberQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
- if (!$number) {
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ $number = id(new PhabricatorAuthContactNumberQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ }
+ if (!isset($number) || !$number) {
return new Aphront404Response();
}
$id = $number->getID();
$cancel_uri = $number->getURI();
// NOTE: This is a global limit shared by all users.
PhabricatorSystemActionEngine::willTakeAction(
array(id(new PhabricatorAuthApplication())->getPHID()),
new PhabricatorAuthTestSMSAction(),
1);
if ($request->isFormPost()) {
$uri = PhabricatorEnv::getURI('/');
$uri = new PhutilURI($uri);
$mail = id(new PhabricatorMetaMTAMail())
->setMessageType(PhabricatorMailSMSMessage::MESSAGETYPE)
->addTos(array($viewer->getPHID()))
->setSensitiveContent(false)
->setBody(
pht(
'This is a terse test text message (from "%s").',
$uri->getDomain()))
->save();
return id(new AphrontRedirectResponse())->setURI($mail->getURI());
}
$number_display = phutil_tag(
'strong',
array(),
$number->getDisplayName());
return $this->newDialog()
->setTitle(pht('Set Test Message'))
->appendParagraph(
pht(
'Send a test message to %s?',
$number_display))
->addSubmitButton(pht('Send SMS'))
->addCancelButton($cancel_uri);
}
}
diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php
index 027d288dbc..75e4b8e3b7 100644
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberViewController.php
@@ -1,139 +1,142 @@
<?php
final class PhabricatorAuthContactNumberViewController
extends PhabricatorAuthContactNumberController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
- $number = id(new PhabricatorAuthContactNumberQuery())
- ->setViewer($viewer)
- ->withIDs(array($request->getURIData('id')))
- ->executeOne();
- if (!$number) {
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ $number = id(new PhabricatorAuthContactNumberQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->executeOne();
+ }
+ if (!isset($number) || !$number) {
return new Aphront404Response();
}
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb($number->getObjectName())
->setBorder(true);
$header = $this->buildHeaderView($number);
$properties = $this->buildPropertiesView($number);
$curtain = $this->buildCurtain($number);
$timeline = $this->buildTransactionTimeline(
$number,
new PhabricatorAuthContactNumberTransactionQuery());
$timeline->setShouldTerminate(true);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(
array(
$timeline,
))
->addPropertySection(pht('Details'), $properties);
return $this->newPage()
->setTitle($number->getDisplayName())
->setCrumbs($crumbs)
->setPageObjectPHIDs(
array(
$number->getPHID(),
))
->appendChild($view);
}
private function buildHeaderView(PhabricatorAuthContactNumber $number) {
$viewer = $this->getViewer();
$view = id(new PHUIHeaderView())
->setViewer($viewer)
->setHeader($number->getObjectName())
->setPolicyObject($number);
if ($number->isDisabled()) {
$view->setStatus('fa-ban', 'red', pht('Disabled'));
} else if ($number->getIsPrimary()) {
$view->setStatus('fa-certificate', 'blue', pht('Primary'));
}
return $view;
}
private function buildPropertiesView(
PhabricatorAuthContactNumber $number) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setViewer($viewer);
$view->addProperty(
pht('Owner'),
$viewer->renderHandle($number->getObjectPHID()));
$view->addProperty(pht('Contact Number'), $number->getDisplayName());
return $view;
}
private function buildCurtain(PhabricatorAuthContactNumber $number) {
$viewer = $this->getViewer();
$id = $number->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$number,
PhabricatorPolicyCapability::CAN_EDIT);
$curtain = $this->newCurtainView($number);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Contact Number'))
->setIcon('fa-pencil')
->setHref($this->getApplicationURI("contact/edit/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Send Test Message'))
->setIcon('fa-envelope-o')
->setHref($this->getApplicationURI("contact/test/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(true));
if ($number->isDisabled()) {
$disable_uri = $this->getApplicationURI("contact/enable/{$id}/");
$disable_name = pht('Enable Contact Number');
$disable_icon = 'fa-check';
$can_primary = false;
} else {
$disable_uri = $this->getApplicationURI("contact/disable/{$id}/");
$disable_name = pht('Disable Contact Number');
$disable_icon = 'fa-ban';
$can_primary = !$number->getIsPrimary();
}
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Make Primary Number'))
->setIcon('fa-certificate')
->setHref($this->getApplicationURI("contact/primary/{$id}/"))
->setDisabled(!$can_primary)
->setWorkflow(true));
$curtain->addAction(
id(new PhabricatorActionView())
->setName($disable_name)
->setIcon($disable_icon)
->setHref($disable_uri)
->setWorkflow(true));
return $curtain;
}
}
diff --git a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
index 33f640e692..2350855859 100644
--- a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
+++ b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
@@ -1,402 +1,402 @@
<?php
final class PhabricatorSMSAuthFactor
extends PhabricatorAuthFactor {
public function getFactorKey() {
return 'sms';
}
public function getFactorName() {
return pht('Text Message (SMS)');
}
public function getFactorShortName() {
return pht('SMS');
}
public function getFactorCreateHelp() {
return pht(
'Allow users to receive a code via SMS.');
}
public function getFactorDescription() {
return pht(
'When you need to authenticate, a text message with a code will '.
'be sent to your phone.');
}
public function getFactorOrder() {
// Sort this factor toward the end of the list because SMS is relatively
// weak.
return 2000;
}
public function isContactNumberFactor() {
return true;
}
public function canCreateNewProvider() {
return $this->isSMSMailerConfigured();
}
public function getProviderCreateDescription() {
$messages = array();
if (!$this->isSMSMailerConfigured()) {
$messages[] = id(new PHUIInfoView())
->setErrors(
array(
pht(
'You have not configured an outbound SMS mailer. You must '.
'configure one before you can set up SMS. See: %s',
phutil_tag(
'a',
array(
'href' => '/config/edit/cluster.mailers/',
),
'cluster.mailers')),
));
}
$messages[] = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors(
array(
pht(
'SMS is weak, and relatively easy for attackers to compromise. '.
'Strongly consider using a different MFA provider.'),
));
return $messages;
}
public function canCreateNewConfiguration(
PhabricatorAuthFactorProvider $provider,
PhabricatorUser $user) {
if (!$this->loadUserContactNumber($user)) {
return false;
}
if ($this->loadConfigurationsForProvider($provider, $user)) {
return false;
}
return true;
}
public function getConfigurationCreateDescription(
PhabricatorAuthFactorProvider $provider,
PhabricatorUser $user) {
$messages = array();
if (!$this->loadUserContactNumber($user)) {
$messages[] = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors(
array(
pht(
'You have not configured a primary contact number. Configure '.
'a contact number before adding SMS as an authentication '.
'factor.'),
));
}
if ($this->loadConfigurationsForProvider($provider, $user)) {
$messages[] = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors(
array(
pht(
'You already have SMS authentication attached to your account.'),
));
}
return $messages;
}
public function getEnrollDescription(
PhabricatorAuthFactorProvider $provider,
PhabricatorUser $user) {
return pht(
'To verify your phone as an authentication factor, a text message with '.
'a secret code will be sent to the phone number you have listed as '.
'your primary contact number.');
}
public function getEnrollButtonText(
PhabricatorAuthFactorProvider $provider,
PhabricatorUser $user) {
$contact_number = $this->loadUserContactNumber($user);
return pht('Send SMS: %s', $contact_number->getDisplayName());
}
public function processAddFactorForm(
PhabricatorAuthFactorProvider $provider,
AphrontFormView $form,
AphrontRequest $request,
PhabricatorUser $user) {
$token = $this->loadMFASyncToken($provider, $request, $form, $user);
$code = $request->getStr('sms.code');
$e_code = true;
if (!$token->getIsNewTemporaryToken()) {
$expect_code = $token->getTemporaryTokenProperty('code');
$okay = phutil_hashes_are_identical(
$this->normalizeSMSCode($code),
$this->normalizeSMSCode($expect_code));
if ($okay) {
$config = $this->newConfigForUser($user)
->setFactorName(pht('SMS'));
return $config;
} else {
if (!strlen($code)) {
$e_code = pht('Required');
} else {
$e_code = pht('Invalid');
}
}
}
$form->appendRemarkupInstructions(
pht(
'Enter the code from the text message which was sent to your '.
'primary contact number.'));
$form->appendChild(
id(new PHUIFormNumberControl())
->setLabel(pht('SMS Code'))
->setName('sms.code')
->setValue($code)
->setError($e_code));
}
protected function newIssuedChallenges(
PhabricatorAuthFactorConfig $config,
PhabricatorUser $viewer,
array $challenges) {
// If we already issued a valid challenge for this workflow and session,
// don't issue a new one.
$challenge = $this->getChallengeForCurrentContext(
$config,
$viewer,
$challenges);
if ($challenge) {
return array();
}
if (!$this->loadUserContactNumber($viewer)) {
return $this->newResult()
->setIsError(true)
->setErrorMessage(
pht(
'Your account has no primary contact number.'));
}
if (!$this->isSMSMailerConfigured()) {
return $this->newResult()
->setIsError(true)
->setErrorMessage(
pht(
'No outbound mailer which can deliver SMS messages is '.
'configured.'));
}
if (!$this->hasCSRF($config)) {
return $this->newResult()
->setIsContinue(true)
->setErrorMessage(
pht(
'A text message with an authorization code will be sent to your '.
'primary contact number.'));
}
// Otherwise, issue a new challenge.
$challenge_code = $this->newSMSChallengeCode();
$envelope = new PhutilOpaqueEnvelope($challenge_code);
$this->sendSMSCodeToUser($envelope, $viewer);
$ttl_seconds = phutil_units('15 minutes in seconds');
return array(
$this->newChallenge($config, $viewer)
->setChallengeKey($challenge_code)
->setChallengeTTL(PhabricatorTime::getNow() + $ttl_seconds),
);
}
protected function newResultFromIssuedChallenges(
PhabricatorAuthFactorConfig $config,
PhabricatorUser $viewer,
array $challenges) {
$challenge = $this->getChallengeForCurrentContext(
$config,
$viewer,
$challenges);
if ($challenge->getIsAnsweredChallenge()) {
return $this->newResult()
->setAnsweredChallenge($challenge);
}
return null;
}
public function renderValidateFactorForm(
PhabricatorAuthFactorConfig $config,
AphrontFormView $form,
PhabricatorUser $viewer,
PhabricatorAuthFactorResult $result) {
$control = $this->newAutomaticControl($result);
if (!$control) {
$value = $result->getValue();
$error = $result->getErrorMessage();
$name = $this->getChallengeResponseParameterName($config);
$control = id(new PHUIFormNumberControl())
->setName($name)
->setDisableAutocomplete(true)
->setValue($value)
->setError($error);
}
$control
->setLabel(pht('SMS Code'))
->setCaption(pht('Factor Name: %s', $config->getFactorName()));
$form->appendChild($control);
}
public function getRequestHasChallengeResponse(
PhabricatorAuthFactorConfig $config,
AphrontRequest $request) {
$value = $this->getChallengeResponseFromRequest($config, $request);
return (bool)strlen($value);
}
protected function newResultFromChallengeResponse(
PhabricatorAuthFactorConfig $config,
PhabricatorUser $viewer,
AphrontRequest $request,
array $challenges) {
$challenge = $this->getChallengeForCurrentContext(
$config,
$viewer,
$challenges);
$code = $this->getChallengeResponseFromRequest(
$config,
$request);
$result = $this->newResult()
->setValue($code);
if ($challenge->getIsAnsweredChallenge()) {
return $result->setAnsweredChallenge($challenge);
}
if (phutil_hashes_are_identical($code, $challenge->getChallengeKey())) {
$ttl = PhabricatorTime::getNow() + phutil_units('15 minutes in seconds');
$challenge
->markChallengeAsAnswered($ttl);
return $result->setAnsweredChallenge($challenge);
}
if (strlen($code)) {
$error_message = pht('Invalid');
} else {
$error_message = pht('Required');
}
$result->setErrorMessage($error_message);
return $result;
}
private function newSMSChallengeCode() {
$value = Filesystem::readRandomInteger(0, 99999999);
$value = sprintf('%08d', $value);
return $value;
}
- private function isSMSMailerConfigured() {
+ public function isSMSMailerConfigured() {
$mailers = PhabricatorMetaMTAMail::newMailers(
array(
'outbound' => true,
'media' => array(
PhabricatorMailSMSMessage::MESSAGETYPE,
),
));
return (bool)$mailers;
}
private function loadUserContactNumber(PhabricatorUser $user) {
$contact_numbers = id(new PhabricatorAuthContactNumberQuery())
->setViewer($user)
->withObjectPHIDs(array($user->getPHID()))
->withStatuses(
array(
PhabricatorAuthContactNumber::STATUS_ACTIVE,
))
->withIsPrimary(true)
->execute();
if (count($contact_numbers) !== 1) {
return null;
}
return head($contact_numbers);
}
protected function newMFASyncTokenProperties(
PhabricatorAuthFactorProvider $providerr,
PhabricatorUser $user) {
$sms_code = $this->newSMSChallengeCode();
$envelope = new PhutilOpaqueEnvelope($sms_code);
$this->sendSMSCodeToUser($envelope, $user);
return array(
'code' => $sms_code,
);
}
private function sendSMSCodeToUser(
PhutilOpaqueEnvelope $envelope,
PhabricatorUser $user) {
return id(new PhabricatorMetaMTAMail())
->setMessageType(PhabricatorMailSMSMessage::MESSAGETYPE)
->addTos(array($user->getPHID()))
->setForceDelivery(true)
->setSensitiveContent(true)
->setBody(
pht(
'%s (%s) MFA Code: %s',
PlatformSymbols::getPlatformServerName(),
$this->getInstallDisplayName(),
$envelope->openEnvelope()))
->save();
}
private function normalizeSMSCode($code) {
return trim($code);
}
}
diff --git a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
index 7056fd02de..60a2064546 100644
--- a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
@@ -1,91 +1,103 @@
<?php
final class PhabricatorContactNumbersSettingsPanel
extends PhabricatorSettingsPanel {
public function getPanelKey() {
return 'contact';
}
public function getPanelName() {
return pht('Contact Numbers');
}
public function getPanelMenuIcon() {
return 'fa-hashtag';
}
public function getPanelGroupKey() {
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
+ /**
+ * Whether to display "Contact Numbers" panel in users' Personal
+ * Settings by checking if global SMS support is configured
+ */
+ public function isUserPanel() {
+ $sms_auth_factor = new PhabricatorSMSAuthFactor();
+ if ($sms_auth_factor->isSMSMailerConfigured()) {
+ return true;
+ }
+ return false;
+ }
+
public function isMultiFactorEnrollmentPanel() {
return true;
}
public function processRequest(AphrontRequest $request) {
$user = $this->getUser();
$viewer = $request->getUser();
$numbers = id(new PhabricatorAuthContactNumberQuery())
->setViewer($viewer)
->withObjectPHIDs(array($user->getPHID()))
->execute();
$numbers = msortv($numbers, 'getSortVector');
$rows = array();
$row_classes = array();
foreach ($numbers as $number) {
if ($number->getIsPrimary()) {
$primary_display = pht('Primary');
$row_classes[] = 'highlighted';
} else {
$primary_display = null;
$row_classes[] = null;
}
$rows[] = array(
$number->newIconView(),
phutil_tag(
'a',
array(
'href' => $number->getURI(),
),
$number->getDisplayName()),
$primary_display,
phabricator_datetime($number->getDateCreated(), $viewer),
);
}
$table = id(new AphrontTableView($rows))
->setNoDataString(
pht("You haven't added any contact numbers to your account."))
->setRowClasses($row_classes)
->setHeaders(
array(
null,
pht('Number'),
pht('Status'),
pht('Created'),
))
->setColumnClasses(
array(
null,
'wide pri',
null,
'right',
));
$buttons = array();
$buttons[] = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-plus')
->setText(pht('Add Contact Number'))
->setHref('/auth/contact/edit/')
->setColor(PHUIButtonView::GREY);
return $this->newBox(pht('Contact Numbers'), $table, $buttons);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Apr 29, 5:55 AM (23 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
108204
Default Alt Text
(29 KB)

Event Timeline