Completed
Push — master ( 6adefe...4d2a94 )
by Sebastian
03:17
created

EnhancedAuthentication::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 11
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
crap 1
1
<?php
2
3
/**
4
 * Linna Framework.
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2018, Sebastian Rapetti
8
 * @license http://opensource.org/licenses/MIT MIT License
9
 */
10
declare(strict_types=1);
11
12
namespace Linna\Authentication;
13
14
use Linna\Session\Session;
15
use Linna\Shared\ClassOptionsTrait;
16
17
/**
18
 * Extend basic user authentication system with more security checks.
19
 */
20
class EnhancedAuthentication extends Authentication
21
{
22
    use ClassOptionsTrait;
23
24
    /**
25
     * @var array An associative array containing options
26
     */
27
    protected $options = [
28
        'maxAttemptsForUserName' => 5,
29
        'maxAttemptsForSessionId' => 10,
30
        'maxAttemptsForIpAddress' => 20,
31
        'maxAttemptsForSecond' => 40,
32
        'banTimeInSeconds' => 900 //15 minutes
33
    ];
34
35
    /**
36
     * @var EnhancedAuthenticationMapperInterface Enhanced Authentication Mapper
37
     */
38
    private $enhancedAuthenticationMapper;
39
40
    /**
41
     * Class Constructor
42
     *
43
     * @param Session $session
44
     * @param Password $password
45
     * @param EnhancedAuthenticationMapperInterface $enhancedAuthenticationMapper
46
     * @param array $options
47
     */
48 28
    public function __construct(
49
            Session $session,
50
            Password $password,
51
            EnhancedAuthenticationMapperInterface $enhancedAuthenticationMapper,
52
            array $options = []
53
        ) {
54 28
        parent::__construct($session, $password);
55
56 28
        $this->enhancedAuthenticationMapper = $enhancedAuthenticationMapper;
57
        //set options
58 28
        $this->setOptions($options);
59 28
    }
60
61
    /**
62
     * Return how many attemps are left for incorrect password.
63
     *
64
     * @param string $userName
65
     *
66
     * @return int
67
     */
68 28
    public function getAttemptsLeftWithSameUser(string $userName): int
69
    {
70 28
        $attemptsLeft = $this->options['maxAttemptsForUserName'] - $this->enhancedAuthenticationMapper->fetchAttemptsWithSameUser($userName, $this->options['banTimeInSeconds']);
71
72
        //casting to int second param for avoid strange things with
73
        //max return value
74
        //http://php.net/manual/en/function.max.php
75 28
        return max(0, (int) $attemptsLeft);
76
    }
77
78
    /**
79
     * Return how many attemps are left for same session id.
80
     *
81
     * @param string $sessionId
82
     *
83
     * @return int
84
     */
85 28
    public function getAttemptsLeftWithSameSession(string $sessionId): int
86
    {
87 28
        $attemptsLeft = $this->options['maxAttemptsForSessionId'] - $this->enhancedAuthenticationMapper->fetchAttemptsWithSameSession($sessionId, $this->options['banTimeInSeconds']);
88
89 28
        return max(0, (int) $attemptsLeft);
90
    }
91
92
    /**
93
     * Return how many attemps are left for same ip.
94
     *
95
     * @param string $ipAddress
96
     *
97
     * @return int
98
     */
99 28
    public function getAttemptsLeftWithSameIp(string $ipAddress): int
100
    {
101 28
        $attemptsLeft = $this->options['maxAttemptsForIpAddress'] - $this->enhancedAuthenticationMapper->fetchAttemptsWithSameIp($ipAddress, $this->options['banTimeInSeconds']);
102
103 28
        return max(0, (int) $attemptsLeft);
104
    }
105
106
    /**
107
     * Check if an user is banned from do login.
108
     *
109
     * @param string $userName
110
     *
111
     * @return bool
112
     */
113 28
    public function isUserBanned(string $userName): bool
114
    {
115 28
        return !$this->getAttemptsLeftWithSameUser($userName);
116
    }
117
118
    /**
119
     * Check if a session id is banned from do login.
120
     *
121
     * @param string $sessionId
122
     *
123
     * @return bool
124
     */
125 28
    public function isSessionBanned(string $sessionId): bool
126
    {
127 28
        return !$this->getAttemptsLeftWithSameSession($sessionId);
128
    }
129
130
    /**
131
     * Check if an ip address is banned from do login.
132
     *
133
     * @param string $ipAddress
134
     *
135
     * @return bool
136
     */
137 28
    public function isIpBanned(string $ipAddress): bool
138
    {
139 28
        return !$this->getAttemptsLeftWithSameIp($ipAddress);
140
    }
141
}
142