Passed
Push — metrics ( 091324...ec38a1 )
by Simon
03:57 queued 13s
created

IrcNotificationHelper::userSuspended()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\Helpers;
11
12
use Exception;
13
use PhpAmqpLib\Connection\AMQPConnectionConfig;
14
use PhpAmqpLib\Connection\AMQPConnectionFactory;
15
use PhpAmqpLib\Message\AMQPMessage;
16
use Waca\DataObjects\Ban;
17
use Waca\DataObjects\Comment;
18
use Waca\DataObjects\Domain;
19
use Waca\DataObjects\EmailTemplate;
20
use Waca\DataObjects\Request;
21
use Waca\DataObjects\RequestQueue;
22
use Waca\DataObjects\User;
23
use Waca\DataObjects\WelcomeTemplate;
24
use Waca\ExceptionHandler;
25
use Waca\IrcColourCode;
26
use Waca\PdoDatabase;
27
use Waca\SiteConfiguration;
28
29
/**
30
 * Class IrcNotificationHelper
31
 * @package Waca\Helpers
32
 */
33
class IrcNotificationHelper
34
{
35
    /** @var bool $notificationsEnabled */
36
    private $notificationsEnabled;
37
    /** @var User $currentUser */
38
    private $currentUser;
39
    /** @var string $instanceName */
40
    private $instanceName;
41
    /** @var string */
42
    private $baseUrl;
43
    /** @var SiteConfiguration */
44
    private $siteConfiguration;
45
    /** @var PdoDatabase */
46
    private $primaryDatabase;
47
48
    /**
49
     * IrcNotificationHelper constructor.
50
     *
51
     * @param SiteConfiguration $siteConfiguration
52
     * @param PdoDatabase       $primaryDatabase
53
     */
54
    public function __construct(
55
        SiteConfiguration $siteConfiguration,
56
        PdoDatabase $primaryDatabase
57
    ) {
58
        $this->siteConfiguration = $siteConfiguration;
59
        $this->primaryDatabase = $primaryDatabase;
60
61
        $this->notificationsEnabled = $siteConfiguration->getIrcNotificationsEnabled();
62
        $this->instanceName = $siteConfiguration->getIrcNotificationsInstance();
63
        $this->baseUrl = $siteConfiguration->getBaseUrl();
64
65
        $this->currentUser = User::getCurrent($primaryDatabase);
66
    }
67
68
    /**
69
     * Send a notification
70
     *
71
     * This method does some *basic* filtering for IRC safety, and then delivers the message to an AMQP queue manager.
72
     * It is the responsibility of the queue manager and consumer to handle message delivery to IRC, message routing to
73
     * the correct channel, and message expiry.
74
     *
75
     * It's also arguably the responsibility of the consumer to ensure the message is *safe* for delivery to IRC.
76
     *
77
     * As of Feb 2022, the message consumer is stwalkerster's IRC bot Helpmebot.
78
     *
79
     * @param string $message The text to send
80
     */
81
    protected function send($message)
82
    {
83
        $instanceName = $this->instanceName;
84
85
        if (!$this->notificationsEnabled) {
86
            return;
87
        }
88
89
        $blacklist = array("DCC", "CCTP", "PRIVMSG");
90
        $message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91
92
        $msg = $message;
93
        if ($instanceName !== null && mb_strlen($instanceName) > 0) {
94
            $msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
95
        }
96
97
        // FIXME: domains!
98
        /** @var Domain $domain */
99
        $domain = Domain::getById(1, $this->primaryDatabase);
100
101
        try {
102
            $amqpSiteConfig = $this->siteConfiguration->getAmqpConfiguration();
103
104
            $amqpConnectionConfig = new AMQPConnectionConfig();
105
            $amqpConnectionConfig->setHost($amqpSiteConfig['host']);
106
            $amqpConnectionConfig->setPort($amqpSiteConfig['port']);
107
            $amqpConnectionConfig->setUser($amqpSiteConfig['user']);
108
            $amqpConnectionConfig->setPassword($amqpSiteConfig['password']);
109
            $amqpConnectionConfig->setVhost($amqpSiteConfig['vhost']);
110
111
            if ($amqpSiteConfig['tls']) {
112
                $amqpConnectionConfig->setIsSecure(true);
113
                $amqpConnectionConfig->setSslVerify(true);
114
            }
115
            else {
116
                $amqpConnectionConfig->setIsSecure(false);
117
            }
118
119
            $connection = AMQPConnectionFactory::create($amqpConnectionConfig);
120
            $channel = $connection->channel();
121
122
            $msg = new AMQPMessage(substr($msg, 0, 512));
123
            $msg->set('user_id', $amqpSiteConfig['user']);
124
            $msg->set('app_id', $this->siteConfiguration->getUserAgent());
125
            $msg->set('content_type', 'text/plain');
126
            
127
            $channel->basic_publish($msg, $amqpSiteConfig['exchange'], $domain->getNotificationTarget());
128
            $channel->close();
129
        }
130
        catch (Exception $ex) {
131
            // OK, so we failed to send the notification - that db might be down?
132
            // This is non-critical, so silently fail.
133
            ExceptionHandler::logExceptionToDisk($ex, $this->siteConfiguration);
134
135
            // Disable notifications for remainder of request.
136
            $this->notificationsEnabled = false;
137
        }
138
    }
139
140
    #region user management
141
142
    /**
143
     * send a new user notification
144
     *
145
     * @param User $user
146
     */
147
    public function userNew(User $user)
148
    {
149
        $this->send("New user: {$user->getUsername()}");
150
    }
151
152
    /**
153
     * send an approved notification
154
     *
155
     * @param User $user
156
     */
157
    public function userApproved(User $user)
158
    {
159
        $this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
160
    }
161
162
    /**
163
     * send a declined notification
164
     *
165
     * @param User   $user
166
     * @param string $reason the reason the user was declined
167
     */
168
    public function userDeclined(User $user, $reason)
169
    {
170
        $this->send("{$user->getUsername()} declined by " . $this->currentUser->getUsername() . " ($reason)");
171
    }
172
173
    /**
174
     * send a suspended notification
175
     *
176
     * @param User   $user
177
     * @param string $reason The reason the user has been suspended
178
     */
179
    public function userSuspended(User $user, $reason)
180
    {
181
        $this->send("{$user->getUsername()} suspended by " . $this->currentUser->getUsername() . " ($reason)");
182
    }
183
184
    /**
185
     * Send a preference change notification
186
     *
187
     * @param User $user
188
     */
189
    public function userPrefChange(User $user)
190
    {
191
        $this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
192
    }
193
194
    /**
195
     * Send a user renamed notification
196
     *
197
     * @param User   $user
198
     * @param string $old
199
     */
200
    public function userRenamed(User $user, $old)
201
    {
202
        $this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
203
    }
204
205
    /**
206
     * @param User   $user
207
     * @param string $reason
208
     */
209
    public function userRolesEdited(User $user, $reason)
210
    {
211
        $currentUser = $this->currentUser->getUsername();
212
        $this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
213
    }
214
215
    #endregion
216
217
    #region Site Notice
218
219
    /**
220
     * Summary of siteNoticeEdited
221
     */
222
    public function siteNoticeEdited()
223
    {
224
        $this->send("Site notice edited by " . $this->currentUser->getUsername());
225
    }
226
    #endregion
227
228
    #region Welcome Templates
229
    /**
230
     * Summary of welcomeTemplateCreated
231
     *
232
     * @param WelcomeTemplate $template
233
     */
234
    public function welcomeTemplateCreated(WelcomeTemplate $template)
235
    {
236
        $this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
237
    }
238
239
    /**
240
     * Summary of welcomeTemplateDeleted
241
     *
242
     * @param int $templateid
243
     */
244
    public function welcomeTemplateDeleted($templateid)
245
    {
246
        $this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
247
    }
248
249
    /**
250
     * Summary of welcomeTemplateEdited
251
     *
252
     * @param WelcomeTemplate $template
253
     */
254
    public function welcomeTemplateEdited(WelcomeTemplate $template)
255
    {
256
        $this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
257
    }
258
259
    #endregion
260
261
    #region bans
262
    /**
263
     * Summary of banned
264
     *
265
     * @param Ban $ban
266
     */
267
    public function banned(Ban $ban)
268
    {
269
        if ($ban->getDuration() === null) {
270
            $duration = "indefinitely";
271
        }
272
        else {
273
            $duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
274
        }
275
276
        $username = $this->currentUser->getUsername();
277
278
        if ($ban->getVisibility() == 'user') {
279
            $this->send("Ban {$ban->getId()} set by {$username} for '{$ban->getReason()}' {$duration}");
280
        }
281
        else {
282
            $this->send("Ban {$ban->getId()} set by {$username} {$duration}");
283
        }
284
    }
285
286
    /**
287
     * Summary of unbanned
288
     *
289
     * @param Ban    $ban
290
     * @param string $unbanReason
291
     */
292
    public function unbanned(Ban $ban, $unbanReason)
293
    {
294
        $this->send("Ban {$ban->getId()} unbanned by " . $this->currentUser
295
                ->getUsername() . " (" . $unbanReason . ")");
296
    }
297
298
    #endregion
299
300
    #region request management
301
302
    /**
303
     * Summary of requestReceived
304
     *
305
     * @param Request $request
306
     */
307
    public function requestReceived(Request $request)
308
    {
309
        $this->send(
310
            IrcColourCode::DARK_GREY . "[["
311
            . IrcColourCode::DARK_GREEN . "acc:"
312
            . IrcColourCode::ORANGE . $request->getId()
313
            . IrcColourCode::DARK_GREY . "]]"
314
            . IrcColourCode::RED . " N "
315
            . IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
316
            . IrcColourCode::DARK_RED . "* "
317
            . IrcColourCode::DARK_GREEN . $request->getName()
318
            . IrcColourCode::DARK_RED . " * "
319
            . IrcColourCode::RESET
320
        );
321
    }
322
323
    /**
324
     * Summary of requestDeferred
325
     *
326
     * @param Request $request
327
     */
328
    public function requestDeferred(Request $request)
329
    {
330
        /** @var RequestQueue $queue */
331
        $queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
332
333
        $deferTo = $queue->getDisplayName();
334
        $username = $this->currentUser->getUsername();
335
336
        $this->send("Request {$request->getId()} ({$request->getName()}) deferred to {$deferTo} by {$username}");
337
    }
338
339
    /**
340
     *
341
     * Summary of requestDeferredWithMail
342
     *
343
     * @param Request $request
344
     */
345
    public function requestDeferredWithMail(Request $request)
346
    {
347
        /** @var RequestQueue $queue */
348
        $queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
349
350
        $deferTo = $queue->getDisplayName();
351
        $username = $this->currentUser->getUsername();
352
        $id = $request->getId();
353
        $name = $request->getName();
354
355
        $this->send("Request {$id} ({$name}) deferred to {$deferTo} with an email by {$username}");
356
    }
357
358
    /**
359
     * Summary of requestClosed
360
     *
361
     * @param Request $request
362
     * @param string  $closetype
363
     */
364
    public function requestClosed(Request $request, $closetype)
365
    {
366
        $username = $this->currentUser->getUsername();
367
368
        $this->send("Request {$request->getId()} ({$request->getName()}) closed ($closetype) by {$username}");
369
    }
370
371
    /**
372
     * Summary of requestClosed
373
     *
374
     * @param Request $request
375
     * @param string  $closetype
376
     */
377
    public function requestCloseQueued(Request $request, $closetype)
378
    {
379
        $username = $this->currentUser->getUsername();
380
381
        $this->send("Request {$request->getId()} ({$request->getName()}) queued for creation ($closetype) by {$username}");
382
    }
383
384
    /**
385
     * Summary of requestClosed
386
     *
387
     * @param Request $request
388
     * @param User    $triggerUser
389
     */
390
    public function requestCreationFailed(Request $request, User $triggerUser)
391
    {
392
        $this->send("Request {$request->getId()} ({$request->getName()}) failed auto-creation for {$triggerUser->getUsername()}, and was sent to the hospital queue.");
393
    }
394
395
    /**
396
     * @param Request $request
397
     * @param User    $triggerUser
398
     */
399
    public function requestWelcomeFailed(Request $request, User $triggerUser)
400
    {
401
        $this->send("Request {$request->getId()} ({$request->getName()}) failed welcome for {$triggerUser->getUsername()}.");
402
    }
403
404
    /**
405
     * Summary of sentMail
406
     *
407
     * @param Request $request
408
     */
409
    public function sentMail(Request $request)
410
    {
411
        $this->send($this->currentUser->getUsername()
412
            . " sent an email related to Request {$request->getId()} ({$request->getName()})");
413
    }
414
415
    #endregion
416
417
    #region reservations
418
419
    /**
420
     * Summary of requestReserved
421
     *
422
     * @param Request $request
423
     */
424
    public function requestReserved(Request $request)
425
    {
426
        $username = $this->currentUser->getUsername();
427
428
        $this->send("Request {$request->getId()} ({$request->getName()}) reserved by {$username}");
429
    }
430
431
    /**
432
     * Summary of requestReserveBroken
433
     *
434
     * @param Request $request
435
     */
436
    public function requestReserveBroken(Request $request)
437
    {
438
        $username = $this->currentUser->getUsername();
439
440
        $this->send("Reservation on request {$request->getId()} ({$request->getName()}) broken by {$username}");
441
    }
442
443
    /**
444
     * Summary of requestUnreserved
445
     *
446
     * @param Request $request
447
     */
448
    public function requestUnreserved(Request $request)
449
    {
450
        $this->send("Request {$request->getId()} ({$request->getName()}) is no longer being handled.");
451
    }
452
453
    /**
454
     * Summary of requestReservationSent
455
     *
456
     * @param Request $request
457
     * @param User    $target
458
     */
459
    public function requestReservationSent(Request $request, User $target)
460
    {
461
        $username = $this->currentUser->getUsername();
462
463
        $this->send(
464
            "Reservation of request {$request->getId()} ({$request->getName()}) sent to {$target->getUsername()} by "
465
            . $username);
466
    }
467
468
    #endregion
469
470
    #region comments
471
472
    /**
473
     * Summary of commentCreated
474
     *
475
     * @param Comment $comment
476
     * @param Request $request
477
     */
478
    public function commentCreated(Comment $comment, Request $request)
479
    {
480
        $username = $this->currentUser->getUsername();
481
        switch ($comment->getVisibility()) {
482
            case 'admin':
483
                $visibility = " with visibility 'admin'";
484
                break;
485
            case 'checkuser':
486
                $visibility = " with visibility 'checkuser'";
487
                break;
488
            default:
489
                $visibility = "";
490
                break;
491
        }
492
493
        $this->send("{$username} posted a comment on request {$request->getId()} ({$request->getName()}){$visibility}");
494
    }
495
496
    /**
497
     * Summary of commentEdited
498
     *
499
     * @param Comment $comment
500
     * @param Request $request
501
     */
502
    public function commentEdited(Comment $comment, Request $request)
503
    {
504
        $username = $this->currentUser->getUsername();
505
506
        $this->send(<<<TAG
507
Comment {$comment->getId()} on request {$request->getId()} ({$request->getName()}) edited by {$username}
508
TAG
509
        );
510
    }
511
512
    public function alertFlaggedComments(int $count)
513
    {
514
        $this->send("There are ${count} flagged comments on closed requests currently awaiting redaction.");
515
    }
516
517
    #endregion
518
519
    #region email management (close reasons)
520
521
    /**
522
     * Summary of emailCreated
523
     *
524
     * @param EmailTemplate $template
525
     */
526
    public function emailCreated(EmailTemplate $template)
527
    {
528
        $username = $this->currentUser->getUsername();
529
        $this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
530
    }
531
532
    /**
533
     * Summary of emailEdited
534
     *
535
     * @param EmailTemplate $template
536
     */
537
    public function emailEdited(EmailTemplate $template)
538
    {
539
        $username = $this->currentUser->getUsername();
540
        $this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
541
    }
542
    #endregion
543
}
544