Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
26 / 28
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
GlobalBlockLocalStatusLookup
92.86% covered (success)
92.86%
26 / 28
66.67% covered (warning)
66.67%
2 / 3
8.02
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
 getLocalWhitelistInfo
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
6
 getLocalWhitelistInfoByIP
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\GlobalBlocking\Services;
4
5use InvalidArgumentException;
6use MediaWiki\User\CentralId\CentralIdLookup;
7use Wikimedia\IPUtils;
8use Wikimedia\Rdbms\IConnectionProvider;
9
10/**
11 * Service for looking up whether a global block has been locally disabled.
12 *
13 * @since 1.42
14 */
15class GlobalBlockLocalStatusLookup {
16
17    private IConnectionProvider $dbProvider;
18    private CentralIdLookup $centralIdLookup;
19
20    public function __construct(
21        IConnectionProvider $dbProvider,
22        CentralIdLookup $centralIdLookup
23    ) {
24        $this->dbProvider = $dbProvider;
25        $this->centralIdLookup = $centralIdLookup;
26    }
27
28    /**
29     * Returns whether the given global block ID or block on a specific target has been
30     * locally disabled.
31     *
32     * @param int|null $id Block ID
33     * @param null|string $target The target of the block (only used if $id is null). Can be an IP, range, or username.
34     * @param string|false $wikiId The wiki where the where the whitelist info should be looked up.
35     *   Use false for the local wiki.
36     * @return array|false false if the block is not locally disabled, otherwise an array containing the
37     *   user ID of the user who disabled the block and the reason for the block being disabled.
38     * @phan-return array{user:int,reason:string}|false
39     */
40    public function getLocalWhitelistInfo( ?int $id = null, ?string $target = null, $wikiId = false ) {
41        $queryBuilder = $this->dbProvider->getReplicaDatabase( $wikiId )
42            ->newSelectQueryBuilder()
43            ->select( [ 'gbw_by', 'gbw_reason' ] )
44            ->from( 'global_block_whitelist' );
45        if ( $id !== null ) {
46            $queryBuilder->where( [ 'gbw_id' => $id ] );
47        } elseif ( $target !== null ) {
48            if ( IPUtils::isIPAddress( $target ) ) {
49                $queryBuilder->where( [ 'gbw_address' => $target ] );
50            } else {
51                $centralIdForTarget = $this->centralIdLookup->centralIdFromName(
52                    $target, CentralIdLookup::AUDIENCE_RAW
53                );
54                if ( !$centralIdForTarget ) {
55                    // If the target does not have a central ID, we cannot look up by username. In this case we can
56                    // assume that there is no global block and therefore it cannot have a local status.
57                    return false;
58                }
59                $queryBuilder->where( [ 'gbw_target_central_id' => $centralIdForTarget ] );
60            }
61        } else {
62            // WTF?
63            throw new InvalidArgumentException(
64                'Both $target and $id are null when attempting to retrieve whitelist status'
65            );
66        }
67
68        $row = $queryBuilder
69            ->caller( __METHOD__ )
70            ->fetchRow();
71
72        if ( $row === false ) {
73            // Not locally disabled.
74            return false;
75        } else {
76            // Block has been locally disabled.
77            return [ 'user' => (int)$row->gbw_by, 'reason' => $row->gbw_reason ];
78        }
79    }
80
81    /**
82     * Returns whether a global block on the given IP address has been locally disabled.
83     *
84     * @param string $block_ip
85     * @param string|false $wikiId The wiki where the where the whitelist info should be looked up.
86     *    Use false for the local wiki.
87     * @return array|false false if the block is not locally disabled, otherwise an array containing the
88     *    user ID of the user who disabled the block and the reason for the block being disabled.
89     * @phan-return array{user:int,reason:string}|false
90     * @deprecated since 1.42. Use ::getLocalWhitelistInfo.
91     */
92    public function getLocalWhitelistInfoByIP( string $block_ip, $wikiId = false ) {
93        wfDeprecated( __METHOD__, '1.42' );
94        return $this->getLocalWhitelistInfo( null, $block_ip, $wikiId );
95    }
96}