UserRepository   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 59.09%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
eloc 37
c 1
b 0
f 0
dl 0
loc 105
ccs 26
cts 44
cp 0.5909
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getOneById() 0 5 1
A getAccessibleSubQuery() 0 7 2
A createShibboleth() 0 14 1
A getOneByEmail() 0 8 1
A getOneByLogin() 0 8 1
B getLoginPassword() 0 27 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Enum\Site;
8
use Application\Enum\UserType;
9
use Application\Model\User;
10
use Ecodev\Felix\Api\Exception;
11
12
/**
13
 * @extends AbstractRepository<User>
14
 */
15
class UserRepository extends AbstractRepository implements \Ecodev\Felix\Repository\LimitedAccessSubQuery
16
{
17
    /**
18
     * Returns the user authenticated by its login and password.
19
     */
20 2
    public function getLoginPassword(string $login, string $password, Site $site): ?User
21
    {
22 2
        $user = $this->getOneByLogin($login, $site);
23
24 2
        if (!$user) {
25 1
            return null;
26
        }
27
28 2
        if (!$user->canLogin()) {
29
            throw new Exception("Ce compte n'est plus actif");
30
        }
31
32 2
        $hashFromDb = $user->getPassword();
33 2
        $isMd5 = mb_strlen($hashFromDb) === 32 && ctype_xdigit($hashFromDb);
34
35
        // If we found a user and he has a correct MD5 or correct new hash, then return the user
36 2
        if (($isMd5 && md5($password) === $hashFromDb) || password_verify($password, $hashFromDb)) {
37
            // Update the hash in DB, if we are still MD5, or if PHP default options changed
38 2
            if ($isMd5 || password_needs_rehash($hashFromDb, PASSWORD_DEFAULT)) {
39 2
                $user->setPassword($password);
40 2
                $this->getEntityManager()->flush();
41
            }
42
43 2
            return $user;
44
        }
45
46 1
        return null;
47
    }
48
49
    /**
50
     * Unsecured way to get a user from its login.
51
     *
52
     * This should only be used in tests or controlled environment.
53
     */
54 75
    public function getOneByLogin(?string $login, Site $site): ?User
55
    {
56 75
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneBy([
57 75
            'login' => $login,
58 75
            'site' => $site->value,
59 75
        ]));
60
61 75
        return $user;
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 5
    public function getOneById(int $id): ?User
70
    {
71 5
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneById($id));
0 ignored issues
show
Bug introduced by
The method findOneById() does not exist on Application\Repository\UserRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->/** @scrutinizer ignore-call */ findOneById($id));
Loading history...
72
73 5
        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
    public function getOneByEmail(?string $email, Site $site): ?User
82
    {
83
        $user = $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneBy([
84
            'email' => $email,
85
            'site' => $site->value,
86
        ]));
87
88
        return $user;
89
    }
90
91
    /**
92
     * Create new Shibboleth user.
93
     */
94
    public function createShibboleth(string $login, string $email, Site $site): User
95
    {
96
        $user = new User();
97
        $user->setLogin($login);
98
        $user->setEmail($email);
99
        $user->setType(UserType::Aai);
100
        $user->setRole(User::ROLE_STUDENT);
101
        $user->setSite($site);
102
        $user->setName('');
103
104
        $this->getEntityManager()->persist($user);
105
        $this->getEntityManager()->flush();
106
107
        return $user;
108
    }
109
110
    /**
111
     * Returns pure SQL to get ID of all objects that are accessible to given user.
112
     */
113 16
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
114
    {
115 16
        if ($user) {
116 13
            return '';
117
        }
118
119 3
        return '-1';
120
    }
121
}
122