Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php
12256 views
1
<?php
2
3
final class PhabricatorMailManagementReceiveTestWorkflow
4
extends PhabricatorMailManagementWorkflow {
5
6
protected function didConstruct() {
7
$this
8
->setName('receive-test')
9
->setSynopsis(
10
pht(
11
'Simulate receiving mail. This is primarily useful if you are '.
12
'developing new mail receivers.'))
13
->setExamples(
14
'**receive-test** --as alincoln --to D123 < body.txt')
15
->setArguments(
16
array(
17
array(
18
'name' => 'as',
19
'param' => 'user',
20
'help' => pht('Act as the specified user.'),
21
),
22
array(
23
'name' => 'from',
24
'param' => 'email',
25
'help' => pht('Simulate mail delivery "From:" the given user.'),
26
),
27
array(
28
'name' => 'to',
29
'param' => 'object',
30
'help' => pht('Simulate mail delivery "To:" the given object.'),
31
),
32
array(
33
'name' => 'cc',
34
'param' => 'address',
35
'help' => pht('Simulate a mail delivery "Cc:" address.'),
36
'repeat' => true,
37
),
38
));
39
}
40
41
public function execute(PhutilArgumentParser $args) {
42
$viewer = $this->getViewer();
43
$console = PhutilConsole::getConsole();
44
45
$to = $args->getArg('to');
46
if (!$to) {
47
throw new PhutilArgumentUsageException(
48
pht(
49
"Use '%s' to specify the receiving object or email address.",
50
'--to'));
51
}
52
53
$to_application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
54
->setViewer($this->getViewer())
55
->withAddresses(array($to))
56
->executeOne();
57
58
$as = $args->getArg('as');
59
if (!$as && $to_application_email) {
60
$default_phid = $to_application_email->getConfigValue(
61
PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR);
62
if ($default_phid) {
63
$default_user = id(new PhabricatorPeopleQuery())
64
->setViewer($this->getViewer())
65
->withPHIDs(array($default_phid))
66
->executeOne();
67
if ($default_user) {
68
$as = $default_user->getUsername();
69
}
70
}
71
}
72
73
if (!$as) {
74
throw new PhutilArgumentUsageException(
75
pht("Use '--as' to specify the acting user."));
76
}
77
78
$user = id(new PhabricatorPeopleQuery())
79
->setViewer($this->getViewer())
80
->withUsernames(array($as))
81
->executeOne();
82
if (!$user) {
83
throw new PhutilArgumentUsageException(
84
pht("No such user '%s' exists.", $as));
85
}
86
87
88
$from = $args->getArg('from');
89
if (!$from) {
90
$from = $user->loadPrimaryEmail()->getAddress();
91
}
92
93
$cc = $args->getArg('cc');
94
95
$console->writeErr("%s\n", pht('Reading message body from stdin...'));
96
$body = file_get_contents('php://stdin');
97
98
$received = new PhabricatorMetaMTAReceivedMail();
99
$header_content = array(
100
'Message-ID' => Filesystem::readRandomCharacters(12),
101
'From' => $from,
102
'Cc' => implode(', ', $cc),
103
);
104
105
if (preg_match('/.+@.+/', $to)) {
106
$header_content['to'] = $to;
107
} else {
108
109
// We allow the user to use an object name instead of a real address
110
// as a convenience. To build the mail, we build a similar message and
111
// look for a receiver which will accept it.
112
113
// In the general case, mail may be processed by multiple receivers,
114
// but mail to objects only ever has one receiver today.
115
116
$pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
117
118
$raw_target = $to.'+1+'.$pseudohash;
119
$target = new PhutilEmailAddress($raw_target.'@local.cli');
120
121
$pseudomail = id(new PhabricatorMetaMTAReceivedMail())
122
->setHeaders(
123
array(
124
'to' => $raw_target,
125
));
126
127
$receivers = id(new PhutilClassMapQuery())
128
->setAncestorClass('PhabricatorMailReceiver')
129
->setFilterMethod('isEnabled')
130
->execute();
131
132
$receiver = null;
133
foreach ($receivers as $possible_receiver) {
134
$possible_receiver = id(clone $possible_receiver)
135
->setViewer($viewer)
136
->setSender($user);
137
138
if (!$possible_receiver->canAcceptMail($pseudomail, $target)) {
139
continue;
140
}
141
$receiver = $possible_receiver;
142
break;
143
}
144
145
if (!$receiver) {
146
throw new Exception(
147
pht("No configured mail receiver can accept mail to '%s'.", $to));
148
}
149
150
if (!($receiver instanceof PhabricatorObjectMailReceiver)) {
151
$class = get_class($receiver);
152
throw new Exception(
153
pht(
154
"Receiver '%s' accepts mail to '%s', but is not a ".
155
"subclass of PhabricatorObjectMailReceiver.",
156
$class,
157
$to));
158
}
159
160
$object = $receiver->loadMailReceiverObject($to, $user);
161
if (!$object) {
162
throw new Exception(pht("No such object '%s'!", $to));
163
}
164
165
$mail_key = PhabricatorMetaMTAMailProperties::loadMailKey($object);
166
167
$hash = PhabricatorObjectMailReceiver::computeMailHash(
168
$mail_key,
169
$user->getPHID());
170
171
$header_content['to'] = $to.'+'.$user->getID().'+'.$hash.'@test.com';
172
}
173
174
$received->setHeaders($header_content);
175
$received->setBodies(
176
array(
177
'text' => $body,
178
));
179
180
$received->save();
181
$received->processReceivedMail();
182
183
$console->writeErr(
184
"%s\n\n phabricator/ $ ./bin/mail show-inbound --id %d\n\n",
185
pht('Mail received! You can view details by running this command:'),
186
$received->getID());
187
}
188
189
}
190
191