Passed
Push — master ( 658945...f0b652 )
by Petr
02:27
created

AccountsDatabase   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Test Coverage

Coverage 6.94%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 64
c 1
b 0
f 0
dl 0
loc 185
ccs 5
cts 72
cp 0.0694
rs 10
wmc 21

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getByLogin() 0 9 2
A updatePassword() 0 7 1
A updateAccount() 0 10 1
A readAccounts() 0 4 1
A checkLogin() 0 14 5
A updateCertKeys() 0 8 1
A authenticate() 0 13 5
A createAccount() 0 8 1
A getCertData() 0 3 1
A __construct() 0 5 1
A deleteAccount() 0 5 1
A getDataOnly() 0 3 1
1
<?php
2
3
namespace kalanis\kw_auth_sources\Sources\Mapper;
4
5
6
use kalanis\kw_auth_sources\AuthSourcesException;
7
use kalanis\kw_auth_sources\Interfaces;
8
use kalanis\kw_auth_sources\Traits\TLang;
9
use kalanis\kw_auth_sources\Traits\TSeparated;
10
use kalanis\kw_mapper\MapperException;
11
use kalanis\kw_mapper\Search\Search;
12
13
14
/**
15
 * Class Database
16
 * @package kalanis\kw_auth_sources\Sources\Mapper
17
 * Authenticate via Database
18
 * need kw_mapper!
19
 * @codeCoverageIgnore because access external content
20
 */
21
class AccountsDatabase implements Interfaces\IAuthCert, Interfaces\IWorkAccounts
22
{
23
    use TLang;
24
    use TSeparated;
25
26
    /** @var Interfaces\IHashes */
27
    protected $passMode = null;
28
    /** @var Database\UsersRecord */
29
    protected $usersRecord = null;
30
31 1
    public function __construct(Interfaces\IHashes $mode, ?Interfaces\IKAusTranslations $lang = null)
32
    {
33 1
        $this->setAusLang($lang);
34 1
        $this->passMode = $mode;
35 1
        $this->usersRecord = new Database\UsersRecord();
36 1
    }
37
38
    /**
39
     * @param string $userName
40
     * @param array<string, string|int|float> $params
41
     * @throws AuthSourcesException
42
     * @throws MapperException
43
     * @return Interfaces\IUser|null
44
     */
45
    public function authenticate(string $userName, array $params = []): ?Interfaces\IUser
46
    {
47
        if (!isset($params['password'])) {
48
            throw new AuthSourcesException($this->getAusLang()->kauPassMustBeSet());
49
        }
50
        $record = $this->getByLogin($userName);
51
        if (empty($record)) {
52
            return null;
53
        }
54
        if (!$this->passMode->checkHash(isset($params['password']) ? strval($params['password']): '', $record->pass)) {
55
            return null;
56
        }
57
        return $record;
58
    }
59
60
    /**
61
     * @param string $userName
62
     * @throws MapperException
63
     * @return Interfaces\IUser|null
64
     */
65
    public function getDataOnly(string $userName): ?Interfaces\IUser
66
    {
67
        return $this->getByLogin($userName);
68
    }
69
70
    /**
71
     * @param string $userName
72
     * @param string|null $certKey
73
     * @param string|null $certSalt
74
     * @throws MapperException
75
     * @return bool
76
     */
77
    public function updateCertKeys(string $userName, ?string $certKey, ?string $certSalt): bool
78
    {
79
        $record = clone $this->usersRecord;
80
        $record->login = $userName;
81
        $record->load();
82
        $record->cert = strval($certKey);
83
        $record->salt = strval($certSalt);
84
        return $record->save();
85
    }
86
87
    /**
88
     * @param string $userName
89
     * @throws MapperException
90
     * @return Interfaces\IUserCert|null
91
     */
92
    public function getCertData(string $userName): ?Interfaces\IUserCert
93
    {
94
        return $this->getByLogin($userName);
95
    }
96
97
    /**
98
     * @param string $login
99
     * @throws MapperException
100
     * @return Database\UsersRecord|null
101
     */
102
    protected function getByLogin(string $login): ?Database\UsersRecord
103
    {
104
        $record = clone $this->usersRecord;
105
        $record->login = $login;
106
        if (empty($record->count())) {
107
            return null;
108
        }
109
        $record->load();
110
        return $record;
111
    }
112
113
    /**
114
     * @param Interfaces\IUser $user
115
     * @param string $password
116
     * @throws AuthSourcesException
117
     * @throws MapperException
118
     * @return bool
119
     */
120
    public function createAccount(Interfaces\IUser $user, string $password): bool
121
    {
122
        $record = clone $this->usersRecord;
123
        $this->checkLogin($user->getAuthName());
124
        $record->login = $user->getAuthName();
125
        $record->groupId = $user->getGroup();
126
        $record->display = $user->getDisplayName();
127
        return $record->save(true);
128
    }
129
130
    /**
131
     * @throws MapperException
132
     * @return Database\UsersRecord[]
133
     */
134
    public function readAccounts(): array
135
    {
136
        $search = new Search(clone $this->usersRecord);
137
        return $search->getResults();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $search->getResults() returns the type kalanis\kw_mapper\Records\ARecord[] which is incompatible with the return type mandated by kalanis\kw_auth_sources\...ccounts::readAccounts() of kalanis\kw_auth_sources\Interfaces\IUser[].

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
138
    }
139
140
    /**
141
     * @param Interfaces\IUser $user
142
     * @throws AuthSourcesException
143
     * @throws MapperException
144
     * @return bool
145
     */
146
    public function updateAccount(Interfaces\IUser $user): bool
147
    {
148
        $this->checkLogin($user->getAuthName(), $user->getAuthId());
149
        $record = clone $this->usersRecord;
150
        $record->id = $user->getAuthId();
151
        $record->load();
152
        $record->login = $user->getAuthName();
153
        $record->groupId = $user->getGroup();
154
        $record->display = $user->getDisplayName();
155
        return $record->save();
156
    }
157
158
    /**
159
     * @param string $userName
160
     * @param string $passWord
161
     * @throws AuthSourcesException
162
     * @throws MapperException
163
     * @return bool
164
     */
165
    public function updatePassword(string $userName, string $passWord): bool
166
    {
167
        $record = clone $this->usersRecord;
168
        $record->login = $userName;
169
        $record->load();
170
        $record->pass = $this->passMode->createHash($passWord);
171
        return $record->save();
172
    }
173
174
    /**
175
     * @param string $userName
176
     * @throws MapperException
177
     * @return bool
178
     */
179
    public function deleteAccount(string $userName): bool
180
    {
181
        $record = clone $this->usersRecord;
182
        $record->login = $userName;
183
        return $record->delete();
184
    }
185
186
    /**
187
     * @param string $login
188
     * @param string $id
189
     * @throws AuthSourcesException
190
     * @throws MapperException
191
     */
192
    protected function checkLogin(string $login, string $id = '0'): void
193
    {
194
        $user = clone $this->usersRecord;
195
        $user->login = $login;
196
        $amount = $user->count();
197
        if (1 > $amount) {
198
            return;
199
        }
200
        if (1 < $amount) {
201
            throw new AuthSourcesException('Too many users with that login!');
202
        }
203
        $user->load();
204
        if ($id && ($user->id != $id)) {
205
            throw new AuthSourcesException('Login already used.');
206
        }
207
    }
208
}
209