Differential D15703 Diff 37833 src/applications/notification/config/PhabricatorNotificationServersConfigOptionType.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/notification/config/PhabricatorNotificationServersConfigOptionType.php
- This file was added.
<?php | |||||
final class PhabricatorNotificationServersConfigOptionType | |||||
extends PhabricatorConfigJSONOptionType { | |||||
public function validateOption(PhabricatorConfigOption $option, $value) { | |||||
if (!is_array($value)) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration is not valid: value must be a '. | |||||
'list of servers')); | |||||
} | |||||
foreach ($value as $index => $spec) { | |||||
if (!is_array($spec)) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration is not valid: each entry in '. | |||||
'the list must be a dictionary describing a service, but '. | |||||
'the value with index "%s" is not a dictionary.', | |||||
$index)); | |||||
} | |||||
} | |||||
$has_admin = false; | |||||
$has_client = false; | |||||
$map = array(); | |||||
foreach ($value as $index => $spec) { | |||||
try { | |||||
PhutilTypeSpec::checkMap( | |||||
$spec, | |||||
array( | |||||
'type' => 'string', | |||||
'host' => 'string', | |||||
'port' => 'int', | |||||
'protocol' => 'string', | |||||
'path' => 'optional string', | |||||
'disabled' => 'optional bool', | |||||
)); | |||||
} catch (Exception $ex) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration has an invalid service '. | |||||
'specification (at index "%s"): %s.', | |||||
$index, | |||||
$ex->getMessage())); | |||||
} | |||||
$type = $spec['type']; | |||||
$host = $spec['host']; | |||||
$port = $spec['port']; | |||||
$protocol = $spec['protocol']; | |||||
$disabled = idx($spec, 'disabled'); | |||||
switch ($type) { | |||||
case 'admin': | |||||
if (!$disabled) { | |||||
$has_admin = true; | |||||
} | |||||
break; | |||||
case 'client': | |||||
if (!$disabled) { | |||||
$has_client = true; | |||||
} | |||||
break; | |||||
default: | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration describes an invalid '. | |||||
'host ("%s", at index "%s") with an unrecognized type ("%s"). '. | |||||
'Valid types are "%s" or "%s".', | |||||
$host, | |||||
$index, | |||||
$type, | |||||
'admin', | |||||
'client')); | |||||
} | |||||
switch ($protocol) { | |||||
case 'http': | |||||
case 'https': | |||||
break; | |||||
default: | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration describes an invalid '. | |||||
'host ("%s", at index "%s") with an invalid protocol ("%s"). '. | |||||
'Valid protocols are "%s" or "%s".', | |||||
$host, | |||||
$index, | |||||
$protocol, | |||||
'http', | |||||
'https')); | |||||
} | |||||
$path = idx($spec, 'path'); | |||||
if ($type == 'admin' && strlen($path)) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration describes an invalid host '. | |||||
'("%s", at index "%s"). This is an "admin" service but it has a '. | |||||
'"path" property. This property is only valid for "client" '. | |||||
'services.')); | |||||
} | |||||
// We can't guarantee that you didn't just give the same host two | |||||
// different names in DNS, but this check can catch silly copy/paste | |||||
// mistakes. | |||||
$key = "{$host}:{$port}"; | |||||
if (isset($map[$key])) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration is invalid: it describes the '. | |||||
'same host and port ("%s") multiple times. Each host and port '. | |||||
'combination should appear only once in the list.', | |||||
$key)); | |||||
} | |||||
$map[$key] = true; | |||||
} | |||||
if ($value) { | |||||
if (!$has_admin) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration is invalid: it does not '. | |||||
'specify any enabled servers with type "admin". Notifications '. | |||||
'require at least one active "admin" server.')); | |||||
} | |||||
if (!$has_client) { | |||||
throw new Exception( | |||||
pht( | |||||
'Notification server configuration is invalid: it does not '. | |||||
'specify any enabled servers with type "client". Notifications '. | |||||
'require at least one active "client" server.')); | |||||
} | |||||
} | |||||
} | |||||
} |