From 70b474e550b7aab3b0a7d25d05953c8f19b029d1 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Jan 2019 09:08:14 -0800 Subject: [PATCH] Allow MFA enrollment guidance to be customized Summary: Depends on D20039. Ref T13242. If installs want users to install a specific application, reference particular help, etc., let them customize the MFA enrollment message so they can make it say "if you have issues, see this walkthrough on the corporate wiki" or whatever. Test Plan: {F6164340} {F6164341} {F6164342} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13242 Differential Revision: https://secure.phabricator.com/D20043 --- src/__phutil_library_map__.php | 4 + .../PhabricatorAuthApplication.php | 2 + ...torAuthFactorProviderMessageController.php | 84 +++++++++++++++++++ ...icatorAuthFactorProviderViewController.php | 18 ++++ .../storage/PhabricatorAuthFactorProvider.php | 8 ++ ...FactorProviderEnrollMessageTransaction.php | 39 +++++++++ .../PhabricatorMultiFactorSettingsPanel.php | 7 +- 7 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderMessageController.php create mode 100644 src/applications/auth/xaction/PhabricatorAuthFactorProviderEnrollMessageTransaction.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f789302450..f2da0e63a6 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2235,8 +2235,10 @@ phutil_register_library_map(array( 'PhabricatorAuthFactorProviderEditController' => 'applications/auth/controller/mfa/PhabricatorAuthFactorProviderEditController.php', 'PhabricatorAuthFactorProviderEditEngine' => 'applications/auth/editor/PhabricatorAuthFactorProviderEditEngine.php', 'PhabricatorAuthFactorProviderEditor' => 'applications/auth/editor/PhabricatorAuthFactorProviderEditor.php', + 'PhabricatorAuthFactorProviderEnrollMessageTransaction' => 'applications/auth/xaction/PhabricatorAuthFactorProviderEnrollMessageTransaction.php', 'PhabricatorAuthFactorProviderListController' => 'applications/auth/controller/mfa/PhabricatorAuthFactorProviderListController.php', 'PhabricatorAuthFactorProviderMFAEngine' => 'applications/auth/engine/PhabricatorAuthFactorProviderMFAEngine.php', + 'PhabricatorAuthFactorProviderMessageController' => 'applications/auth/controller/mfa/PhabricatorAuthFactorProviderMessageController.php', 'PhabricatorAuthFactorProviderNameTransaction' => 'applications/auth/xaction/PhabricatorAuthFactorProviderNameTransaction.php', 'PhabricatorAuthFactorProviderQuery' => 'applications/auth/query/PhabricatorAuthFactorProviderQuery.php', 'PhabricatorAuthFactorProviderStatus' => 'applications/auth/constants/PhabricatorAuthFactorProviderStatus.php', @@ -7975,8 +7977,10 @@ phutil_register_library_map(array( 'PhabricatorAuthFactorProviderEditController' => 'PhabricatorAuthFactorProviderController', 'PhabricatorAuthFactorProviderEditEngine' => 'PhabricatorEditEngine', 'PhabricatorAuthFactorProviderEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhabricatorAuthFactorProviderEnrollMessageTransaction' => 'PhabricatorAuthFactorProviderTransactionType', 'PhabricatorAuthFactorProviderListController' => 'PhabricatorAuthProviderController', 'PhabricatorAuthFactorProviderMFAEngine' => 'PhabricatorEditEngineMFAEngine', + 'PhabricatorAuthFactorProviderMessageController' => 'PhabricatorAuthFactorProviderController', 'PhabricatorAuthFactorProviderNameTransaction' => 'PhabricatorAuthFactorProviderTransactionType', 'PhabricatorAuthFactorProviderQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorAuthFactorProviderStatus' => 'Phobject', diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php index a9ab3be181..df86595b46 100644 --- a/src/applications/auth/application/PhabricatorAuthApplication.php +++ b/src/applications/auth/application/PhabricatorAuthApplication.php @@ -95,6 +95,8 @@ final class PhabricatorAuthApplication extends PhabricatorApplication { 'PhabricatorAuthFactorProviderEditController', '(?P[1-9]\d*)/' => 'PhabricatorAuthFactorProviderViewController', + 'message/(?P[1-9]\d*)/' => + 'PhabricatorAuthFactorProviderMessageController', ), 'message/' => array( diff --git a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderMessageController.php b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderMessageController.php new file mode 100644 index 0000000000..563ee39931 --- /dev/null +++ b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderMessageController.php @@ -0,0 +1,84 @@ +requireApplicationCapability( + AuthManageProvidersCapability::CAPABILITY); + + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); + + $provider = id(new PhabricatorAuthFactorProviderQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$provider) { + return new Aphront404Response(); + } + + $cancel_uri = $provider->getURI(); + $enroll_key = + PhabricatorAuthFactorProviderEnrollMessageTransaction::TRANSACTIONTYPE; + + $message = $provider->getEnrollMessage(); + + if ($request->isFormOrHisecPost()) { + $message = $request->getStr('message'); + + $xactions = array(); + + $xactions[] = id(new PhabricatorAuthFactorProviderTransaction()) + ->setTransactionType($enroll_key) + ->setNewValue($message); + + $editor = id(new PhabricatorAuthFactorProviderEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->setCancelURI($cancel_uri); + + $editor->applyTransactions($provider, $xactions); + + return id(new AphrontRedirectResponse())->setURI($cancel_uri); + } + + $default_message = $provider->getEnrollDescription($viewer); + $default_message = new PHUIRemarkupView($viewer, $default_message); + + $form = id(new AphrontFormView()) + ->setViewer($viewer) + ->appendRemarkupInstructions( + pht( + 'When users add a factor for this provider, they are given this '. + 'enrollment guidance by default:')) + ->appendControl( + id(new AphrontFormMarkupControl()) + ->setLabel(pht('Default Message')) + ->setValue($default_message)) + ->appendRemarkupInstructions( + pht( + 'You may optionally customize the enrollment message users are '. + 'presented with by providing a replacement message below:')) + ->appendControl( + id(new PhabricatorRemarkupControl()) + ->setLabel(pht('Custom Message')) + ->setName('message') + ->setValue($message)); + + return $this->newDialog() + ->setTitle(pht('Change Enroll Message')) + ->setWidth(AphrontDialogView::WIDTH_FORM) + ->appendForm($form) + ->addCancelButton($cancel_uri) + ->addSubmitButton(pht('Save')); + } + +} diff --git a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php index 3047c8714d..1dac49bcf9 100644 --- a/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php +++ b/src/applications/auth/controller/mfa/PhabricatorAuthFactorProviderViewController.php @@ -81,6 +81,16 @@ final class PhabricatorAuthFactorProviderViewController pht('Factor Type'), $provider->getFactor()->getFactorName()); + + $custom_enroll = $provider->getEnrollMessage(); + if (strlen($custom_enroll)) { + $view->addSectionHeader( + pht('Custom Enroll Message'), + PHUIPropertyListView::ICON_SUMMARY); + $view->addTextContent( + new PHUIRemarkupView($viewer, $custom_enroll)); + } + return $view; } @@ -103,6 +113,14 @@ final class PhabricatorAuthFactorProviderViewController ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); + $curtain->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Customize Enroll Message')) + ->setIcon('fa-commenting-o') + ->setHref($this->getApplicationURI("mfa/message/{$id}/")) + ->setDisabled(!$can_edit) + ->setWorkflow(true)); + return $curtain; } diff --git a/src/applications/auth/storage/PhabricatorAuthFactorProvider.php b/src/applications/auth/storage/PhabricatorAuthFactorProvider.php index 79acd4f23e..2213535dff 100644 --- a/src/applications/auth/storage/PhabricatorAuthFactorProvider.php +++ b/src/applications/auth/storage/PhabricatorAuthFactorProvider.php @@ -57,6 +57,14 @@ final class PhabricatorAuthFactorProvider return $this; } + public function getEnrollMessage() { + return $this->getAuthFactorProviderProperty('enroll-message'); + } + + public function setEnrollMessage($message) { + return $this->setAuthFactorProviderProperty('enroll-message', $message); + } + public function attachFactor(PhabricatorAuthFactor $factor) { $this->factor = $factor; return $this; diff --git a/src/applications/auth/xaction/PhabricatorAuthFactorProviderEnrollMessageTransaction.php b/src/applications/auth/xaction/PhabricatorAuthFactorProviderEnrollMessageTransaction.php new file mode 100644 index 0000000000..d6d26143c1 --- /dev/null +++ b/src/applications/auth/xaction/PhabricatorAuthFactorProviderEnrollMessageTransaction.php @@ -0,0 +1,39 @@ +getEnrollMessage(); + } + + public function applyInternalEffects($object, $value) { + $object->setEnrollMessage($value); + } + + public function getTitle() { + return pht( + '%s updated the enroll message.', + $this->renderAuthor()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO ENROLL MESSAGE'); + } + + public function newChangeDetailView() { + $viewer = $this->getViewer(); + + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) + ->setViewer($viewer) + ->setOldText($this->getOldValue()) + ->setNewText($this->getNewValue()); + } + +} diff --git a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php index 4da09dd324..6809b51334 100644 --- a/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php @@ -256,13 +256,16 @@ final class PhabricatorMultiFactorSettingsPanel // sometimes requires us to push a challenge to them as a side effect (for // example, with SMS). if (!$request->isFormPost() || !$request->getBool('mfa.start')) { - $description = $selected_provider->getEnrollDescription($viewer); + $enroll = $selected_provider->getEnrollMessage(); + if (!strlen($enroll)) { + $enroll = $selected_provider->getEnrollDescription($viewer); + } return $this->newDialog() ->addHiddenInput('providerPHID', $selected_provider->getPHID()) ->addHiddenInput('mfa.start', 1) ->setTitle(pht('Add Authentication Factor')) - ->appendChild(new PHUIRemarkupView($viewer, $description)) + ->appendChild(new PHUIRemarkupView($viewer, $enroll)) ->addCancelButton($cancel_uri) ->addSubmitButton($selected_provider->getEnrollButtonText($viewer)); } -- 2.51.2