Skip to content

Commit a14b82d

Browse files
author
epriestley
committedJun 27, 2017
Move "wild" config types to new code
Summary: Ref T12845. This is the last of the hard-coded types. These are mostly used for values which users don't directly edit, so it's largely OK that they aren't carefully validated. In some cases, it would be good to introduce a separate validator eventually. Test Plan: Edited, deleted and mangled these values via the web UI and CLI. Reviewers: chad, amckinley Reviewed By: amckinley Maniphest Tasks: T12845 Differential Revision: https://secure.phabricator.com/D18164
1 parent ec2af08 commit a14b82d

7 files changed

+104
-60
lines changed
 

‎src/__phutil_library_map__.php

+4
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,7 @@
30103010
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorIteratedMD5PasswordHasherTestCase.php',
30113011
'PhabricatorIteratorFileUploadSource' => 'applications/files/uploadsource/PhabricatorIteratorFileUploadSource.php',
30123012
'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
3013+
'PhabricatorJSONConfigType' => 'applications/config/type/PhabricatorJSONConfigType.php',
30133014
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
30143015
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
30153016
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
@@ -4263,6 +4264,7 @@
42634264
'PhabricatorWebContentSource' => 'infrastructure/contentsource/PhabricatorWebContentSource.php',
42644265
'PhabricatorWebServerSetupCheck' => 'applications/config/check/PhabricatorWebServerSetupCheck.php',
42654266
'PhabricatorWeekStartDaySetting' => 'applications/settings/setting/PhabricatorWeekStartDaySetting.php',
4267+
'PhabricatorWildConfigType' => 'applications/config/type/PhabricatorWildConfigType.php',
42664268
'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php',
42674269
'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
42684270
'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php',
@@ -8348,6 +8350,7 @@
83488350
'PhabricatorIteratedMD5PasswordHasherTestCase' => 'PhabricatorTestCase',
83498351
'PhabricatorIteratorFileUploadSource' => 'PhabricatorFileUploadSource',
83508352
'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
8353+
'PhabricatorJSONConfigType' => 'PhabricatorTextConfigType',
83518354
'PhabricatorJavelinLinter' => 'ArcanistLinter',
83528355
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
83538356
'PhabricatorJumpNavHandler' => 'Phobject',
@@ -9839,6 +9842,7 @@
98399842
'PhabricatorWebContentSource' => 'PhabricatorContentSource',
98409843
'PhabricatorWebServerSetupCheck' => 'PhabricatorSetupCheck',
98419844
'PhabricatorWeekStartDaySetting' => 'PhabricatorSelectSetting',
9845+
'PhabricatorWildConfigType' => 'PhabricatorJSONConfigType',
98429846
'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider',
98439847
'PhabricatorWorker' => 'Phobject',
98449848
'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',

‎src/applications/config/controller/PhabricatorConfigEditController.php

+13-53
Original file line numberDiff line numberDiff line change
@@ -325,40 +325,14 @@ private function readRequest(
325325
$e_value = null;
326326
$errors = array();
327327

328-
329328
if ($option->isCustomType()) {
330329
$info = $option->getCustomObject()->readRequest($option, $request);
331330
list($e_value, $errors, $set_value, $value) = $info;
332331
} else {
333-
$value = $request->getStr('value');
334-
if (!strlen($value)) {
335-
$value = null;
336-
337-
$xaction->setNewValue(
338-
array(
339-
'deleted' => true,
340-
'value' => null,
341-
));
342-
343-
return array($e_value, $errors, $value, $xaction);
344-
}
345-
346-
$type = $option->getType();
347-
$set_value = null;
348-
349-
switch ($type) {
350-
default:
351-
$json = json_decode($value, true);
352-
if ($json === null && strtolower($value) != 'null') {
353-
$e_value = pht('Invalid');
354-
$errors[] = pht(
355-
'The given value must be valid JSON. This means, among '.
356-
'other things, that you must wrap strings in double-quotes.');
357-
} else {
358-
$set_value = $json;
359-
}
360-
break;
361-
}
332+
throw new Exception(
333+
pht(
334+
'Unknown configuration option type "%s".',
335+
$option->getType()));
362336
}
363337

364338
if (!$errors) {
@@ -389,13 +363,12 @@ private function getDisplayValue(
389363
$option,
390364
$entry,
391365
$value);
392-
} else {
393-
$type = $option->getType();
394-
switch ($type) {
395-
default:
396-
return PhabricatorConfigJSON::prettyPrintJSON($value);
397-
}
398366
}
367+
368+
throw new Exception(
369+
pht(
370+
'Unknown configuration option type "%s".',
371+
$option->getType()));
399372
}
400373

