Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.92% covered (success)
94.92%
56 / 59
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CheckUserPrivateEventLogFormatter
94.92% covered (success)
94.92%
56 / 59
50.00% covered (danger)
50.00%
2 / 4
25.08
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getMessageParameters
97.06% covered (success)
97.06%
33 / 34
0.00% covered (danger)
0.00%
0 / 1
12
 getActionMessage
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getParametersForApi
89.47% covered (warning)
89.47%
17 / 19
0.00% covered (danger)
0.00%
0 / 1
10.12
1<?php
2
3namespace MediaWiki\CheckUser\Logging;
4
5use InvalidArgumentException;
6use LogEntry;
7use LogFormatter;
8use MediaWiki\Html\Html;
9use MediaWiki\User\UserFactory;
10use MediaWiki\User\UserRigorOptions;
11use Message;
12
13/**
14 * LogFormatter for the rows stored in cu_private_event that are
15 * not visible outside of CheckUser.
16 *
17 * Supports the log types checkuser-private-event/*
18 */
19class CheckUserPrivateEventLogFormatter extends LogFormatter {
20
21    private UserFactory $userFactory;
22
23    public function __construct(
24        LogEntry $entry,
25        UserFactory $userFactory
26    ) {
27        parent::__construct( $entry );
28        $this->userFactory = $userFactory;
29    }
30
31    /**
32     * @inheritDoc
33     */
34    protected function getMessageParameters() {
35        $params = parent::getMessageParameters();
36
37        if (
38            $this->entry->getSubtype() == 'password-reset-email-sent' ||
39            $this->entry->getSubtype() == 'login-success' ||
40            $this->entry->getSubtype() == 'login-failure' ||
41            $this->entry->getSubtype() == 'login-failure-with-good-password'
42        ) {
43            // For messages:
44            // * logentry-checkuser-private-event-login-success
45            // * logentry-checkuser-private-event-login-failure
46            // * logentry-checkuser-private-event-login-failure-with-good-password
47            // * logentry-checkuser-private-event-password-reset-email-sent
48            if ( $this->entry->getSubtype() == 'password-reset-email-sent' ) {
49                $accountName = $this->entry->getParameters()['4::receiver'];
50            } else {
51                $accountName = $this->entry->getParameters()['4::target'];
52            }
53            // User can be non-existent or invalid in the case of failed login attempts.
54            $user = $this->userFactory->newFromName( $accountName, UserRigorOptions::RIGOR_NONE );
55            if ( !$user ) {
56                throw new InvalidArgumentException( "The account name $accountName is not valid." );
57            }
58            $hidden = $user->isHidden()
59                && !$this->context->getAuthority()->isAllowed( 'hideuser' );
60            if ( $hidden ) {
61                $params[3] = Message::rawParam( Html::element(
62                    'span',
63                    [ 'class' => 'history-deleted' ],
64                    $this->msg( 'rev-deleted-user' )->text()
65                ) );
66                $params[4] = '';
67            } else {
68                $link = $this->makeUserLink( $user );
69                if ( $user->isHidden() ) {
70                    $link = Html::rawElement(
71                        'span',
72                        [ 'class' => [ 'mw-history-suppressed', 'history-deleted' ] ],
73                        $link
74                    );
75                }
76                $params[3] = Message::rawParam( $link );
77                $params[4] = $accountName;
78            }
79        } elseif ( $this->entry->getSubtype() == 'email-sent' ) {
80            // For message logentry-checkuser-private-event-email-sent
81            $params[3] = $this->entry->getParameters()['4::hash'];
82        } elseif ( $this->entry->getSubtype() == 'migrated-cu_changes-log-event' ) {
83            // For message logentry-checkuser-private-event-migrated-cu_changes-log-event
84            $params[3] = $this->entry->getParameters()['4::actiontext'];
85        }
86
87        return $params;
88    }
89
90    /** @inheritDoc */
91    protected function getActionMessage() {
92        $actionMessage = parent::getActionMessage();
93        if ( $this->entry->getSubtype() === 'migrated-cu_changes-log-event' ) {
94            // Use ::parse so that the wikitext in the actiontext parameter can be
95            // parsed and displayed. Similar to WikitextLogFormatter, but defined
96            // here to allow mixing non-wikitext and wikitext log parameters for
97            // different messages.
98            return $actionMessage->parse();
99        }
100        return $actionMessage;
101    }
102
103    /** @inheritDoc */
104    protected function getParametersForApi() {
105        if (
106            $this->entry->getSubtype() == 'password-reset-email-sent' ||
107            $this->entry->getSubtype() == 'login-success' ||
108            $this->entry->getSubtype() == 'login-failure' ||
109            $this->entry->getSubtype() == 'login-failure-with-good-password'
110        ) {
111            $entryParametersForReturn = $this->entry->getParameters();
112            // Hide the username if it is hidden and the user does not
113            // have the rights to view it.
114            if ( $this->entry->getSubtype() == 'password-reset-email-sent' ) {
115                $accountName = $entryParametersForReturn['4::receiver'];
116            } else {
117                $accountName = $entryParametersForReturn['4::target'];
118            }
119            // User can be non-existent or invalid in the case of failed login attempts.
120            $user = $this->userFactory->newFromName( $accountName, UserRigorOptions::RIGOR_NONE );
121            if ( !$user ) {
122                throw new InvalidArgumentException( "The account name $accountName is not valid." );
123            }
124            $hidden = $user->isHidden()
125                && !$this->context->getAuthority()->isAllowed( 'hideuser' );
126            if ( $hidden ) {
127                if ( $this->entry->getSubtype() == 'password-reset-email-sent' ) {
128                    $entryParametersForReturn['4::receiver'] = $this->msg( 'rev-deleted-user' )->text();
129                } else {
130                    $entryParametersForReturn['4::target'] = $this->msg( 'rev-deleted-user' )->text();
131                }
132            }
133            return $entryParametersForReturn;
134        }
135        return parent::getParametersForApi();
136    }
137}