@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Config - add an option to lock policy settings

Summary: Fixes T6947

Test Plan:
locked people.create.user and noted the UI only showed a link to the existing policy with no way to edit it.

tried to set the config to all the various bad things and saw helpful error messages telling me what I did wrong.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T6947

Differential Revision: https://secure.phabricator.com/D11358

+90 -11
+2
src/__phutil_library_map__.php
··· 2864 2864 'PhrictionTransactionComment' => 'applications/phriction/storage/PhrictionTransactionComment.php', 2865 2865 'PhrictionTransactionEditor' => 'applications/phriction/editor/PhrictionTransactionEditor.php', 2866 2866 'PhrictionTransactionQuery' => 'applications/phriction/query/PhrictionTransactionQuery.php', 2867 + 'PolicyLockOptionType' => 'applications/policy/config/PolicyLockOptionType.php', 2867 2868 'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php', 2868 2869 'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php', 2869 2870 'PonderAnswerCommentController' => 'applications/ponder/controller/PonderAnswerCommentController.php', ··· 6194 6195 'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment', 6195 6196 'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 6196 6197 'PhrictionTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 6198 + 'PolicyLockOptionType' => 'PhabricatorConfigJSONOptionType', 6197 6199 'PonderAddAnswerView' => 'AphrontView', 6198 6200 'PonderAnswer' => array( 6199 6201 'PonderDAO',
+9 -11
src/applications/meta/controller/PhabricatorApplicationEditController.php
··· 3 3 final class PhabricatorApplicationEditController 4 4 extends PhabricatorApplicationsController { 5 5 6 - private $application; 7 - 8 6 public function shouldRequireAdmin() { 9 7 return true; 10 8 } 11 9 12 - public function willProcessRequest(array $data) { 13 - $this->application = $data['application']; 14 - } 15 - 16 - public function processRequest() { 17 - $request = $this->getRequest(); 10 + public function handleRequest(AphrontRequest $request) { 18 11 $user = $request->getUser(); 12 + $application = $request->getURIData('application'); 19 13 20 14 $application = id(new PhabricatorApplicationQuery()) 21 15 ->setViewer($user) 22 - ->withClasses(array($this->application)) 16 + ->withClasses(array($application)) 23 17 ->requireCapabilities( 24 18 array( 25 19 PhabricatorPolicyCapability::CAN_VIEW, ··· 107 101 $user, 108 102 $config_entry, 109 103 $value, 110 - PhabricatorContentSource::newFromRequest($this->getRequest())); 104 + PhabricatorContentSource::newFromRequest($request)); 111 105 } 112 106 113 107 return id(new AphrontRedirectResponse())->setURI($view_uri); ··· 120 114 $form = id(new AphrontFormView()) 121 115 ->setUser($user); 122 116 117 + $locked_policies = PhabricatorEnv::getEnvConfig('policy.locked'); 118 + $locked_map = array_fill_keys($locked_policies, true); 123 119 foreach ($application->getCapabilities() as $capability) { 124 120 $label = $application->getCapabilityLabel($capability); 125 121 $can_edit = $application->isCapabilityEditable($capability); 122 + $locked = idx($locked_map, $capability); 126 123 $caption = $application->getCapabilityCaption($capability); 127 124 128 - if (!$can_edit) { 125 + if (!$can_edit || $locked) { 129 126 $form->appendChild( 130 127 id(new AphrontFormStaticControl()) 131 128 ->setLabel($label) ··· 135 132 $form->appendChild( 136 133 id(new AphrontFormPolicyControl()) 137 134 ->setUser($user) 135 + ->setDisabled(idx($locked_map, $capability)) 138 136 ->setCapability($capability) 139 137 ->setPolicyObject($application) 140 138 ->setPolicies($policies)
+16
src/applications/policy/config/PhabricatorPolicyConfigOptions.php
··· 12 12 } 13 13 14 14 public function getOptions() { 15 + $policy_locked_type = 'custom:PolicyLockOptionType'; 16 + $policy_locked_example = array( 17 + 'people.create.users' => 'admin',); 18 + $json = new PhutilJSON(); 19 + $policy_locked_example = $json->encodeFormatted($policy_locked_example); 20 + 15 21 return array( 16 22 $this->newOption('policy.allow-public', 'bool', false) 17 23 ->setBoolOptions( ··· 39 45 "With this setting disabled, the 'Public' policy is not ". 40 46 "available, and the most open policy is 'All Users' (which means ". 41 47 "users must have accounts and be logged in to view things).")), 48 + $this->newOption('policy.locked', $policy_locked_type, array()) 49 + ->setSummary(pht( 50 + 'Lock specific application policies so they can not be edited.')) 51 + ->setDescription(pht( 52 + 'Phabricator has application policies which can dictate whether '. 53 + 'users can take certain actions, such as creating new users. '."\n\n". 54 + 'This setting allows for "locking" these policies such that no '. 55 + 'further edits can be made on a per-policy basis.')) 56 + ->addExample($policy_locked_example, 57 + pht('Lock Create User Policy To Admins')), 42 58 ); 43 59 } 44 60
+63
src/applications/policy/config/PolicyLockOptionType.php
··· 1 + <?php 2 + 3 + final class PolicyLockOptionType 4 + extends PhabricatorConfigJSONOptionType { 5 + 6 + public function validateOption(PhabricatorConfigOption $option, $value) { 7 + $capabilities = id(new PhutilSymbolLoader()) 8 + ->setAncestorClass('PhabricatorPolicyCapability') 9 + ->loadObjects(); 10 + $capabilities = mpull($capabilities, null, 'getCapabilityKey'); 11 + 12 + $policy_phids = array(); 13 + foreach ($value as $capability_key => $policy) { 14 + $capability = idx($capabilities, $capability_key); 15 + if (!$capability) { 16 + throw new Exception(pht( 17 + 'Capability "%s" does not exist.', $capability_key)); 18 + } 19 + if (phid_get_type($policy) != 20 + PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) { 21 + $policy_phids[$policy] = $policy; 22 + } else { 23 + try { 24 + $policy_object = PhabricatorPolicyQuery::getGlobalPolicy($policy); 25 + // this exception is not helpful here as its about global policy; 26 + // throw a better exception 27 + } catch (Exception $ex) { 28 + throw new Exception(pht( 29 + 'Capability "%s" has invalid policy "%s".', 30 + $capability_key, 31 + $policy)); 32 + } 33 + } 34 + 35 + if ($policy == PhabricatorPolicies::POLICY_PUBLIC) { 36 + if (!$capability->shouldAllowPublicPolicySetting()) { 37 + throw new Exception(pht( 38 + 'Capability "%s" does not support public policy.', 39 + $capability_key)); 40 + } 41 + } 42 + } 43 + 44 + if ($policy_phids) { 45 + $handles = id(new PhabricatorHandleQuery()) 46 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 47 + ->withPhids($policy_phids) 48 + ->execute(); 49 + $handles = mpull($handles, null, 'getPHID'); 50 + foreach ($value as $capability_key => $policy) { 51 + $handle = $handles[$policy]; 52 + if (!$handle->isComplete()) { 53 + throw new Exception(pht( 54 + 'Capability "%s" has invalid policy "%s"; "%s" does not exist.', 55 + $capability_key, 56 + $policy, 57 + $policy)); 58 + } 59 + } 60 + } 61 + } 62 + 63 + }