UserProvider   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 1
dl 0
loc 163
ccs 51
cts 51
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A loadUserByUsername() 0 4 1
A loadUserById() 0 4 1
A getAllUserNames() 0 4 1
A generateHash() 0 4 1
A verifyHash() 0 4 1
A changePassword() 0 7 1
A setUserProperty() 0 10 2
A register() 0 23 1
A deleteUser() 0 17 2
A getKey() 0 4 1
1
<?php
2
3
namespace BrainExe\Core\Authentication;
4
5
use BrainExe\Core\Annotations\Service;
6
use BrainExe\Core\Authentication\Event\DeleteUserEvent;
7
use BrainExe\Core\Authentication\Exception\UserNotFoundException;
8
use BrainExe\Core\Traits\EventDispatcherTrait;
9
use BrainExe\Core\Traits\IdGeneratorTrait;
10
use BrainExe\Core\Traits\RedisTrait;
11
12
/**
13
 * @Service
14
 */
15
class UserProvider
16
{
17
18
    use RedisTrait;
19
    use IdGeneratorTrait;
20
    use EventDispatcherTrait;
21
22
    const REDIS_USER       = 'user:%d';
23
    const REDIS_USER_NAMES = 'user_names';
24
25
    /**
26
     * @var PasswordHasher
27
     */
28
    private $hasher;
29
30
    /**
31
     * @var LoadUser
32
     */
33
    private $loadUser;
34
35
    /**
36
     * @param PasswordHasher $passwordHasher
37
     * @param LoadUser $loadUser
38
     */
39 12
    public function __construct(PasswordHasher $passwordHasher, LoadUser $loadUser)
40
    {
41 12
        $this->hasher   = $passwordHasher;
42 12
        $this->loadUser = $loadUser;
43 12
    }
44
45
    /**
46
     * @param string $username
47
     * @return UserVO
48
     * @throws UserNotFoundException
49
     */
50 1
    public function loadUserByUsername(string $username) : UserVO
51
    {
52 1
        return $this->loadUser->loadUserByUsername($username);
53
    }
54
55
    /**
56
     * @param int $userId
57
     * @return UserVO
58
     * @throws UserNotFoundException
59
     */
60 1
    public function loadUserById(int $userId) : UserVO
61
    {
62 1
        return $this->loadUser->loadUserById($userId);
63
    }
64
65
    /**
66
     * @return string[]
67
     */
68 1
    public function getAllUserNames() : array
69
    {
70 1
        return $this->getRedis()->hgetall(self::REDIS_USER_NAMES);
71
    }
72
73
    /**
74
     * @param string $password
75
     * @return string $hash
76
     */
77 3
    public function generateHash(string $password) : string
78
    {
79 3
        return $this->hasher->generateHash($password);
80
    }
81
82
    /**
83
     * @param string $password
84
     * @param string $hash
85
     * @return bool
86
     */
87 1
    public function verifyHash(string $password, string $hash) : bool
88
    {
89 1
        return $this->hasher->verifyHash($password, $hash);
90
    }
91
92
    /**
93
     * @param UserVO $user
94
     * @param string $newPassword
95
     */
96 1
    public function changePassword(UserVO $user, string $newPassword)
97
    {
98 1
        $hash = $this->generateHash($newPassword);
99 1
        $user->password = $hash;
100
101 1
        $this->setUserProperty($user, 'password');
102 1
    }
103
104
    /**
105
     * @param UserVO $userVo
106
     * @param string $property
107
     */
108 3
    public function setUserProperty(UserVO $userVo, string $property)
109
    {
110 3
        $redis = $this->getRedis();
111 3
        $value = $userVo->$property;
112
113 3
        if (is_array($value)) {
114 1
            $value = implode(',', $value);
115
        }
116 3
        $redis->hset($this->getKey($userVo->id), $property, $value);
117 3
    }
118
119
    /**
120
     * @param UserVO $user
121
     * @return int $userId
122
     */
123 1
    public function register(UserVO $user) : int
124
    {
125 1
        $redis = $this->getRedis()->pipeline();
126
127
        $userArray = [
128 1
            'username' => $user->getUsername(),
129 1
            'password' => $this->generateHash($user->password),
130 1
            'roles'    => implode(',', $user->roles),
131 1
            'one_time_secret' => $user->one_time_secret,
132 1
            'avatar'   => $user->avatar
133
        ];
134
135 1
        $newUserId = $this->generateUniqueId('userid');
136
137 1
        $redis->hset(self::REDIS_USER_NAMES, mb_strtolower($user->getUsername()), $newUserId);
138 1
        $redis->hmset($this->getKey($newUserId), $userArray);
139
140 1
        $redis->execute();
141
142 1
        $user->id = $newUserId;
143
144 1
        return $newUserId;
145
    }
146
147
    /**
148
     * @param int $userId
149
     * @return bool
150
     */
151 2
    public function deleteUser(int $userId) : bool
152
    {
153
        try {
154 2
            $user = $this->loadUser->loadUserById($userId);
155 1
        } catch (UserNotFoundException $e) {
156 1
            return false;
157
        }
158
159 1
        $event = new DeleteUserEvent($user, DeleteUserEvent::DELETE);
160 1
        $this->dispatchEvent($event);
161
162 1
        $redis = $this->getRedis();
163 1
        $redis->hdel(self::REDIS_USER_NAMES, mb_strtolower($user->getUsername()));
164 1
        $redis->del($this->getKey($userId));
165
166 1
        return true;
167
    }
168
169
    /**
170
     * @param int $userId
171
     * @return string
172
     */
173 5
    private function getKey(int $userId) : string
174
    {
175 5
        return sprintf(self::REDIS_USER, $userId);
176
    }
177
}
178