Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbuseLogPrivateDetails
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 2
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 mustBePosted
n/a
0 / 0
n/a
0 / 0
1
 isWriteMode
n/a
0 / 0
n/a
0 / 0
1
 needsToken
n/a
0 / 0
n/a
0 / 0
1
 execute
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
42
 getAllowedParams
n/a
0 / 0
n/a
0 / 0
1
 getExamplesMessages
n/a
0 / 0
n/a
0 / 0
1
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 */
18
19namespace MediaWiki\Extension\AbuseFilter\Api;
20
21use MediaWiki\Api\ApiBase;
22use MediaWiki\Api\ApiMain;
23use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
24use MediaWiki\Extension\AbuseFilter\Special\SpecialAbuseLog;
25use Wikimedia\ParamValidator\ParamValidator;
26
27/**
28 * API module to allow accessing private details (the user's IP) from AbuseLog entries
29 *
30 * @ingroup API
31 * @ingroup Extensions
32 */
33class AbuseLogPrivateDetails extends ApiBase {
34
35    private AbuseFilterPermissionManager $afPermManager;
36
37    public function __construct(
38        ApiMain $main,
39        string $action,
40        AbuseFilterPermissionManager $afPermManager
41    ) {
42        parent::__construct( $main, $action );
43        $this->afPermManager = $afPermManager;
44    }
45
46    /**
47     * @codeCoverageIgnore Merely declarative
48     * @inheritDoc
49     */
50    public function mustBePosted() {
51        return true;
52    }
53
54    /**
55     * @codeCoverageIgnore Merely declarative
56     * @inheritDoc
57     */
58    public function isWriteMode() {
59        return true;
60    }
61
62    /**
63     * @codeCoverageIgnore Merely declarative
64     * @inheritDoc
65     */
66    public function needsToken() {
67        return 'csrf';
68    }
69
70    /**
71     * @inheritDoc
72     */
73    public function execute() {
74        $user = $this->getUser();
75
76        if ( !$this->afPermManager->canSeePrivateDetails( $user ) ) {
77            $this->dieWithError( 'abusefilter-log-cannot-see-privatedetails' );
78        }
79        $params = $this->extractRequestParams();
80
81        if ( !SpecialAbuseLog::checkPrivateDetailsAccessReason( $params['reason'] ) ) {
82            // Double check, in case we add some extra validation
83            $this->dieWithError( 'abusefilter-noreason' );
84        }
85        $status = SpecialAbuseLog::getPrivateDetailsRow( $user, $params['logid'] );
86        if ( !$status->isGood() ) {
87            $this->dieStatus( $status );
88        }
89        $row = $status->getValue();
90        // Log accessing private details
91        if ( $this->getConfig()->get( 'AbuseFilterLogPrivateDetailsAccess' ) ) {
92            SpecialAbuseLog::addPrivateDetailsAccessLogEntry(
93                $params['logid'],
94                $params['reason'],
95                $user
96            );
97        }
98
99        $result = [
100            'log-id' => $params['logid'],
101            'user' => $row->afl_user_text,
102            'filter-id' => (int)$row->af_id,
103            'filter-description' => $row->af_public_comments,
104            'ip-address' => $row->afl_ip !== '' ? $row->afl_ip : null
105        ];
106        $this->getResult()->addValue( null, $this->getModuleName(), $result );
107    }
108
109    /**
110     * @codeCoverageIgnore Merely declarative
111     * @inheritDoc
112     */
113    public function getAllowedParams() {
114        return [
115            'logid' => [
116                ParamValidator::PARAM_TYPE => 'integer'
117            ],
118            'reason' => [
119                ParamValidator::PARAM_TYPE => 'string',
120                ParamValidator::PARAM_REQUIRED => $this->getConfig()->get( 'AbuseFilterPrivateDetailsForceReason' ),
121                ParamValidator::PARAM_DEFAULT => '',
122            ]
123        ];
124    }
125
126    /**
127     * @codeCoverageIgnore Merely declarative
128     * @inheritDoc
129     */
130    protected function getExamplesMessages() {
131        return [
132            'action=abuselogprivatedetails&logid=1&reason=example&token=ABC123'
133                => 'apihelp-abuselogprivatedetails-example-1'
134        ];
135    }
136}