Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14087058
D20008.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D20008.diff
View Options
diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php
--- a/src/applications/auth/application/PhabricatorAuthApplication.php
+++ b/src/applications/auth/application/PhabricatorAuthApplication.php
@@ -72,8 +72,10 @@
=> 'PhabricatorAuthRevokeTokenController',
'session/downgrade/'
=> 'PhabricatorAuthDowngradeSessionController',
- 'multifactor/'
- => 'PhabricatorAuthNeedsMultiFactorController',
+ 'enroll/' => array(
+ '(?:(?P<pageKey>[^/]+)/)?(?:(?P<formSaved>saved)/)?'
+ => 'PhabricatorAuthNeedsMultiFactorController',
+ ),
'sshkey/' => array(
$this->getQueryRoutePattern('for/(?P<forPHID>[^/]+)/')
=> 'PhabricatorAuthSSHKeyListController',
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
@@ -30,80 +30,187 @@
return new Aphront400Response();
}
- $panel = id(new PhabricatorMultiFactorSettingsPanel())
- ->setUser($viewer)
- ->setViewer($viewer)
- ->setOverrideURI($this->getApplicationURI('/multifactor/'))
- ->processRequest($request);
+ $panels = $this->loadPanels();
+
+ $multifactor_key = id(new PhabricatorMultiFactorSettingsPanel())
+ ->getPanelKey();
+
+ $panel_key = $request->getURIData('pageKey');
+ if (!strlen($panel_key)) {
+ $panel_key = $multifactor_key;
+ }
- if ($panel instanceof AphrontResponse) {
- return $panel;
+ if (!isset($panels[$panel_key])) {
+ return new Aphront404Response();
}
- $crumbs = $this->buildApplicationCrumbs();
- $crumbs->addTextCrumb(pht('Add Multi-Factor Auth'));
+ $nav = $this->newNavigation();
+ $nav->selectFilter($panel_key);
+
+ $panel = $panels[$panel_key];
$viewer->updateMultiFactorEnrollment();
- if (!$viewer->getIsEnrolledInMultiFactor()) {
- $help = id(new PHUIInfoView())
- ->setTitle(pht('Add Multi-Factor Authentication To Your Account'))
- ->setSeverity(PHUIInfoView::SEVERITY_WARNING)
- ->setErrors(
- array(
- pht(
- 'Before you can use Phabricator, you need to add multi-factor '.
- 'authentication to your account.'),
- pht(
- 'Multi-factor authentication helps secure your account by '.
- 'making it more difficult for attackers to gain access or '.
- 'take sensitive actions.'),
- pht(
- 'To learn more about multi-factor authentication, click the '.
- '%s button below.',
- phutil_tag('strong', array(), pht('Help'))),
- pht(
- 'To add an authentication factor, click the %s button below.',
- phutil_tag('strong', array(), pht('Add Authentication Factor'))),
- pht(
- 'To continue, add at least one authentication factor to your '.
- 'account.'),
- ));
+ if ($panel_key === $multifactor_key) {
+ $header_text = pht('Add Multi-Factor Auth');
+ $help = $this->newGuidance();
+ $panel->setIsEnrollment(true);
} else {
- $help = id(new PHUIInfoView())
- ->setTitle(pht('Multi-Factor Authentication Configured'))
- ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
- ->setErrors(
- array(
- pht(
- 'You have successfully configured multi-factor authentication '.
- 'for your account.'),
- pht(
- 'You can make adjustments from the Settings panel later.'),
- pht(
- 'When you are ready, %s.',
- phutil_tag(
- 'strong',
- array(),
- phutil_tag(
- 'a',
- array(
- 'href' => '/',
- ),
- pht('continue to Phabricator')))),
- ));
+ $header_text = $panel->getPanelName();
+ $help = null;
}
- $view = array(
- $help,
- $panel,
- );
+ $response = $panel
+ ->setController($this)
+ ->setNavigation($nav)
+ ->processRequest($request);
+
+ if (($response instanceof AphrontResponse) ||
+ ($response instanceof AphrontResponseProducerInterface)) {
+ return $response;
+ }
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addTextCrumb(pht('Add Multi-Factor Auth'))
+ ->setBorder(true);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($header_text);
+
+ $view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setFooter(
+ array(
+ $help,
+ $response,
+ ));
return $this->newPage()
->setTitle(pht('Add Multi-Factor Authentication'))
->setCrumbs($crumbs)
+ ->setNavigation($nav)
->appendChild($view);
}
+ private function loadPanels() {
+ $viewer = $this->getViewer();
+ $preferences = PhabricatorUserPreferences::loadUserPreferences($viewer);
+
+ $panels = PhabricatorSettingsPanel::getAllDisplayPanels();
+ $base_uri = $this->newEnrollBaseURI();
+
+ $result = array();
+ foreach ($panels as $key => $panel) {
+ $panel
+ ->setPreferences($preferences)
+ ->setViewer($viewer)
+ ->setUser($viewer)
+ ->setOverrideURI(urisprintf('%s%s/', $base_uri, $key));
+
+ if (!$panel->isEnabled()) {
+ continue;
+ }
+
+ if (!$panel->isUserPanel()) {
+ continue;
+ }
+
+ if (!$panel->isMultiFactorEnrollmentPanel()) {
+ continue;
+ }
+
+ if (!empty($result[$key])) {
+ throw new Exception(pht(
+ "Two settings panels share the same panel key ('%s'): %s, %s.",
+ $key,
+ get_class($panel),
+ get_class($result[$key])));
+ }
+
+ $result[$key] = $panel;
+ }
+
+ return $result;
+ }
+
+
+ private function newNavigation() {
+ $viewer = $this->getViewer();
+
+ $enroll_uri = $this->newEnrollBaseURI();
+
+ $nav = id(new AphrontSideNavFilterView())
+ ->setBaseURI(new PhutilURI($enroll_uri));
+
+ $multifactor_key = id(new PhabricatorMultiFactorSettingsPanel())
+ ->getPanelKey();
+
+ $nav->addFilter(
+ $multifactor_key,
+ pht('Enroll in MFA'),
+ null,
+ 'fa-exclamation-triangle blue');
+
+ $panels = $this->loadPanels();
+
+ if ($panels) {
+ $nav->addLabel(pht('Settings'));
+ }
+
+ foreach ($panels as $panel_key => $panel) {
+ if ($panel_key === $multifactor_key) {
+ continue;
+ }
+
+ $nav->addFilter(
+ $panel->getPanelKey(),
+ $panel->getPanelName(),
+ null,
+ $panel->getPanelMenuIcon());
+ }
+
+ return $nav;
+ }
+
+ private function newEnrollBaseURI() {
+ return $this->getApplicationURI('enroll/');
+ }
+
+ private function newGuidance() {
+ $viewer = $this->getViewer();
+
+ if ($viewer->getIsEnrolledInMultiFactor()) {
+ $guidance = pht(
+ '{icon check, color="green"} **Setup Complete!**'.
+ "\n\n".
+ 'You have successfully configured multi-factor authentication '.
+ 'for your account.'.
+ "\n\n".
+ 'You can make adjustments from the [[ /settings/ | Settings ]] panel '.
+ 'later.');
+
+ return $this->newDialog()
+ ->setTitle(pht('Multi-Factor Authentication Setup Complete'))
+ ->setWidth(AphrontDialogView::WIDTH_FULL)
+ ->appendChild(new PHUIRemarkupView($viewer, $guidance))
+ ->addCancelButton('/', pht('Continue'));
+ }
+
+ $messages = array();
+
+ $messages[] = pht(
+ 'Before you can use Phabricator, you need to add multi-factor '.
+ 'authentication to your account. Multi-factor authentication helps '.
+ 'secure your account by making it more difficult for attackers to '.
+ 'gain access or take sensitive actions.');
+
+ $view = id(new PHUIInfoView())
+ ->setTitle(pht('Add Multi-Factor Authentication To Your Account'))
+ ->setSeverity(PHUIInfoView::SEVERITY_WARNING)
+ ->setErrors($messages);
+
+ return $view;
+ }
+
}
diff --git a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberController.php b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberController.php
--- a/src/applications/auth/controller/contact/PhabricatorAuthContactNumberController.php
+++ b/src/applications/auth/controller/contact/PhabricatorAuthContactNumberController.php
@@ -3,6 +3,21 @@
abstract class PhabricatorAuthContactNumberController
extends PhabricatorAuthController {
+ // Users may need to access these controllers to enroll in SMS MFA during
+ // account setup.
+
+ public function shouldRequireMultiFactorEnrollment() {
+ return false;
+ }
+
+ public function shouldRequireEnabledUser() {
+ return false;
+ }
+
+ public function shouldRequireEmailVerification() {
+ return false;
+ }
+
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
diff --git a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php
@@ -19,6 +19,10 @@
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
+ public function isMultiFactorEnrollmentPanel() {
+ return true;
+ }
+
public function processRequest(AphrontRequest $request) {
$user = $this->getUser();
$viewer = $request->getUser();
diff --git a/src/applications/settings/panel/PhabricatorLanguageSettingsPanel.php b/src/applications/settings/panel/PhabricatorLanguageSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorLanguageSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorLanguageSettingsPanel.php
@@ -25,4 +25,8 @@
return true;
}
+ public function isMultiFactorEnrollmentPanel() {
+ return true;
+ }
+
}
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
@@ -3,6 +3,8 @@
final class PhabricatorMultiFactorSettingsPanel
extends PhabricatorSettingsPanel {
+ private $isEnrollment;
+
public function getPanelKey() {
return 'multifactor';
}
@@ -19,6 +21,19 @@
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
+ public function isMultiFactorEnrollmentPanel() {
+ return true;
+ }
+
+ public function setIsEnrollment($is_enrollment) {
+ $this->isEnrollment = $is_enrollment;
+ return $this;
+ }
+
+ public function getIsEnrollment() {
+ return $this->isEnrollment;
+ }
+
public function processRequest(AphrontRequest $request) {
if ($request->getExists('new') || $request->getExists('providerPHID')) {
return $this->processNew($request);
@@ -106,13 +121,21 @@
$buttons = array();
+ // If we're enrolling a new account in MFA, provide a small visual hint
+ // that this is the button they want to click.
+ if ($this->getIsEnrollment()) {
+ $add_color = PHUIButtonView::BLUE;
+ } else {
+ $add_color = PHUIButtonView::GREY;
+ }
+
$buttons[] = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-plus')
->setText(pht('Add Auth Factor'))
->setHref($this->getPanelURI('?new=true'))
->setWorkflow(true)
- ->setColor(PHUIButtonView::GREY);
+ ->setColor($add_color);
$buttons[] = id(new PHUIButtonView())
->setTag('a')
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanel.php b/src/applications/settings/panel/PhabricatorSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanel.php
@@ -198,6 +198,17 @@
return false;
}
+ /**
+ * Return true if this panel should be available when enrolling in MFA on
+ * a new account with MFA requiredd.
+ *
+ * @return bool True to allow configuration during MFA enrollment.
+ * @task config
+ */
+ public function isMultiFactorEnrollmentPanel() {
+ return false;
+ }
+
/* -( Panel Implementation )----------------------------------------------- */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 24, 6:49 PM (4 h, 5 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6783702
Default Alt Text
D20008.diff (12 KB)
Attached To
Mode
D20008: Allow users to access some settings at the "Add MFA" account setup roadblock
Attached
Detach File
Event Timeline
Log In to Comment