Issues (21)

src/PdoCredentialsValidator.php (2 issues)

1
<?php
2
namespace Germania\UserProfiles;
3
4
use Psr\Log\LoggerInterface;
5
use Psr\Log\NullLogger;
6
7
/**
8
 * This Callable checks if given username and password match a stored login name and password combination,
9
 * using a custom verifier function.
10
 *
11
 * Example:
12
 *
13
 *     <?php
14
 *     use Germania\UserProfiles\PdoCredentialsValidator;
15
 *
16
 *     $pdo      = new PDO( ... );
17
 *     $verifier = function() { return false; };
18
 *     $logger   = new Monolog();
19
 *     $table    = 'users';
20
 *
21
 *     $checker = new PdoCredentialsValidator( $pdo, $verifier, $logger, $table);
22
 *     $result = $checker( '[email protected]', 'take_this_secret' );
23
 *     ?>
24
 *
25
 * @author  Carsten Witt <[email protected]>
26
 */
27
class PdoCredentialsValidator
28
{
29
30
    /**
31
     * Database table
32
     * @var string
33
     */
34
    public $table = 'users';
35
36
    /**
37
     * @var PDOStatement
0 ignored issues
show
The type Germania\UserProfiles\PDOStatement was not found. Did you mean PDOStatement? If so, make sure to prefix the type with \.
Loading history...
38
     */
39
    public $stmt;
40
41
    /**
42
     * @var Callable
43
     */
44
    public $password_verifier;
45
46
    /**
47
     * @var LoggerInterface
48
     */
49
    public $logger;
50
51
52
    /**
53
     * @param PDO             $pdo                PDO instance
54
     * @param Callable        $password_verifier  Callable password verifier that accepts password and password hash
55
     * @param LoggerInterface $logger             Optional: PSR-3 Logger
56
     * @param string          $table              Optional: Database table name
57
     */
58 15
    public function __construct( \PDO $pdo, Callable $password_verifier, LoggerInterface $logger = null, $table = null)
59
    {
60 15
        $this->password_verifier = $password_verifier;
61 15
        $this->logger            = $logger ?: new NullLogger;
62 15
        $this->table             = $table  ?: $this->table;
63
64
65
        // Prepare business
66
        $sql = "SELECT
67
        id,
68
        password
69 15
        FROM {$this->table}
70
        WHERE user_login_name = :login_name
71 3
        LIMIT 1";
72
73
        // Store for later use
74 15
        $this->stmt = $pdo->prepare( $sql );
0 ignored issues
show
Documentation Bug introduced by
It seems like $pdo->prepare($sql) of type PDOStatement or boolean is incompatible with the declared type Germania\UserProfiles\PDOStatement of property $stmt.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
75
76 15
    }
77
78
79
80
    /**
81
     * @param  string $login_name
82
     * @param  string $$password
83
     *
84
     * @return mixed  User ID as integer or FALSE on any failure
85
     */
86 15
    public function __invoke( $login_name, $password )
87
    {
88
89
        // Perform
90 15
        $this->stmt->execute([
91 12
            'login_name' => $login_name
92 3
        ]);
93
94
95
        // If user not found...
96 15
        $found_user = $this->stmt->fetch( \PDO::FETCH_OBJ );
97 15
        if (!$found_user):
98 5
            $this->logger->warning("User login name not found", [
99 4
                'user_name' => $login_name
100 1
            ]);
101 5
            return false;
102
        endif;
103
104
105
        // If password is wrong...
106 10
        $verifier = $this->password_verifier;
107 10
        if(!$verifier( $password, $found_user->password)) :
108
109 5
            $this->logger->warning("Wrong password", [
110 4
                'user_name' => $login_name
111 1
            ]);
112 5
            return false;
113
        endif;
114
115
        // Return found user ID
116 5
        return $found_user->id;
117
118
    }
119
120
121
122
}
123