ContredanseUserProvider::ensureAuthIsWorking()   B
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 22
c 1
b 0
f 0
nc 7
nop 0
dl 0
loc 39
ccs 0
cts 30
cp 0
crap 42
rs 8.9457
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Security;
6
7
use App\Security\Exception\QueryErrorException;
8
use App\Security\Exception\UserNotFoundException;
9
use Zend\Expressive\Authentication\UserInterface;
10
11
class ContredanseUserProvider implements UserProviderInterface
12
{
13
    /**
14
     * @var \PDO
15
     */
16
    private $adapter;
17
18
    public function __construct(\PDO $adapter)
19
    {
20
        $this->adapter = $adapter;
21
    }
22
23
    public function getUserByEmail(string $email): ?UserInterface
24
    {
25
        $sql = sprintf(
26
            "%s\n%s",
27
            $this->getBaseSql(),
28
            'where `l`.`Login` = :email'
29
        );
30
        $stmt = $this->adapter->prepare(
31
            $sql,
32
            [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]
33
        );
34
        $stmt->execute([':email' => $email]);
35
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
36
37
        if ($rows === false || count($rows) !== 1) {
38
            return null;
39
        }
40
41
        return new ContredanseUser(
42
            $rows[0]['user_id'],
43
            explode(' ', $rows[0]['role'] ?? ''),
44
            $rows[0]
45
        );
46
    }
47
48
    /**
49
     * Return all users.
50
     *
51
     * @throws QueryErrorException
52
     */
53
    public function getAllUsers(): array
54
    {
55
        $sql  = $this->getBaseSql();
56
        $stmt = $this->adapter->prepare(
57
            $sql,
58
            [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]
59
        );
60
        $stmt->execute();
61
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
62
        if ($rows === false) {
63
            throw new QueryErrorException('Cannot retrieve users');
64
        }
65
66
        return $rows;
67
    }
68
69
    /**
70
     * Return a specific user.
71
     *
72
     * @throws QueryErrorException
73
     * @throws UserNotFoundException
74
     *
75
     * @return array<int, UserInterface>
76
     */
77
    public function findUser(string $user_id): array
78
    {
79
        $sql = sprintf(
80
            "%s\n%s",
81
            $this->getBaseSql(),
82
            'where `l`.`user_id` = :user_id'
83
        );
84
        $stmt = $this->adapter->prepare(
85
            $sql,
86
            [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]
87
        );
88
        $stmt->execute([':user_id' => $user_id]);
89
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
90
        if ($rows === false) {
91
            throw new QueryErrorException('Cannot find user, query error');
92
        }
93
        if (count($rows) !== 1) {
94
            throw new UserNotFoundException(sprintf(
95
                'User \'%d\' not found',
96
                $user_id
97
            ));
98
        }
99
100
        return $rows[0];
101
    }
102
103
    public function ensureAuthIsWorking(): void
104
    {
105
        // Check query working
106
        $sql = sprintf(
107
            "%s\n%s",
108
            $this->getBaseSql(),
109
            'limit 1'
110
        );
111
112
        try {
113
            $stmt = $this->adapter->prepare($sql);
114
            $stmt->execute();
115
            $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
116
        } catch (\Throwable $e) {
117
            throw new QueryErrorException(
118
                sprintf('Cannot query database, query error: %s', $e->getMessage())
119
            );
120
        }
121
122
        if ($rows === false || count($rows) !== 1) {
123
            throw new \RuntimeException('User database empty');
124
        }
125
126
        // Take first user email
127
128
        $email  = $rows[0]['email'];
129
        $userId = $rows[0]['user_id'];
130
131
        $user = $this->getUserByEmail($email);
132
133
        if ($user === null) {
134
            throw new \RuntimeException(
135
                'Cannot locate user'
136
            );
137
        }
138
139
        if ($user->getDetail('user_id') !== $userId) {
140
            throw new \RuntimeException(
141
                sprintf('Users does no match: %s', '')
142
            );
143
        }
144
    }
145
146
    private function getBaseSql(): string
147
    {
148
        $sql = '
149
                  select 
150
                      `s`.`suj_id` as `subject_id`,
151
                      `l`.`User_id` as `user_id`, 
152
                      `l`.`Login` as `email`, 
153
                      `l`.`Pwd` as `password`, 
154
                      `s`.`suj_type` as `subject_type`,
155
                      `s`.`suj_title` as `title`,
156
                      `s`.`suj_name` as `name`,
157
                      `s`.`suj_firstname` as `firstname`,                      
158
                      `l`.`role`,
159
                      `s`.`membre_cd`,
160
                      `s`.`membre_cf`
161
                  from `usr_login` as `l` inner join `sujet` as `s` 
162
                  on `s`.`suj_id` = `l`.`suj_id`  
163
               ';
164
165
        return $sql;
166
    }
167
}
168