Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ContributionsRangeTrait
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
3 / 3
9
100.00% covered (success)
100.00%
1 / 1
 isQueryableRange
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
6
 isValidIPOrQueryableRange
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getQueryableRangeLimit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * @license GPL-2.0-or-later
5 * @file
6 */
7
8namespace MediaWiki\SpecialPage;
9
10use MediaWiki\Config\Config;
11use MediaWiki\MainConfigNames;
12use Wikimedia\IPUtils;
13
14/**
15 * Handle ranges for contributions special pages and APIs.
16 *
17 * @since 1.44
18 */
19trait ContributionsRangeTrait {
20    /**
21     * Check whether the given IP is a range and within the contributions CIDR limit.
22     *
23     * @param string $target
24     * @param Config $config
25     * @return bool
26     */
27    protected function isQueryableRange( string $target, Config $config ): bool {
28        if ( !IPUtils::isValidRange( $target ) ) {
29            return false;
30        }
31
32        // IPs in the format `X.X.X.X - Y.Y.Y.Y` are considered valid by IPUtils
33        // but don't have a CIDR we can get from the IP reliably.
34        // Contributions pages don't accept this as a valid input, so just return false.
35        $ipParts = explode( '/', $target, 2 );
36        if ( count( $ipParts ) < 2 ) {
37            return false;
38        }
39        [ $ip, $range ] = $ipParts;
40
41        $CIDRLimit = $this->getQueryableRangeLimit( $config );
42        return (
43            ( IPUtils::isIPv4( $ip ) && $range >= $CIDRLimit['IPv4'] ) ||
44            ( IPUtils::isIPv6( $ip ) && $range >= $CIDRLimit['IPv6'] )
45        );
46    }
47
48    /**
49     * Check whether the given target is either a valid IP address or a valid range within the
50     * contributions CIDR limit.
51     *
52     * @param string $target
53     * @param Config $config
54     * @return bool
55     */
56    protected function isValidIPOrQueryableRange( string $target, Config $config ): bool {
57        return IPUtils::isValid( $target ) ||
58            $this->isQueryableRange( $target, $config );
59    }
60
61    /**
62     * @param Config $config
63     * @return int[]
64     */
65    protected function getQueryableRangeLimit( Config $config ): array {
66        return $config->get( MainConfigNames::RangeContributionsCIDRLimit );
67    }
68}