401374
private function renderControls(
@@ -417,23 +390,10 @@ private function renderControls(
417390
$display_value,
418391
$e_value);
419392
} else {
420-
$type = $option->getType();
421-
switch ($type) {
422-
default:
423-
$control = id(new AphrontFormTextAreaControl())
424-
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
425-
->setCustomClass('PhabricatorMonospaced')
426-
->setCaption(pht('Enter value in JSON.'));
427-
break;
428-
}
429-
430-
$control
431-
->setLabel(pht('Database Value'))
432-
->setError($e_value)
433-
->setValue($display_value)
434-
->setName('value');
435-
436-
$controls = array($control);
393+
throw new Exception(
394+
pht(
395+
'Unknown configuration option type "%s".',
396+
$option->getType()));
437397
}
438398

439399
return $controls;

‎src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public function execute(PhutilArgumentParser $args) {
7070
throw new PhutilArgumentUsageException($ex->getMessage());
7171
}
7272
} else {
73+
// NOTE: For now, this handles both "wild" values and custom types.
7374
$type = $option->getType();
7475
switch ($type) {
7576
default:

‎src/applications/config/option/PhabricatorApplicationConfigOptions.php

+8-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function validateOption(PhabricatorConfigOption $option, $value) {
2424
if ($type) {
2525
try {
2626
$type->validateStoredValue($option, $value);
27+
$this->didValidateOption($option, $value);
2728
} catch (PhabricatorConfigValidationException $ex) {
2829
throw $ex;
2930
} catch (Exception $ex) {
@@ -32,6 +33,8 @@ public function validateOption(PhabricatorConfigOption $option, $value) {
3233
// configuration and raise an error.
3334
throw new PhabricatorConfigValidationException($ex->getMessage());
3435
}
36+
37+
return;
3538
}
3639

3740
if ($option->isCustomType()) {
@@ -40,12 +43,11 @@ public function validateOption(PhabricatorConfigOption $option, $value) {
4043
} catch (Exception $ex) {
4144
throw new PhabricatorConfigValidationException($ex->getMessage());
4245
}
43-
}
44-
45-
switch ($option->getType()) {
46-
case 'wild':
47-
default:
48-
break;
46+
} else {
47+
throw new Exception(
48+
pht(
49+
'Unknown configuration option type "%s".',
50+
$option->getType()));
4951
}
5052

5153
$this->didValidateOption($option, $value);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
abstract class PhabricatorJSONConfigType
4+
extends PhabricatorTextConfigType {
5+
6+
protected function newCanonicalValue(
7+
PhabricatorConfigOption $option,
8+
$value) {
9+
10+
try {
11+
$value = phutil_json_decode($value);
12+
} catch (Exception $ex) {
13+
throw $this->newException(
14+
pht(
15+
'Value for option "%s" (of type "%s") must be specified in JSON, '.
16+
'but input could not be decoded: %s',
17+
$option->getKey(),
18+
$this->getTypeKey(),
19+
$ex->getMessage()));
20+
}
21+
22+
return $value;
23+
}
24+
25+
protected function newControl(PhabricatorConfigOption $option) {
26+
return id(new AphrontFormTextAreaControl())
27+
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
28+
->setCustomClass('PhabricatorMonospaced')
29+
->setCaption(pht('Enter value in JSON.'));
30+
}
31+
32+
public function newDisplayValue(
33+
PhabricatorConfigOption $option,
34+
$value) {
35+
return PhabricatorConfigJSON::prettyPrintJSON($value);
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
final class PhabricatorWildConfigType
4+
extends PhabricatorJSONConfigType {
5+
6+
const TYPEKEY = 'wild';
7+
8+
protected function newCanonicalValue(
9+
PhabricatorConfigOption $option,
10+
$value) {
11+
12+
$raw_value = $value;
13+
14+
// NOTE: We're significantly more liberal about canonicalizing "wild"
15+
// values than "JSON" values because they're used to deal with some
16+
// unusual edge cases, including situations where old config has been left
17+
// in the database and we aren't sure what type it's supposed to be.
18+
// Accept anything we can decode.
19+
20+
$value = json_decode($raw_value, true);
21+
if ($value === null && $raw_value != 'null') {
22+
throw $this->newException(
23+
pht(
24+
'Value for option "%s" (of type "%s") must be specified in JSON, '.
25+
'but input could not be decoded. (Did you forget to quote a string?)',
26+
$option->getKey(),
27+
$this->getTypeKey()));
28+
}
29+
30+
return $value;
31+
}
32+
33+
public function validateStoredValue(
34+
PhabricatorConfigOption $option,
35+
$value) {
36+
return;
37+
}
38+
39+
}

‎src/applications/people/config/PhabricatorUserConfigOptions.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function getOptions() {
4343
$this->newOption('user.fields', $custom_field_type, $default)
4444
->setCustomData(id(new PhabricatorUser())->getCustomFieldBaseClass())
4545
->setDescription(pht('Select and reorder user profile fields.')),
46-
$this->newOption('user.custom-field-definitions', 'map', array())
46+
$this->newOption('user.custom-field-definitions', 'wild', array())
4747
->setDescription(pht('Add new simple fields to user profiles.')),
4848
$this->newOption('user.require-real-name', 'bool', true)
4949
->setDescription(pht('Always require real name for user profiles.'))

0 commit comments

Comments
 (0)
Failed to load comments.