IpHelper   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
wmc 16
lcom 2
cbo 0
dl 0
loc 117
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getClientIp() 0 4 1
A isAllowed() 0 12 3
A getAllowedIps() 0 14 4
A isARange() 0 4 1
A ipEqualOrInRange() 0 6 2
A ipInRange() 0 9 1
A commaSepratedValues() 0 14 4
1
<?php
2
3
namespace Tequilarapido\RestrictAccess\Restricter;
4
5
trait IpHelper
6
{
7
    /**
8
     * Returns client IP.
9
     * If a proxy used this returns X_FORWARDED_FOR IP.
10
     *
11
     * @return string
12
     */
13
    protected function getClientIp()
14
    {
15
        return $this->request->getClientIp();
0 ignored issues
show
Bug introduced by
The property request does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
16
    }
17
18
    /**
19
     * Checks client IP against allowed ips.
20
     *
21
     * @param $clientIp
22
     *
23
     * @return bool
24
     *
25
     * @throws \Exception
26
     */
27
    protected function isAllowed($clientIp)
28
    {
29
        $allowedIps = $this->getAllowedIps();
30
31
        foreach ($allowedIps as $allowedIp) {
32
            if ($this->ipEqualOrInRange($clientIp, $allowedIp)) {
33
                return true;
34
            }
35
        }
36
37
        return false;
38
    }
39
40
    /**
41
     * Returns allowed Ips from config.
42
     *
43
     * @return mixed
44
     *
45
     * @throws \Exception
46
     */
47
    protected function getAllowedIps()
48
    {
49
        $allowedIps = config('restrict_access.by_ip.except');
50
51
        if (is_string($allowedIps)) {
52
            $allowedIps = $this->commaSepratedValues($allowedIps);
53
        }
54
55
        if (! is_array($allowedIps) || empty($allowedIps)) {
56
            throw new \Exception('restrict_access.by_ip.except is required and must be an array of Ips and/or Ip ranges');
57
        }
58
59
        return $allowedIps;
60
    }
61
62
    /**
63
     * Quick way to check if the given ip is a range.
64
     *
65
     * @param $ipRange
66
     *
67
     * @return bool
68
     */
69
    protected function isARange($ipRange)
70
    {
71
        return strpos($ipRange, '/') !== false;
72
    }
73
74
    /**
75
     * Compare a given ip against an ip or a an ip range.
76
     *
77
     * @param $ip
78
     * @param $ipOrRange
79
     *
80
     * @return bool
81
     */
82
    protected function ipEqualOrInRange($ip, $ipOrRange)
83
    {
84
        return $this->isARange($ipOrRange) ?
85
            $this->ipInRange($ip, $ipOrRange) :
86
            $ip === $ipOrRange;
87
    }
88
89
    /**
90
     * Checks if a given ip belongs to an ip Range.
91
     *
92
     * @param $ip
93
     * @param $range
94
     *
95
     * @return bool
96
     */
97
    protected function ipInRange($ip, $range)
98
    {
99
        list($subnet, $bits) = explode('/', $range);
100
        $ip = ip2long($ip);
101
        $subnet = ip2long($subnet);
102
        $mask = -1 << (32 - $bits);
103
        $subnet &= $mask; // nb: in case the supplied subnet wasn't correctly aligned
104
        return ($ip & $mask) == $subnet;
105
    }
106
107
    private function commaSepratedValues($csv, $trim = true)
108
    {
109
        $items = ! empty($csv) && is_string($csv)
110
            ? explode(',', $csv)
111
            : [];
112
113
        if ($trim) {
114
            $items = array_map(function ($item) {
115
                return trim($item);
116
            }, $items);
117
        }
118
119
        return array_filter($items);
120
    }
121
}
122