From 9481b9eff111168db57ae25cfa6a4b7a3967711c Mon Sep 17 00:00:00 2001 From: epriestley Date: Sat, 17 Nov 2018 10:39:25 -0800 Subject: [PATCH] Allow "Can Configure Application" permissions to be configured Summary: Ref T13216. See PHI980. Currently, each application in {nav Applications > X > Configure} has a "Can Configure Application" permission which is hard-coded to "Administrators". There's no technical reason for this, there just hasn't been a great use case for unlocking it. I think when I originally wrote it our protections against locking yourself out of things weren't that great (i.e., it was easier to set the policy to something that prevented you from editing it after the new policy took effect). Our protections are better now. The major goal here is to let installs open up Custom Forms for given applications (mostly Maniphest) to more users, but the other options mostly go hand-in-hand with that. Also, in developer mode, include stack traces for policy exceptions. This makes debugging weird stuff (like the indirect Config application errors here) easier. Test Plan: - Granted "Can Configure Application" for Maniphest to all users. - Edited custom forms as a non-administrator. - Configured Maniphest as a non-administrator. - Installed/uninstalled Maniphest as a non-administrator. - Tried to lock myself out (got an error message). {F6015721} Reviewers: amckinley, joshuaspence Reviewed By: joshuaspence Subscribers: joshuaspence Maniphest Tasks: T13216 Differential Revision: https://secure.phabricator.com/D19822 --- .../PhabricatorPolicyRequestExceptionHandler.php | 12 ++++++++++++ src/applications/base/PhabricatorApplication.php | 2 +- .../config/editor/PhabricatorConfigEditor.php | 7 ++++++- ...habricatorApplicationPolicyChangeTransaction.php | 13 +++++++++++-- .../PhabricatorApplicationUninstallTransaction.php | 8 ++++++-- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php b/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php index cb1dea3533..442cb08f66 100644 --- a/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php +++ b/src/aphront/handler/PhabricatorPolicyRequestExceptionHandler.php @@ -83,6 +83,18 @@ final class PhabricatorPolicyRequestExceptionHandler $dialog->appendList($list); } + // If the install is in developer mode, include a stack trace for the + // exception. When debugging things, it isn't always obvious where a + // policy exception came from and this can make it easier to hunt down + // bugs or improve ambiguous/confusing messaging. + + $is_developer = PhabricatorEnv::getEnvConfig('phabricator.developer-mode'); + if ($is_developer) { + $dialog->appendChild( + id(new AphrontStackTraceView()) + ->setTrace($throwable->getTrace())); + } + if ($request->isAjax()) { $dialog->addCancelButton('/', pht('Close')); } else { diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index e276e035e4..1cabeb0709 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -545,7 +545,7 @@ abstract class PhabricatorApplication case PhabricatorPolicyCapability::CAN_VIEW: return $this->canUninstall(); case PhabricatorPolicyCapability::CAN_EDIT: - return false; + return true; default: $spec = $this->getCustomCapabilitySpecification($capability); return idx($spec, 'edit', true); diff --git a/src/applications/config/editor/PhabricatorConfigEditor.php b/src/applications/config/editor/PhabricatorConfigEditor.php index f776c3ec0c..deccf1ef5c 100644 --- a/src/applications/config/editor/PhabricatorConfigEditor.php +++ b/src/applications/config/editor/PhabricatorConfigEditor.php @@ -118,7 +118,8 @@ final class PhabricatorConfigEditor PhabricatorUser $user, PhabricatorConfigEntry $config_entry, $value, - PhabricatorContentSource $source) { + PhabricatorContentSource $source, + $acting_as_phid = null) { $xaction = id(new PhabricatorConfigTransaction()) ->setTransactionType(PhabricatorConfigTransaction::TYPE_EDIT) @@ -133,6 +134,10 @@ final class PhabricatorConfigEditor ->setContinueOnNoEffect(true) ->setContentSource($source); + if ($acting_as_phid) { + $editor->setActingAsPHID($acting_as_phid); + } + $editor->applyTransactions($config_entry, array($xaction)); } diff --git a/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php b/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php index 91b5c73249..59dfc09486 100644 --- a/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php +++ b/src/applications/meta/xactions/PhabricatorApplicationPolicyChangeTransaction.php @@ -35,11 +35,20 @@ final class PhabricatorApplicationPolicyChangeTransaction $editor = $this->getEditor(); $content_source = $editor->getContentSource(); + + // NOTE: We allow applications to have custom edit policies, but they are + // currently stored in the Config application. The ability to edit Config + // values is always restricted to administrators, today. Empower this + // particular edit to punch through possible stricter policies, so normal + // users can change application configuration if the application allows + // them to do so. + PhabricatorConfigEditor::storeNewValue( - $user, + PhabricatorUser::getOmnipotentUser(), $config_entry, $current_value, - $content_source); + $content_source, + $user->getPHID()); } public function getTitle() { diff --git a/src/applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php b/src/applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php index 12fbc8ebd4..b76e63b5c0 100644 --- a/src/applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php +++ b/src/applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php @@ -43,11 +43,15 @@ final class PhabricatorApplicationUninstallTransaction $editor = $this->getEditor(); $content_source = $editor->getContentSource(); + + // Today, changing config requires "Administrator", but "Can Edit" on + // applications to let you uninstall them may be granted to any user. PhabricatorConfigEditor::storeNewValue( - $user, + PhabricatorUser::getOmnipotentUser(), $config_entry, $list, - $content_source); + $content_source, + $user->getPHID()); } public function getTitle() { -- 2.51.2