Passed
Push — master ( a46d73...177b0c )
by Petr
08:04
created

CompositeSources::updateCertData()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
cc 3
nc 4
nop 3
crap 3
1
<?php
2
3
namespace kalanis\kw_auth_groups\Access;
4
5
6
use kalanis\kw_accounts\AccountsException;
7
use kalanis\kw_accounts\Interfaces;
8
use kalanis\kw_auth_sources\Access as source_access;
9
use kalanis\kw_auth_groups\Sources\KwAuth;
10
use kalanis\kw_groups\GroupsException;
11
use kalanis\kw_groups\Interfaces\IProcessor;
12
use kalanis\kw_groups\Processor\Basic;
13
14
15
/**
16
 * Class CompositeSources
17
 * @package kalanis\kw_auth_groups\Access
18
 *
19
 * todo: next step: separate user rights themselves and system consistency checks
20
 */
21
class CompositeSources extends source_access\CompositeSources
22
{
23
    /** @var IProcessor */
24
    protected $libGroup = null;
25
    /** @var Interfaces\IUser|null */
26
    protected $currentUser = null;
27
28 66
    public function __construct(source_access\SourcesAdapters\AAdapter $adapter, ?IProcessor $libGroup = null)
29
    {
30 66
        parent::__construct($adapter);
31 66
        $this->libGroup = $libGroup ?: new Basic(new KwAuth($adapter->getGroups()));
32 66
    }
33
34
    /**
35
     * @param string $userName
36
     * @throws AccountsException
37
     * @throws GroupsException
38
     * @return Interfaces\IUser|null
39
     */
40 13
    public function getDataOnly(string $userName): ?Interfaces\IUser
41
    {
42 13
        $data = parent::getDataOnly($userName);
43 13
        return $data && $this->canAccessUser($data)
44 6
            ? $data
45 13
            : null
46
        ;
47
    }
48
49
    /**
50
     * @param string $userName
51
     * @throws AccountsException
52
     * @throws GroupsException
53
     * @return Interfaces\ICert|null
54
     */
55 8
    public function getCertData(string $userName): ?Interfaces\ICert
56
    {
57 8
        $data = parent::getDataOnly($userName);
58 8
        return $data && $this->canAccessUser($data)
59 3
            ? parent::getCertData($userName)
60 8
            : null
61
        ;
62
    }
63
64
    /**
65
     * @param Interfaces\IUser $user
66
     * @param string $password
67
     * @throws AccountsException
68
     * @throws GroupsException
69
     * @return bool
70
     */
71 4
    public function createAccount(Interfaces\IUser $user, string $password): bool
72
    {
73 4
        return $this->canAccessUserByClassId($user->getClass()) && !$this->currentUserRepresents($user)
74 2
            ? parent::createAccount($user, $password)
75 4
            : false
76
        ;
77
    }
78
79
    /**
80
     * @throws AccountsException
81
     * @throws GroupsException
82
     * @return Interfaces\IUser[]
83
     */
84 4
    public function readAccounts(): array
85
    {
86 4
        $availableAccounts = [];
87
        /** @var Interfaces\IUser[] $allAccounts */
88 4
        $allAccounts = parent::readAccounts();
89 4
        foreach ($allAccounts as $account) {
90 3
            if ($this->canAccessUserByClassId($account->getClass()) && $this->isCurrentUserRepresented($account)) {
91 2
                $availableAccounts[] = $account;
92
            }
93
        }
94 4
        return $availableAccounts;
95
    }
96
97
    /**
98
     * @param Interfaces\IUser $user
99
     * @throws AccountsException
100
     * @throws GroupsException
101
     * @return bool
102
     */
103 7
    public function updateAccount(Interfaces\IUser $user): bool
104
    {
105 7
        return $this->canAccessUser($user)
106 5
            ? parent::updateAccount($user)
107 7
            : false
108
        ;
109
    }
110
111
    /**
112
     * @param string $userName
113
     * @param string $passWord
114
     * @throws AccountsException
115
     * @throws GroupsException
116
     * @return bool
117
     */
118 7
    public function updatePassword(string $userName, string $passWord): bool
119
    {
120 7
        $user = parent::getDataOnly($userName);
121 7
        return $user && $this->canAccessUser($user)
122 4
            ? parent::updatePassword($userName, $passWord)
123 7
            : false
124
        ;
125
    }
126
127
    /**
128
     * @param string $userName
129
     * @param string|null $certKey
130
     * @param string|null $certSalt
131
     * @throws AccountsException
132
     * @throws GroupsException
133
     * @return bool
134
     */
135 8
    public function updateCertData(string $userName, ?string $certKey, ?string $certSalt): bool
136
    {
137 8
        $user = $this->getDataOnly($userName);
138 8
        return $user && $this->canAccessUser($user)
139 3
            ? parent::updateCertData($userName, $certKey, $certSalt)
140 8
            : false
141
        ;
142
    }
143
144
    /**
145
     * @param string $userName
146
     * @throws AccountsException
147
     * @throws GroupsException
148
     * @return bool
149
     */
150 7
    public function deleteAccount(string $userName): bool
151
    {
152 7
        $user = parent::getDataOnly($userName);
153 7
        return $user && $this->canAccessUserByClassId($user->getClass()) && !$this->currentUserRepresents($user)
154 3
            ? parent::deleteAccount($userName)
155 7
            : false
156
        ;
157
    }
158
159
    /**
160
     * All lower classes than user has
161
     * @throws GroupsException
162
     * @return array<int, string>
163
     */
164 6
    public function readClasses(): array
165
    {
166 6
        $availableClasses = [];
167 6
        foreach (parent::readClasses() as $classId => $className) {
168 6
            if ($this->canAccessUserByClassId($classId)) {
169 3
                $availableClasses[$classId] = $className;
170
            }
171
        }
172 6
        return $availableClasses;
173
    }
174
175
    /**
176
     * @param Interfaces\IGroup $group
177
     * @throws AccountsException
178
     * @throws GroupsException
179
     * @return bool
180
     */
181 7
    public function createGroup(Interfaces\IGroup $group): bool
182
    {
183 7
        $reGroup = clone $group;
184 7
        $reGroup->setGroupData(
185 7
            $group->getGroupId(),
186 7
            $group->getGroupName(),
187 7
            $group->getGroupDesc(),
188 7
            $this->getCurrentUser()->getAuthId(),
189 7
            $group->getGroupStatus(),
190 7
            $group->getGroupParents(),
191 7
            $group->getGroupExtra()
192
        );
193
194 7
        return ($this->canAccessGroup($reGroup) && !$this->isAlreadyInParents($reGroup))
195 4
            ? parent::createGroup($reGroup)
196 7
            : false
197
        ;
198
    }
199
200
    /**
201
     * @param string $groupId
202
     * @throws AccountsException
203
     * @throws GroupsException
204
     * @return Interfaces\IGroup|null
205
     */
206 11
    public function getGroupDataOnly(string $groupId): ?Interfaces\IGroup
207
    {
208 11
        $thisGroup = null;
209 11
        foreach (parent::readGroup() as $group) {
210
            /** @var Interfaces\IGroup $group */
211 10
            if ($group->getGroupId() == $groupId) {
212 9
                $thisGroup = $group;
213 9
                break;
214
            }
215
        }
216 11
        if (!$thisGroup) {
217 6
            return null;
218
        }
219
220 9
        return ($this->canAccessGroup($thisGroup))
221 5
            ? $thisGroup
222 9
            : null
223
        ;
224
    }
225
226
    /**
227
     * @throws AccountsException
228
     * @throws GroupsException
229
     * @return Interfaces\IGroup[]
230
     */
231 5
    public function readGroup(): array
232
    {
233 5
        $availableGroups = [];
234 5
        foreach (parent::readGroup() as $group) {
235
            /** @var Interfaces\IGroup $group */
236 4
            if ($this->canAccessGroup($group)) {
237 2
                $availableGroups[] = $group;
238
            }
239
        }
240 5
        return $availableGroups;
241
    }
242
243
    /**
244
     * @param Interfaces\IGroup $group
245
     * @throws AccountsException
246
     * @throws GroupsException
247
     * @return bool
248
     */
249 5
    public function updateGroup(Interfaces\IGroup $group): bool
250
    {
251 5
        return $this->canAccessGroup($group) && !$this->isAlreadyInParents($group)
252 2
            ? parent::updateGroup($group)
253 5
            : false
254
        ;
255
    }
256
257
    /**
258
     * @param string $groupId
259
     * @throws AccountsException
260
     * @throws GroupsException
261
     * @return bool
262
     */
263 5
    public function deleteGroup(string $groupId): bool
264
    {
265 5
        $group = $this->getGroupDataOnly($groupId);
266 5
        return $group && !$this->hasChildren($group)
267 2
            ? parent::deleteGroup($groupId)
268 5
            : false
269
        ;
270
    }
271
272 2
    public function getAuth(): Interfaces\IAuth
273
    {
274 2
        return $this;
275
    }
276
277 2
    public function getAccounts(): Interfaces\IProcessAccounts
278
    {
279 2
        return $this;
280
    }
281
282 1
    public function getGroups(): Interfaces\IProcessGroups
283
    {
284 1
        return $this;
285
    }
286
287 1
    public function getClasses(): Interfaces\IProcessClasses
288
    {
289 1
        return $this;
290
    }
291
292 63
    public function setCurrentUser(?Interfaces\IUser $user): self
293
    {
294 63
        $this->currentUser = $user;
295 63
        return $this;
296
    }
297
298
    /**
299
     * @throws GroupsException
300
     * @return Interfaces\IUser
301
     */
302 62
    public function getCurrentUser(): Interfaces\IUser
303
    {
304 62
        if (empty($this->currentUser)) {
305 1
            throw new GroupsException('Set Current User first!');
306
        }
307 62
        return $this->currentUser;
308
    }
309
310
    /**
311
     * @param Interfaces\IUser $user
312
     * @throws GroupsException
313
     * @return bool
314
     */
315 27
    protected function canAccessUser(Interfaces\IUser $user): bool
316
    {
317 27
        return $this->isMe($user) || $this->canAccessUserByClassId($user->getClass()) || $this->isCurrentUserRepresented($user);
318
    }
319
320
    /**
321
     * Aktualni Zastupuje dodavaneho
322
     * Aktualni je potomek dodavaneho
323
     * @param Interfaces\IUser $data
324
     * @throws GroupsException
325
     * @return bool
326
     */
327 6
    protected function currentUserRepresents(Interfaces\IUser $data): bool
328
    {
329
//print_r(['grp child', $this->getCurrentUser()->getGroup(), $data->getGroup(), intval($this->libGroup->canAccess($this->getCurrentUser()->getGroup(), $data->getGroup()))]);
330 6
        return $this->libGroup->canAccess($this->getCurrentUser()->getGroup(), $data->getGroup());
331
    }
332
333
    /**
334
     * Akntualni Je zastupovan dodanym
335
     * Aktualni je rodic dodavaneho
336
     * @param Interfaces\IUser $data
337
     * @throws GroupsException
338
     * @return bool
339
     */
340 12
    protected function isCurrentUserRepresented(Interfaces\IUser $data): bool
341
    {
342
//print_r(['grp parent', $this->getCurrentUser()->getGroup(), $data->getGroup(), intval($this->libGroup->canAccess($data->getGroup(), $this->getCurrentUser()->getGroup()))]);
343 12
        return $this->libGroup->canAccess($data->getGroup(), $this->getCurrentUser()->getGroup());
344
    }
345
346
    /**
347
     * @param int $class
348
     * @throws GroupsException
349
     * @return bool
350
     */
351 35
    protected function canAccessUserByClassId(int $class): bool
352
    {
353 35
        return $this->getCurrentUser()->getClass() < $class;
354
    }
355
356
    /**
357
     * @param Interfaces\IUser $data
358
     * @throws GroupsException
359
     * @return bool
360
     */
361 27
    protected function isMe(Interfaces\IUser $data): bool
362
    {
363 27
        return $this->getCurrentUser()->getAuthId() == $data->getAuthId();
364
    }
365
366
    /**
367
     * @param Interfaces\IGroup $data
368
     * @throws GroupsException
369
     * @return bool
370
     */
371 22
    protected function canAccessGroup(Interfaces\IGroup $data): bool
372
    {
373 22
        return $this->isMaintainer() || $this->canProcess($data);
374
    }
375
376
    /**
377
     * @throws GroupsException
378
     * @return bool
379
     */
380 22
    protected function isMaintainer(): bool
381
    {
382 22
        return Interfaces\IProcessClasses::CLASS_MAINTAINER == $this->getCurrentUser()->getClass();
383
    }
384
385
    /**
386
     * @param Interfaces\IGroup $group
387
     * @throws GroupsException
388
     * @return bool
389
     */
390 17
    protected function canProcess(Interfaces\IGroup $group): bool
391
    {
392 17
        $current = $this->getCurrentUser();
393
        return
394 17
            Interfaces\IProcessClasses::CLASS_ADMIN == $current->getClass()
395
            && (
396 6
                $group->getGroupAuthorId() == $current->getAuthId()
397
                || (
398 4
                    $group->getGroupId()
399 17
                    && $this->libGroup->canAccess($group->getGroupId(), $current->getGroup())
400
                )
401
            )
402
        ;
403
    }
404
405
    /**
406
     * @param Interfaces\IGroup $group
407
     * @throws GroupsException
408
     * @return bool
409
     */
410 4
    protected function isAlreadyInParents(Interfaces\IGroup $group): bool
411
    {
412 4
        foreach ($group->getGroupParents() as $groupParent) {
413 4
            if ($this->libGroup->canAccess($groupParent, $group->getGroupId())) {
414 2
                return true;
415
            }
416
        }
417 4
        return false;
418
    }
419
420
    /**
421
     * @param Interfaces\IGroup $group
422
     * @throws AccountsException
423
     * @return bool
424
     */
425 2
    protected function hasChildren(Interfaces\IGroup $group): bool
426
    {
427 2
        $allGroups = $this->adapter->getGroups()->readGroup();
428 2
        foreach ($allGroups as $sourceGroup) {
429 2
            if (in_array($group->getGroupId(), $sourceGroup->getGroupParents())) {
430 2
                return true;
431
            }
432
        }
433 2
        return false;
434
    }
435
}
436