Completed
Branch newinternal (113bb8)
by Michael
05:12
created

XffTrustProvider   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 19
eloc 52
c 0
b 0
f 0
dl 0
loc 153
ccs 0
cts 74
cp 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A isTrusted() 0 34 6
A getTrustedClientIp() 0 19 5
A ipInRange() 0 11 4
A explodeCidr() 0 22 3
A __construct() 0 4 1
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Providers;
10
11
use PDOStatement;
12
use Waca\PdoDatabase;
13
use Waca\Providers\Interfaces\IXffTrustProvider;
14
15
/**
16
 * XffTrustProvider short summary.
17
 *
18
 * XffTrustProvider description.
19
 *
20
 * @version 1.0
21
 * @author  stwalkerster
22
 */
23
class XffTrustProvider implements IXffTrustProvider
24
{
25
    /**
26
     * Array of IP addresses which are TRUSTED proxies
27
     * @var string[]
28
     */
29
    private $trustedCache = array();
30
    /**
31
     * Array of IP addresses which are UNTRUSTED proxies
32
     * @var string[]
33
     */
34
    private $untrustedCache = array();
35
    /** @var PDOStatement */
36
    private $trustedQuery;
37
    /**
38
     * @var PdoDatabase
39
     */
40
    private $database;
41
42
    /**
43
     * Creates a new instance of the trust provider
44
     *
45
     * @param string[]    $squidIpList List of IP addresses to pre-approve
46
     * @param PdoDatabase $database
47
     */
48
    public function __construct($squidIpList, PdoDatabase $database)
49
    {
50
        $this->trustedCache = $squidIpList;
51
        $this->database = $database;
52
    }
0 ignored issues
show
Coding Style introduced by
Expected //end __construct()
Loading history...
53
54
    /**
55
     * Returns a value if the IP address is a trusted proxy
56
     *
57
     * @param string $ip
58
     *
59
     * @return bool
60
     */
61
    public function isTrusted($ip)
62
    {
63
        if (in_array($ip, $this->trustedCache)) {
64
            return true;
65
        }
66
67
        if (in_array($ip, $this->untrustedCache)) {
68
            return false;
69
        }
70
71
        if ($this->trustedQuery === null) {
72
            $query = "SELECT COUNT(id) FROM xfftrustcache WHERE ip = :ip;";
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT COUNT(id) FROM xf...stcache WHERE ip = :ip; does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
73
            $this->trustedQuery = $this->database->prepare($query);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->database->prepare($query) can also be of type boolean. However, the property $trustedQuery is declared as type PDOStatement. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
74
        }
75
76
        $this->trustedQuery->execute(array(":ip" => $ip));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal :ip does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
77
        $result = $this->trustedQuery->fetchColumn();
78
        $this->trustedQuery->closeCursor();
79
80
        if ($result == 0) {
81
            $this->untrustedCache[] = $ip;
82
83
            return false;
84
        }
85
86
        if ($result >= 1) {
87
            $this->trustedCache[] = $ip;
88
89
            return true;
90
        }
91
92
        // something weird has happened if we've got here.
93
        // default to untrusted.
94
        return false;
95
    }
0 ignored issues
show
Coding Style introduced by
Expected //end isTrusted()
Loading history...
96
97
    /**
98
     * Gets the last trusted IP in the proxy chain.
99
     *
100
     * @param string $ip      The IP address from REMOTE_ADDR
101
     * @param string $proxyIp The contents of the XFF header.
102
     *
103
     * @return string Trusted source IP address
104
     */
105
    public function getTrustedClientIp($ip, $proxyIp)
106
    {
107
        $clientIpAddress = $ip;
108
        if ($proxyIp) {
109
            $ipList = explode(",", $proxyIp);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal , does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
110
            $ipList[] = $clientIpAddress;
111
            $ipList = array_reverse($ipList);
112
113
            foreach ($ipList as $ipNumber => $ipAddress) {
114
                if ($this->isTrusted(trim($ipAddress)) && $ipNumber < (count($ipList) - 1)) {
115
                    continue;
116
                }
117
118
                $clientIpAddress = $ipAddress;
119
                break;
120
            }
121
        }
122
123
        return $clientIpAddress;
124
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getTrustedClientIp()
Loading history...
125
126
    /**
127
     * Takes an array( "low" => "high" ) values, and returns true if $needle is in at least one of them.
128
     *
129
     * @param array  $haystack
130
     * @param string $ip
131
     *
132
     * @return bool
133
     */
134
    public function ipInRange($haystack, $ip)
135
    {
136
        $needle = ip2long($ip);
137
138
        foreach ($haystack as $low => $high) {
139
            if (ip2long($low) <= $needle && ip2long($high) >= $needle) {
140
                return true;
141
            }
142
        }
143
144
        return false;
145
    }
0 ignored issues
show
Coding Style introduced by
Expected //end ipInRange()
Loading history...
146
147
    /**
148
     * Explodes a CIDR range into an array of addresses
149
     *
150
     * @param string $range A CIDR-format range
151
     *
152
     * @return array An array containing every IP address in the range
153
     */
154
    public function explodeCidr($range)
155
    {
156
        $cidrData = explode('/', $range);
157
158
        if (!isset($cidrData[1])) {
159
            return array($range);
160
        }
161
162
        $blow = (
163
            str_pad(decbin(ip2long($cidrData[0])), 32, "0", STR_PAD_LEFT) &
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal 0 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Bug introduced by
Are you sure you want to use the bitwise & or did you mean &&?
Loading history...
164
            str_pad(str_pad("", $cidrData[1], "1"), 32, "0")
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal 1 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Bug introduced by
$cidrData[1] of type string is incompatible with the type integer expected by parameter $pad_length of str_pad(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
            str_pad(str_pad("", /** @scrutinizer ignore-type */ $cidrData[1], "1"), 32, "0")
Loading history...
165
        );
166
        $bhigh = ($blow | str_pad(str_pad("", $cidrData[1], "0"), 32, "1"));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal 0 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Bug introduced by
Are you sure you want to use the bitwise | or did you mean ||?
Loading history...
167
168
        $list = array();
169
170
        $bindecBHigh = bindec($bhigh);
171
        for ($x = bindec($blow); $x <= $bindecBHigh; $x++) {
172
            $list[] = long2ip($x);
173
        }
174
175
        return $list;
176
    }
0 ignored issues
show
Coding Style introduced by
Expected //end explodeCidr()
Loading history...
177
}
0 ignored issues
show
Coding Style introduced by
Expected //end class
Loading history...
178