Completed
Push — feature/controller ( 4da62c...5a6415 )
by René
04:10
created

UserAuthenticator   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%
Metric Value
wmc 7
lcom 1
cbo 3
dl 0
loc 106
ccs 0
cts 35
cp 0
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A userFromCookie() 0 18 3
B signIn() 0 46 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Zortje\MVC\User;
5
6
use Zortje\MVC\Storage\Cookie\Cookie;
7
use Zortje\MVC\Storage\Cookie\Exception\CookieUndefinedIndexException;
8
9
/**
10
 * Class UserAuthenticator
11
 *
12
 * @package Zortje\MVC\User
13
 */
14
class UserAuthenticator
15
{
16
17
    /**
18
     * @var \PDO PDO
19
     */
20
    protected $pdo;
21
22
    /**
23
     * @var int Password hashing cost
24
     *
25
     * @todo Get the cost from a configuration class
26
     */
27
    private $passwordHashingCost = 11;
28
29
    /**
30
     * UserAuthenticator constructor.
31
     *
32
     * @param \PDO $pdo
33
     */
34
    public function __construct(\PDO $pdo)
35
    {
36
        $this->pdo = $pdo;
37
    }
38
39
    /**
40
     * Authenticate user object from cookie
41
     *
42
     * @param Cookie $cookie Cookie object
43
     *
44
     * @return User|null User if a user ID is sent in cookie
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use User.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
45
     */
46
    public function userFromCookie(Cookie $cookie): User
47
    {
48
        try {
49
            $userId = $cookie->get('User.id');
50
51
            $userTable = new UserTable($this->pdo);
52
53
            $users = $userTable->findBy('id', $userId);
54
55
            if (count($users) === 1) {
56
                return $users[0];
57
            } else {
58
                return null;
59
            }
60
        } catch (CookieUndefinedIndexException $e) {
61
            return null;
62
        }
63
    }
64
65
    /**
66
     * Sign in an user
67
     *
68
     * @param User   $user     User object
69
     * @param string $password User password
70
     *
71
     * @return bool Returns true if sign in was successful, otherwise false will be returned
72
     */
73
    public function signIn(User $user, string $password): bool
74
    {
75
        /**
76
         * Verify password
77
         */
78
        if (password_verify($password, $user->get('password_hash')) === false) {
79
            /**
80
             * Return false to indicate incorrect credentials
81
             */
82
            return false;
83
        } else {
84
            /**
85
             * Check if a new hashing algorithm is available or the cost has changed
86
             * If so, create a new hash and replace the old one in the user
87
             */
88
            $options = ['cost' => $this->passwordHashingCost];
89
90
            if (password_needs_rehash($user->get('password_hash'), PASSWORD_DEFAULT, $options)) {
91
                /**
92
                 * Create new password hash
93
                 */
94
                $user->set('password_hash', password_hash($password, PASSWORD_DEFAULT, $options));
95
96
                /**
97
                 * Update user in database
98
                 */
99
                $userTable = new UserTable($this->pdo);
100
                $userTable->update($user);
101
            }
102
103
            /**
104
             * Regenerate session ID to prevent session fixation attacks
105
             */
106
            session_regenerate_id();
107
108
            /**
109
             * Set User id in session
110
             */
111
            $_SESSION['User.id'] = $user->get('id');
112
113
            /**
114
             * Return true to indicate a successful sign in
115
             */
116
            return true;
117
        }
118
    }
119
}
120