Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
SessionHuman
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 11
1406
0.00% covered (danger)
0.00%
0 / 1
 writeVerifySession
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 writeBotSession
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 redirectOnSuspicion
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
110
 isOverAged
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isUnderAged
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 addStep
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 hasStep
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 hasStepMaxReload
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 isVerified
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isOrigin
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 writeRedirectCaptcha
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace BO\Slim\Middleware\Session;
4
5/**
6 * Check if human
7 */
8class SessionHuman extends SessionContainer
9{
10    const MAX_RELOAD = 10;
11
12    const MAX_TIME = 1800;
13
14    const MIN_TIME = 3;
15
16    public function writeVerifySession($request, $origin = '')
17    {
18        $clientIp = $request->getAttribute('ip_address');
19        $this->set('client', 1, 'human');
20        $this->set('ts', time(), 'human');
21        if (! $this->isOrigin('captcha')) {
22            $this->set('origin', $origin, 'human');
23        }
24        $this->set('remoteAddress', $clientIp, 'human');
25    }
26
27    public function writeBotSession($origin = '')
28    {
29        $this->set('client', 0, 'human');
30        $this->set('ts', 0, 'human');
31        $this->set('origin', $origin, 'human');
32    }
33
34    /**
35     * @SuppressWarnings(Complexity)
36     * @return Boolean
37     */
38    public function redirectOnSuspicion($request, $requiredSteps = array(), $referer = false)
39    {
40        $path = $request->getUri()->getPath();
41        if (! $this->isOrigin('captcha')) {
42            foreach ($requiredSteps as $stepName) {
43                if (!$this->hasStep($stepName)) {
44                    \App::$log->notice(
45                        "[Human " . session_id() . "] Missing step $stepName on " . $path . " (referer: " . $referer . ")"
46                    );
47                    $this->writeRedirectCaptcha($path, $stepName);
48                    return true;
49                }
50                if ($this->hasStepMaxReload($stepName)) {
51                    \App::$log->notice(
52                        "[Human " . session_id() . "] Exceeded max reload for step $stepName on " . $path
53                    );
54                    $this->writeRedirectCaptcha($path, ($referer) ? $referer : end($requiredSteps));
55                    return true;
56                }
57            }
58            $clientIpAddress = $request->getAttribute('ip_address');
59            if (!$this->has('remoteAddress', 'human') || $clientIpAddress != $this->get('remoteAddress', 'human')) {
60                \App::$log->error("[Human " . session_id() . "] Missing remote address " . $clientIpAddress);
61                $this->writeRedirectCaptcha($path, $referer);
62                return true;
63            }
64        }
65        if (!$this->isVerified()) {
66            \App::$log->error(
67                "[Human " . session_id() . "] Missing session on " . $path . " (referer: " . $referer . ")"
68            );
69            $this->writeRedirectCaptcha($path, $referer);
70            return true;
71        }
72        $this->writeRedirectCaptcha($path, ($referer) ? $referer : end($requiredSteps));
73        return false;
74    }
75
76    public function isOverAged()
77    {
78        if (!$this->has('ts', 'human') || time() > ($this->get('ts', 'human') + self::MAX_TIME)) {
79            return true;
80        }
81        return false;
82    }
83
84    public function isUnderAged()
85    {
86        if (!$this->has('ts', 'human') || time() < ($this->get('ts', 'human') + self::MIN_TIME)) {
87            return true;
88        }
89        return false;
90    }
91
92    /**
93     *
94     *
95     * @return array
96     */
97    public function addStep($stepName)
98    {
99        if (!$this->has('step', 'human')) {
100            $this->set('step', array(), 'human');
101        }
102        if (!array_key_exists($stepName, $this->get('step', 'human'))) {
103            $stepCount = 1;
104        } else {
105            $stepCount = $this->get('step', 'human')[$stepName] + 1;
106        }
107        $step = $this->get('step', 'human');
108        $step[$stepName] = $stepCount;
109        $this->setGroup(array('human' => array('step' => $step)));
110    }
111
112    /**
113     * check if has steps
114     *
115     * @return boolean
116     */
117    public function hasStep($stepName)
118    {
119        if ($this->has('step', 'human') && array_key_exists($stepName, $this->get('step', 'human'))) {
120            return true;
121        }
122        return false;
123    }
124
125    /**
126     * check if has steps
127     *
128     * @return boolean
129     */
130    public function hasStepMaxReload($stepName)
131    {
132        if (
133            $this->has('step', 'human') &&
134            array_key_exists($stepName, $this->get('step', 'human')) &&
135            $this->get('step', 'human')[$stepName] > self::MAX_RELOAD
136        ) {
137            return true;
138        }
139        return false;
140    }
141
142    public function isVerified()
143    {
144        if ($this->has('client', 'human') && $this->get('client', 'human')) {
145            return true;
146        }
147        return false;
148    }
149
150    /**
151     * check if is origin
152     *
153     * @return boolean
154     */
155    protected function isOrigin($originName)
156    {
157        if ($this->has('origin', 'human') && $originName == $this->get('origin', 'human')) {
158            return true;
159        }
160        return false;
161    }
162
163    /**
164     *
165     *
166     * @return self
167     */
168    protected function writeRedirectCaptcha($path, $referer = false)
169    {
170        if (false === $referer) {
171            $referer = basename($path);
172        }
173        $referer = array('human' => array('referer' => $referer));
174        $this->setGroup($referer);
175    }
176}