Skip to content

Commit e4525f9

Browse files
author
epriestley
committed
Provide some diagnostic tools for examining inbound and outbound mail
Summary: We can't show this stuff on the web UI because it has password reset links and private reply-to addresses, but we can provide easier CLI tools than "root around in the database". Land a rough version of `bin/mail show-inbound` and `bin/mail show-outbound`. Test Plan: Used both commands to examine mail from the CLI. Reviewers: btrahan Reviewed By: btrahan CC: tido, euresti, aran Differential Revision: https://secure.phabricator.com/D5963
1 parent c5e7222 commit e4525f9

File tree

4 files changed

+187
-0
lines changed

4 files changed

+187
-0
lines changed

scripts/mail/manage_mail.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
$workflows = array(
1818
new PhabricatorMailManagementResendWorkflow(),
1919
new PhutilHelpArgumentWorkflow(),
20+
new PhabricatorMailManagementShowOutboundWorkflow(),
21+
new PhabricatorMailManagementShowInboundWorkflow(),
2022
);
2123

2224
$args->parseWorkflows($workflows);

src/__phutil_library_map__.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,8 @@
10881088
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
10891089
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
10901090
'PhabricatorMailManagementResendWorkflow' => 'applications/metamta/management/PhabricatorMailManagementResendWorkflow.php',
1091+
'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
1092+
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
10911093
'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
10921094
'PhabricatorMailReceiver' => 'applications/metamta/receiver/PhabricatorMailReceiver.php',
10931095
'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php',
@@ -2846,6 +2848,8 @@
28462848
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
28472849
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
28482850
'PhabricatorMailManagementResendWorkflow' => 'PhabricatorSearchManagementWorkflow',
2851+
'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorSearchManagementWorkflow',
2852+
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorSearchManagementWorkflow',
28492853
'PhabricatorMailManagementWorkflow' => 'PhutilArgumentWorkflow',
28502854
'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase',
28512855
'PhabricatorMailingListsController' => 'PhabricatorController',
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
final class PhabricatorMailManagementShowInboundWorkflow
4+
extends PhabricatorSearchManagementWorkflow {
5+
6+
protected function didConstruct() {
7+
$this
8+
->setName('show-inbound')
9+
->setSynopsis('Show diagnostic details about inbound mail.')
10+
->setExamples(
11+
"**show-inbound** --id 1 --id 2")
12+
->setArguments(
13+
array(
14+
array(
15+
'name' => 'id',
16+
'param' => 'id',
17+
'help' => 'Show details about inbound mail with given ID.',
18+
'repeat' => true,
19+
),
20+
));
21+
}
22+
23+
public function execute(PhutilArgumentParser $args) {
24+
$console = PhutilConsole::getConsole();
25+
26+
$ids = $args->getArg('id');
27+
if (!$ids) {
28+
throw new PhutilArgumentUsageException(
29+
"Use the '--id' flag to specify one or more messages to show.");
30+
}
31+
32+
$messages = id(new PhabricatorMetaMTAReceivedMail())->loadAllWhere(
33+
'id IN (%Ld)',
34+
$ids);
35+
36+
if ($ids) {
37+
$ids = array_fuse($ids);
38+
$missing = array_diff_key($ids, $messages);
39+
if ($missing) {
40+
throw new PhutilArgumentUsageException(
41+
"Some specified messages do not exist: ".
42+
implode(', ', array_keys($missing)));
43+
}
44+
}
45+
46+
$last_key = last_key($messages);
47+
foreach ($messages as $message_key => $message) {
48+
$info = array();
49+
50+
$info[] = pht('PROPERTIES');
51+
$info[] = pht('ID: %d', $message->getID());
52+
$info[] = pht('Status: %s', $message->getStatus());
53+
$info[] = pht('Related PHID: %s', $message->getRelatedPHID());
54+
$info[] = pht('Author PHID: %s', $message->getAuthorPHID());
55+
$info[] = pht('Message ID Hash: %s', $message->getMessageIDHash());
56+
57+
$info[] = null;
58+
$info[] = pht('HEADERS');
59+
foreach ($message->getHeaders() as $key => $value) {
60+
$info[] = pht('%s: %s', $key, $value);
61+
}
62+
63+
$bodies = $message->getBodies();
64+
65+
$last_body = last_key($bodies);
66+
67+
$info[] = null;
68+
$info[] = pht('BODIES');
69+
foreach ($bodies as $key => $value) {
70+
$info[] = pht('Body "%s"', $key);
71+
$info[] = $value;
72+
if ($key != $last_body) {
73+
$info[] = null;
74+
}
75+
}
76+
77+
$attachments = $message->getAttachments();
78+
79+
$info[] = null;
80+
$info[] = pht('ATTACHMENTS');
81+
if (!$attachments) {
82+
$info[] = pht('No attachments.');
83+
} else {
84+
foreach ($attachments as $attachment) {
85+
$info[] = pht('File PHID: %s', $attachment);
86+
}
87+
}
88+
89+
$console->writeOut("%s\n", implode("\n", $info));
90+
91+
if ($message_key != $last_key) {
92+
$console->writeOut("\n%s\n\n", str_repeat('-', 80));
93+
}
94+
}
95+
}
96+
97+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
final class PhabricatorMailManagementShowOutboundWorkflow
4+
extends PhabricatorSearchManagementWorkflow {
5+
6+
protected function didConstruct() {
7+
$this
8+
->setName('show-outbound')
9+
->setSynopsis('Show diagnostic details about outbound mail.')
10+
->setExamples(
11+
"**show-outbound** --id 1 --id 2")
12+
->setArguments(
13+
array(
14+
array(
15+
'name' => 'id',
16+
'param' => 'id',
17+
'help' => 'Show details about outbound mail with given ID.',
18+
'repeat' => true,
19+
),
20+
));
21+
}
22+
23+
public function execute(PhutilArgumentParser $args) {
24+
$console = PhutilConsole::getConsole();
25+
26+
$ids = $args->getArg('id');
27+
if (!$ids) {
28+
throw new PhutilArgumentUsageException(
29+
"Use the '--id' flag to specify one or more messages to show.");
30+
}
31+
32+
$messages = id(new PhabricatorMetaMTAMail())->loadAllWhere(
33+
'id IN (%Ld)',
34+
$ids);
35+
36+
if ($ids) {
37+
$ids = array_fuse($ids);
38+
$missing = array_diff_key($ids, $messages);
39+
if ($missing) {
40+
throw new PhutilArgumentUsageException(
41+
"Some specified messages do not exist: ".
42+
implode(', ', array_keys($missing)));
43+
}
44+
}
45+
46+
$last_key = last_key($messages);
47+
foreach ($messages as $message_key => $message) {
48+
$info = array();
49+
50+
$info[] = pht('PROPERTIES');
51+
$info[] = pht('ID: %d', $message->getID());
52+
$info[] = pht('Status: %s', $message->getStatus());
53+
$info[] = pht('Retry Count: %s', $message->getRetryCount());
54+
$info[] = pht('Next Retry: %s', $message->getNextRetry());
55+
$info[] = pht('Related PHID: %s', $message->getRelatedPHID());
56+
$info[] = pht('Message: %s', $message->getMessage());
57+
58+
$info[] = null;
59+
$info[] = pht('PARAMETERS');
60+
foreach ($message->getParameters() as $key => $value) {
61+
if ($key == 'body') {
62+
continue;
63+
}
64+
65+
if (!is_scalar($value)) {
66+
$value = json_encode($value);
67+
}
68+
69+
$info[] = pht('%s: %s', $key, $value);
70+
}
71+
72+
$info[] = null;
73+
$info[] = pht('BODY');
74+
$info[] = $message->getBody();
75+
76+
$console->writeOut('%s', implode("\n", $info));
77+
78+
if ($message_key != $last_key) {
79+
$console->writeOut("\n%s\n\n", str_repeat('-', 80));
80+
}
81+
}
82+
}
83+
84+
}

0 commit comments

Comments
 (0)