Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14058058
D20031.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
D20031.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2234,6 +2234,8 @@
'PhabricatorAuthFactorProviderListController' => 'applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php',
'PhabricatorAuthFactorProviderNameTransaction' => 'applications/auth/xaction/PhabricatorAuthFactorProviderNameTransaction.php',
'PhabricatorAuthFactorProviderQuery' => 'applications/auth/query/PhabricatorAuthFactorProviderQuery.php',
+ 'PhabricatorAuthFactorProviderStatus' => 'applications/auth/constants/PhabricatorAuthFactorProviderStatus.php',
+ 'PhabricatorAuthFactorProviderStatusTransaction' => 'applications/auth/xaction/PhabricatorAuthFactorProviderStatusTransaction.php',
'PhabricatorAuthFactorProviderTransaction' => 'applications/auth/storage/PhabricatorAuthFactorProviderTransaction.php',
'PhabricatorAuthFactorProviderTransactionQuery' => 'applications/auth/query/PhabricatorAuthFactorProviderTransactionQuery.php',
'PhabricatorAuthFactorProviderTransactionType' => 'applications/auth/xaction/PhabricatorAuthFactorProviderTransactionType.php',
@@ -7961,6 +7963,8 @@
'PhabricatorAuthFactorProviderListController' => 'PhabricatorAuthProviderController',
'PhabricatorAuthFactorProviderNameTransaction' => 'PhabricatorAuthFactorProviderTransactionType',
'PhabricatorAuthFactorProviderQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorAuthFactorProviderStatus' => 'Phobject',
+ 'PhabricatorAuthFactorProviderStatusTransaction' => 'PhabricatorAuthFactorProviderTransactionType',
'PhabricatorAuthFactorProviderTransaction' => 'PhabricatorModularTransaction',
'PhabricatorAuthFactorProviderTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorAuthFactorProviderTransactionType' => 'PhabricatorModularTransactionType',
diff --git a/src/applications/auth/constants/PhabricatorAuthFactorProviderStatus.php b/src/applications/auth/constants/PhabricatorAuthFactorProviderStatus.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/constants/PhabricatorAuthFactorProviderStatus.php
@@ -0,0 +1,103 @@
+<?php
+
+final class PhabricatorAuthFactorProviderStatus
+ extends Phobject {
+
+ private $key;
+ private $spec = array();
+
+ const STATUS_ACTIVE = 'active';
+ const STATUS_DEPRECATED = 'deprecated';
+ const STATUS_DISABLED = 'disabled';
+
+ public static function newForStatus($status) {
+ $result = new self();
+
+ $result->key = $status;
+ $result->spec = self::newSpecification($status);
+
+ return $result;
+ }
+
+ public function getName() {
+ return idx($this->spec, 'name', $this->key);
+ }
+
+ public function getStatusHeaderIcon() {
+ return idx($this->spec, 'header.icon');
+ }
+
+ public function getStatusHeaderColor() {
+ return idx($this->spec, 'header.color');
+ }
+
+ public function isActive() {
+ return ($this->key === self::STATUS_ACTIVE);
+ }
+
+ public function getListIcon() {
+ return idx($this->spec, 'list.icon');
+ }
+
+ public function getListColor() {
+ return idx($this->spec, 'list.color');
+ }
+
+ public function getFactorIcon() {
+ return idx($this->spec, 'factor.icon');
+ }
+
+ public function getFactorColor() {
+ return idx($this->spec, 'factor.color');
+ }
+
+ public function getOrder() {
+ return idx($this->spec, 'order', 0);
+ }
+
+ public static function getMap() {
+ $specs = self::newSpecifications();
+ return ipull($specs, 'name');
+ }
+
+ private static function newSpecification($key) {
+ $specs = self::newSpecifications();
+ return idx($specs, $key, array());
+ }
+
+ private static function newSpecifications() {
+ return array(
+ self::STATUS_ACTIVE => array(
+ 'name' => pht('Active'),
+ 'header.icon' => 'fa-check',
+ 'header.color' => null,
+ 'list.icon' => null,
+ 'list.color' => null,
+ 'factor.icon' => 'fa-check',
+ 'factor.color' => 'green',
+ 'order' => 1,
+ ),
+ self::STATUS_DEPRECATED => array(
+ 'name' => pht('Deprecated'),
+ 'header.icon' => 'fa-ban',
+ 'header.color' => 'indigo',
+ 'list.icon' => 'fa-ban',
+ 'list.color' => 'indigo',
+ 'factor.icon' => 'fa-ban',
+ 'factor.color' => 'indigo',
+ 'order' => 2,
+ ),
+ self::STATUS_DISABLED => array(
+ 'name' => pht('Disabled'),
+ 'header.icon' => 'fa-times',
+ 'header.color' => 'red',
+ 'list.icon' => 'fa-times',
+ 'list.color' => 'red',
+ 'factor.icon' => 'fa-times',
+ 'factor.color' => 'grey',
+ 'order' => 3,
+ ),
+ );
+ }
+
+}
diff --git a/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php b/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php
--- a/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php
+++ b/src/applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php
@@ -197,6 +197,8 @@
->addCancelButton('/', pht('Continue'));
}
+ $views = array();
+
$messages = array();
$messages[] = pht(
@@ -210,7 +212,39 @@
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors($messages);
- return $view;
+ $views[] = $view;
+
+
+ $providers = id(new PhabricatorAuthFactorProviderQuery())
+ ->setViewer($viewer)
+ ->withStatuses(
+ array(
+ PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE,
+ ))
+ ->execute();
+ if (!$providers) {
+ $messages = array();
+
+ $required_key = 'security.require-multi-factor-auth';
+
+ $messages[] = pht(
+ 'This install has the configuration option "%s" enabled, but does '.
+ 'not have any active multifactor providers configured. This means '.
+ 'you are required to add MFA, but are also prevented from doing so. '.
+ 'An administrator must disable "%s" or enable an MFA provider to '.
+ 'allow you to continue.',
+ $required_key,
+ $required_key);
+
+ $view = id(new PHUIInfoView())
+ ->setTitle(pht('Multi-Factor Authentication is Misconfigured'))
+ ->setSeverity(PHUIInfoView::SEVERITY_ERROR)
+ ->setErrors($messages);
+
+ $views[] = $view;
+ }
+
+ return $views;
}
}
diff --git a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php
--- a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php
+++ b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php
@@ -20,6 +20,16 @@
->setHeader($provider->getDisplayName())
->setHref($provider->getURI());
+ $status = $provider->newStatus();
+
+ $icon = $status->getListIcon();
+ $color = $status->getListColor();
+ if ($icon !== null) {
+ $item->setStatusIcon("{$icon} {$color}", $status->getName());
+ }
+
+ $item->setDisabled(!$status->isActive());
+
$list->addItem($item);
}
diff --git a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php
--- a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php
+++ b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php
@@ -58,6 +58,15 @@
->setHeader($provider->getDisplayName())
->setPolicyObject($provider);
+ $status = $provider->newStatus();
+
+ $header_icon = $status->getStatusHeaderIcon();
+ $header_color = $status->getStatusHeaderColor();
+ $header_name = $status->getName();
+ if ($header_icon !== null) {
+ $view->setStatus($header_icon, $header_color, $header_name);
+ }
+
return $view;
}
diff --git a/src/applications/auth/editor/PhabricatorAuthFactorProviderEditEngine.php b/src/applications/auth/editor/PhabricatorAuthFactorProviderEditEngine.php
--- a/src/applications/auth/editor/PhabricatorAuthFactorProviderEditEngine.php
+++ b/src/applications/auth/editor/PhabricatorAuthFactorProviderEditEngine.php
@@ -95,6 +95,8 @@
protected function buildCustomEditFields($object) {
$factor_name = $object->getFactor()->getFactorName();
+ $status_map = PhabricatorAuthFactorProviderStatus::getMap();
+
return array(
id(new PhabricatorStaticEditField())
->setKey('displayType')
@@ -109,6 +111,14 @@
->setDescription(pht('Display name for the MFA provider.'))
->setValue($object->getName())
->setPlaceholder($factor_name),
+ id(new PhabricatorSelectEditField())
+ ->setKey('status')
+ ->setTransactionType(
+ PhabricatorAuthFactorProviderStatusTransaction::TRANSACTIONTYPE)
+ ->setLabel(pht('Status'))
+ ->setDescription(pht('Status of the MFA provider.'))
+ ->setValue($object->getStatus())
+ ->setOptions($status_map),
);
}
diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
--- a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
+++ b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
@@ -473,9 +473,20 @@
$factors = id(new PhabricatorAuthFactorConfigQuery())
->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID()))
- ->setOrderVector(array('-id'))
+ ->withFactorProviderStatuses(
+ array(
+ PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE,
+ PhabricatorAuthFactorProviderStatus::STATUS_DEPRECATED,
+ ))
->execute();
+ // Sort factors in the same order that they appear in on the Settings
+ // panel. This means that administrators changing provider statuses may
+ // change the order of prompts for users, but the alternative is that the
+ // Settings panel order disagrees with the prompt order, which seems more
+ // disruptive.
+ $factors = msort($factors, 'newSortVector');
+
// If the account has no associated multi-factor auth, just issue a token
// without putting the session into high security mode. This is generally
// easier for users. A minor but desirable side effect is that when a user
diff --git a/src/applications/auth/factor/PhabricatorAuthFactor.php b/src/applications/auth/factor/PhabricatorAuthFactor.php
--- a/src/applications/auth/factor/PhabricatorAuthFactor.php
+++ b/src/applications/auth/factor/PhabricatorAuthFactor.php
@@ -54,11 +54,15 @@
return null;
}
- public function canCreateNewConfiguration(PhabricatorUser $user) {
+ public function canCreateNewConfiguration(
+ PhabricatorAuthFactorProvider $provider,
+ PhabricatorUser $user) {
return true;
}
- public function getConfigurationCreateDescription(PhabricatorUser $user) {
+ public function getConfigurationCreateDescription(
+ PhabricatorAuthFactorProvider $provider,
+ PhabricatorUser $user) {
return null;
}
diff --git a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
--- a/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
+++ b/src/applications/auth/factor/PhabricatorSMSAuthFactor.php
@@ -67,7 +67,10 @@
return $messages;
}
- public function canCreateNewConfiguration(PhabricatorUser $user) {
+ public function canCreateNewConfiguration(
+ PhabricatorAuthFactorProvider $provider,
+ PhabricatorUser $user) {
+
if (!$this->loadUserContactNumber($user)) {
return false;
}
@@ -75,7 +78,9 @@
return true;
}
- public function getConfigurationCreateDescription(PhabricatorUser $user) {
+ public function getConfigurationCreateDescription(
+ PhabricatorAuthFactorProvider $provider,
+ PhabricatorUser $user) {
$messages = array();
diff --git a/src/applications/auth/query/PhabricatorAuthFactorConfigQuery.php b/src/applications/auth/query/PhabricatorAuthFactorConfigQuery.php
--- a/src/applications/auth/query/PhabricatorAuthFactorConfigQuery.php
+++ b/src/applications/auth/query/PhabricatorAuthFactorConfigQuery.php
@@ -7,6 +7,7 @@
private $phids;
private $userPHIDs;
private $factorProviderPHIDs;
+ private $factorProviderStatuses;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -28,6 +29,11 @@
return $this;
}
+ public function withFactorProviderStatuses(array $statuses) {
+ $this->factorProviderStatuses = $statuses;
+ return $this;
+ }
+
public function newResultObject() {
return new PhabricatorAuthFactorConfig();
}
@@ -42,34 +48,54 @@
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
- 'id IN (%Ld)',
+ 'config.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
- 'phid IN (%Ls)',
+ 'config.phid IN (%Ls)',
$this->phids);
}
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn,
- 'userPHID IN (%Ls)',
+ 'config.userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->factorProviderPHIDs !== null) {
$where[] = qsprintf(
$conn,
- 'factorProviderPHID IN (%Ls)',
+ 'config.factorProviderPHID IN (%Ls)',
$this->factorProviderPHIDs);
}
+ if ($this->factorProviderStatuses !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'provider.status IN (%Ls)',
+ $this->factorProviderStatuses);
+ }
+
return $where;
}
+ protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
+ $joins = parent::buildJoinClauseParts($conn);
+
+ if ($this->factorProviderStatuses !== null) {
+ $joins[] = qsprintf(
+ $conn,
+ 'JOIN %R provider ON config.factorProviderPHID = provider.phid',
+ new PhabricatorAuthFactorProvider());
+ }
+
+ return $joins;
+ }
+
protected function willFilterPage(array $configs) {
$provider_phids = mpull($configs, 'getFactorProviderPHID');
@@ -94,6 +120,10 @@
return $configs;
}
+ protected function getPrimaryTableAlias() {
+ return 'config';
+ }
+
public function getQueryApplicationClass() {
return 'PhabricatorAuthApplication';
}
diff --git a/src/applications/auth/storage/PhabricatorAuthFactorConfig.php b/src/applications/auth/storage/PhabricatorAuthFactorConfig.php
--- a/src/applications/auth/storage/PhabricatorAuthFactorConfig.php
+++ b/src/applications/auth/storage/PhabricatorAuthFactorConfig.php
@@ -80,6 +80,12 @@
return $this;
}
+ public function newSortVector() {
+ return id(new PhutilSortVector())
+ ->addInt($this->getFactorProvider()->newStatus()->getOrder())
+ ->addInt($this->getID());
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
diff --git a/src/applications/auth/storage/PhabricatorAuthFactorProvider.php b/src/applications/auth/storage/PhabricatorAuthFactorProvider.php
--- a/src/applications/auth/storage/PhabricatorAuthFactorProvider.php
+++ b/src/applications/auth/storage/PhabricatorAuthFactorProvider.php
@@ -14,15 +14,11 @@
private $factor = self::ATTACHABLE;
- const STATUS_ACTIVE = 'active';
- const STATUS_DEPRECATED = 'deprecated';
- const STATUS_DISABLED = 'disabled';
-
public static function initializeNewProvider(PhabricatorAuthFactor $factor) {
return id(new self())
->setProviderFactorKey($factor->getFactorKey())
->attachFactor($factor)
- ->setStatus(self::STATUS_ACTIVE);
+ ->setStatus(PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE);
}
protected function getConfiguration() {
@@ -117,6 +113,20 @@
return $this->getFactor()->getEnrollButtonText($this, $user);
}
+ public function newStatus() {
+ $status_key = $this->getStatus();
+ return PhabricatorAuthFactorProviderStatus::newForStatus($status_key);
+ }
+
+ public function canCreateNewConfiguration(PhabricatorUser $user) {
+ return $this->getFactor()->canCreateNewConfiguration($this, $user);
+ }
+
+ public function getConfigurationCreateDescription(PhabricatorUser $user) {
+ return $this->getFactor()->getConfigurationCreateDescription($this, $user);
+ }
+
+
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
diff --git a/src/applications/auth/xaction/PhabricatorAuthFactorProviderStatusTransaction.php b/src/applications/auth/xaction/PhabricatorAuthFactorProviderStatusTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/xaction/PhabricatorAuthFactorProviderStatusTransaction.php
@@ -0,0 +1,103 @@
+<?php
+
+final class PhabricatorAuthFactorProviderStatusTransaction
+ extends PhabricatorAuthFactorProviderTransactionType {
+
+ const TRANSACTIONTYPE = 'status';
+
+ public function generateOldValue($object) {
+ return $object->getStatus();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setStatus($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $old_display = PhabricatorAuthFactorProviderStatus::newForStatus($old)
+ ->getName();
+ $new_display = PhabricatorAuthFactorProviderStatus::newForStatus($new)
+ ->getName();
+
+ return pht(
+ '%s changed the status of this provider from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderValue($old_display),
+ $this->renderValue($new_display));
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+ $actor = $this->getActor();
+
+ $map = PhabricatorAuthFactorProviderStatus::getMap();
+ foreach ($xactions as $xaction) {
+ $new_value = $xaction->getNewValue();
+
+ if (!isset($map[$new_value])) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Status "%s" is invalid. Valid statuses are: %s.',
+ $new_value,
+ implode(', ', array_keys($map))),
+ $xaction);
+ continue;
+ }
+
+ $require_key = 'security.require-multi-factor-auth';
+ $require_mfa = PhabricatorEnv::getEnvConfig($require_key);
+
+ if ($require_mfa) {
+ $status_active = PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE;
+ if ($new_value !== $status_active) {
+ $active_providers = id(new PhabricatorAuthFactorProviderQuery())
+ ->setViewer($actor)
+ ->withStatuses(
+ array(
+ $status_active,
+ ))
+ ->execute();
+ $active_providers = mpull($active_providers, null, 'getID');
+ unset($active_providers[$object->getID()]);
+
+ if (!$active_providers) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'You can not deprecate or disable the last active MFA '.
+ 'provider while "%s" is enabled, because new users would '.
+ 'be unable to enroll in MFA. Disable the MFA requirement '.
+ 'in Config, or create or enable another MFA provider first.',
+ $require_key));
+ continue;
+ }
+ }
+ }
+ }
+
+ return $errors;
+ }
+
+ public function didCommitTransaction($object, $value) {
+ $status = PhabricatorAuthFactorProviderStatus::newForStatus($value);
+
+ // If a provider has undergone a status change, reset the MFA enrollment
+ // cache for all users. This may immediately force a lot of users to redo
+ // MFA enrollment.
+
+ // We could be more surgical about this: we only really need to affect
+ // users who had a factor under the provider, and only really need to
+ // do anything if a provider was disabled. This is just a little simpler.
+
+ $table = new PhabricatorUser();
+ $conn = $table->establishConnection('w');
+
+ queryfx(
+ $conn,
+ 'UPDATE %R SET isEnrolledInMultiFactor = 0',
+ $table);
+ }
+
+}
diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -908,9 +908,15 @@
* @task factors
*/
public function updateMultiFactorEnrollment() {
- $factors = id(new PhabricatorAuthFactorConfig())->loadAllWhere(
- 'userPHID = %s',
- $this->getPHID());
+ $factors = id(new PhabricatorAuthFactorConfigQuery())
+ ->setViewer($this)
+ ->withUserPHIDs(array($this->getPHID()))
+ ->withFactorProviderStatuses(
+ array(
+ PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE,
+ PhabricatorAuthFactorProviderStatus::STATUS_DEPRECATED,
+ ))
+ ->execute();
$enrolled = count($factors) ? 1 : 0;
if ($enrolled !== $this->isEnrolledInMultiFactor) {
diff --git a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php
@@ -53,8 +53,8 @@
$factors = id(new PhabricatorAuthFactorConfigQuery())
->setViewer($viewer)
->withUserPHIDs(array($user->getPHID()))
- ->setOrderVector(array('-id'))
->execute();
+ $factors = msort($factors, 'newSortVector');
$rows = array();
$rowc = array();
@@ -69,7 +69,16 @@
$rowc[] = null;
}
+ $status = $provider->newStatus();
+ $status_icon = $status->getFactorIcon();
+ $status_color = $status->getFactorColor();
+
+ $icon = id(new PHUIIconView())
+ ->setIcon("{$status_icon} {$status_color}")
+ ->setTooltip(pht('Provider: %s', $status->getName()));
+
$rows[] = array(
+ $icon,
javelin_tag(
'a',
array(
@@ -95,21 +104,24 @@
pht("You haven't added any authentication factors to your account yet."));
$table->setHeaders(
array(
+ null,
pht('Name'),
pht('Type'),
pht('Created'),
- '',
+ null,
));
$table->setColumnClasses(
array(
+ null,
'wide pri',
- '',
+ null,
'right',
'action',
));
$table->setRowClasses($rowc);
$table->setDeviceVisibility(
array(
+ true,
true,
false,
false,
@@ -129,12 +141,15 @@
$add_color = PHUIButtonView::GREY;
}
+ $can_add = (bool)$this->loadActiveMFAProviders();
+
$buttons[] = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-plus')
->setText(pht('Add Auth Factor'))
->setHref($this->getPanelURI('?new=true'))
->setWorkflow(true)
+ ->setDisabled(!$can_add)
->setColor($add_color);
$buttons[] = id(new PHUIButtonView())
@@ -155,21 +170,18 @@
// Check that we have providers before we send the user through the MFA
// gate, so you don't authenticate and then immediately get roadblocked.
- $providers = id(new PhabricatorAuthFactorProviderQuery())
- ->setViewer($viewer)
- ->withStatuses(array(PhabricatorAuthFactorProvider::STATUS_ACTIVE))
- ->execute();
+ $providers = $this->loadActiveMFAProviders();
+
if (!$providers) {
return $this->newDialog()
->setTitle(pht('No MFA Providers'))
->appendParagraph(
pht(
- 'There are no active MFA providers. At least one active provider '.
- 'must be available to add new MFA factors.'))
+ 'This install does not have any active MFA providers configured. '.
+ 'At least one provider must be configured and active before you '.
+ 'can add new MFA factors.'))
->addCancelButton($cancel_uri);
}
- $providers = mpull($providers, null, 'getPHID');
- $proivders = msortv($providers, 'newSortVector');
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
$viewer,
@@ -184,8 +196,7 @@
// Only let the user continue creating a factor for a given provider if
// they actually pass the provider's checks.
- $selected_factor = $selected_provider->getFactor();
- if (!$selected_factor->canCreateNewConfiguration($viewer)) {
+ if (!$selected_provider->canCreateNewConfiguration($viewer)) {
$selected_provider = null;
}
}
@@ -200,8 +211,7 @@
$provider_uri = id(new PhutilURI($this->getPanelURI()))
->setQueryParam('providerPHID', $provider_phid);
- $factor = $provider->getFactor();
- $is_enabled = $factor->canCreateNewConfiguration($viewer);
+ $is_enabled = $provider->canCreateNewConfiguration($viewer);
$item = id(new PHUIObjectItemView())
->setHeader($provider->getDisplayName())
@@ -216,7 +226,7 @@
$item->setDisabled(true);
}
- $create_description = $factor->getConfigurationCreateDescription(
+ $create_description = $provider->getConfigurationCreateDescription(
$viewer);
if ($create_description) {
$item->appendChild($create_description);
@@ -424,5 +434,22 @@
->setDialog($dialog);
}
+ private function loadActiveMFAProviders() {
+ $viewer = $this->getViewer();
+
+ $providers = id(new PhabricatorAuthFactorProviderQuery())
+ ->setViewer($viewer)
+ ->withStatuses(
+ array(
+ PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE,
+ ))
+ ->execute();
+
+ $providers = mpull($providers, null, 'getPHID');
+ $providers = msortv($providers, 'newSortVector');
+
+ return $providers;
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 18, 9:14 AM (1 d, 16 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6732387
Default Alt Text
D20031.diff (25 KB)
Attached To
Mode
D20031: Allow MFA providers to be deprecated or disabled
Attached
Detach File
Event Timeline
Log In to Comment