Completed
Pull Request — master (#2)
by René
05:31 queued 03:25
created

UserAuthenticator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 5
ccs 0
cts 5
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace Zortje\MVC\User;
5
6
use Zortje\MVC\Configuration\Configuration;
7
use Zortje\MVC\Storage\Cookie\Cookie;
8
use Zortje\MVC\Storage\Cookie\Exception\CookieUndefinedIndexException;
9
10
/**
11
 * Class UserAuthenticator
12
 *
13
 * @package Zortje\MVC\User
14
 */
15
class UserAuthenticator
16
{
17
18
    /**
19
     * @var \PDO PDO
20
     */
21
    protected $pdo;
22
23
    /**
24
     * @var Configuration
25
     */
26
    protected $configuration;
27
28
    /**
29
     * UserAuthenticator constructor.
30
     *
31
     * @param \PDO          $pdo
32
     * @param Configuration $configuration
33
     */
34
    public function __construct(\PDO $pdo, Configuration $configuration)
35
    {
36
        $this->pdo           = $pdo;
37
        $this->configuration = $configuration;
38
    }
39
40
    /**
41
     * Authenticate user object from cookie
42
     *
43
     * @param Cookie $cookie Cookie object
44
     *
45
     * @return User|null User if a user ID is sent in cookie
0 ignored issues
show
Documentation introduced by
Should the return type not be \Zortje\MVC\Model\Table\Entity\Entity|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

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