Passed
Push — master ( f3b4d6...85dd39 )
by Sam
11:35
created

UserRepository   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
wmc 14
eloc 30
c 0
b 0
f 0
dl 0
loc 91
ccs 30
cts 33
cp 0.9091
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
B getOneByEmailPassword() 0 31 8
A getAccessibleSubQuery() 0 9 2
A getOneById() 0 5 1
A getOneByEmail() 0 5 1
A getOrCreate() 0 10 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Model\User;
8
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
9
10
class UserRepository extends AbstractRepository implements LimitedAccessSubQuery
11
{
12
    /**
13
     * Returns pure SQL to get ID of all objects that are accessible to given user.
14
     *
15
     * @param null|User $user
16
     */
17 11
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
18
    {
19 11
        if (!$user) {
20 2
            $facilitator = $this->getEntityManager()->getConnection()->quote(User::ROLE_FACILITATOR);
21
22 2
            return 'SELECT id FROM user WHERE role = ' . $facilitator;
23
        }
24
25 9
        return $this->getAllIdsQuery();
26
    }
27
28
    /**
29
     * Returns the user authenticated by its email and password.
30
     */
31 2
    public function getOneByEmailPassword(string $email, string $password): ?User
32
    {
33
        /** @var null|User $user */
34 2
        $user = $this->getOneByEmail($email);
35
36 2
        if (!$user) {
37 1
            return null;
38
        }
39
40 2
        $hashFromDb = $user->getPassword();
41 2
        $isMd5 = mb_strlen($hashFromDb) === 32 && ctype_xdigit($hashFromDb);
42
43
        $possibleMd5 = [
44 2
            md5($password), // normal md5 for our test data
45 2
            md5('oQqnnn8sVBZzveU2zWCqdcu8N9JVE3GXFq6kS0i1ZyS3FkFoPZAN3GCA' . $password), // From PrestaShop `\ToolsCore::encrypt()` with hardcoded _COOKIE_KEY_ value
46
        ];
47
48
        // If we found a user and he has a correct MD5 or correct new hash, then return the user
49 2
        if (($isMd5 && in_array($hashFromDb, $possibleMd5, true)) || password_verify($password, $hashFromDb)) {
50
51
            // Update the hash in DB, if we are still MD5, or if PHP default options changed
52 2
            if ($isMd5 || password_needs_rehash($hashFromDb, PASSWORD_DEFAULT)) {
53 2
                $user->setPassword($password);
54
            }
55 2
            $user->revokeToken();
56 2
            _em()->flush();
57
58 2
            return $user;
59
        }
60
61 1
        return null;
62
    }
63
64
    /**
65
     * Unsecured way to get a user from its ID.
66
     *
67
     * This should only be used in tests or controlled environment.
68
     */
69 1
    public function getOneById(int $id): ?User
70
    {
71 1
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneById($id));
72
73 1
        return $user;
74
    }
75
76
    /**
77
     * Unsecured way to get a user from its email.
78
     *
79
     * This should only be used in tests or controlled environment.
80
     */
81 68
    public function getOneByEmail(?string $email): ?User
82
    {
83 68
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneByEmail($email));
84
85 68
        return $user;
86
    }
87
88
    /**
89
     * Get or create the user for the given email.
90
     */
91 1
    public function getOrCreate(string $email): User
92
    {
93 1
        $user = $this->getOneByEmail($email);
94 1
        if (!$user) {
95
            $user = new User();
96
            $this->getEntityManager()->persist($user);
97
            $user->setEmail($email);
98
        }
99
100 1
        return $user;
101
    }
102
}
103