UserAssignRoleAuthorizationChecker   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 80.77%

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 70
ccs 21
cts 26
cp 0.8077
rs 10
c 0
b 0
f 0
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B userRoleIsGranted() 0 46 10
1
<?php
2
3
namespace App\Module\User\AssignRole\Service;
4
5
use App\Application\Data\UserNetworkSessionData;
6
use App\Module\Authorization\Repository\AuthorizationUserRoleFinderRepository;
0 ignored issues
show
Bug introduced by
The type App\Module\Authorization...serRoleFinderRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use App\Module\User\Enum\UserRole;
8
use Psr\Log\LoggerInterface;
9
10
/**
11
 * Check if authenticated user is permitted to do actions
12
 * Roles: newcomer < advisor < managing_advisor < administrator.
13
 */
14
final class UserAssignRoleAuthorizationChecker
15
{
16
    private ?int $loggedInUserId = null;
17
18 39
    public function __construct(
19
        private readonly UserNetworkSessionData $userNetworkSessionData,
20
        private readonly AuthorizationUserRoleFinderRepository $authorizationUserRoleFinderRepository,
21
        private readonly LoggerInterface $logger,
22
    ) {
23
        // Fix error $userId must not be accessed before initialization
24 39
        $this->loggedInUserId = $this->userNetworkSessionData->userId ?? null;
25
    }
26
27
    /**
28
     * Check if the authenticated user is allowed to assign a user role.
29
     *
30
     * @param string|int|null $newUserRoleId (New) user role id to be assigned. Nullable as admins are authorized to
31
     * set any role, validation should check if the value is valid.
32
     * @param string|int|null $userRoleIdOfUserToMutate (Existing) user role of user to be changed
33
     * @param int|null $authenticatedUserRoleHierarchy optional so that it can be called outside this class
34
     * @param array|null $userRoleHierarchies optional so that it can be called outside this class
35
     *
36
     * @return bool
37
     */
38 21
    public function userRoleIsGranted(
39
        string|int|null $newUserRoleId,
40
        string|int|null $userRoleIdOfUserToMutate,
41
        ?int $authenticatedUserRoleHierarchy = null,
42
        ?array $userRoleHierarchies = null,
43
    ): bool {
44 21
        if ($this->loggedInUserId === null) {
45
            $this->logger->error(
46
                'loggedInUserId not set while authorization check that user role is granted $userRoleIdOfUserToMutate: '
47
                . $userRoleIdOfUserToMutate
48
            );
49
50
            return false;
51
        }
52
        // $authenticatedUserRoleData and $userRoleHierarchies passed as arguments if called inside this class
53 21
        if ($authenticatedUserRoleHierarchy === null) {
54 10
            $authenticatedUserRoleHierarchy = $this->authorizationUserRoleFinderRepository->getRoleHierarchyByUserId(
55 10
                $this->loggedInUserId
56 10
            );
57
        }
58 21
        if ($userRoleHierarchies === null) {
59
            // Returns array with role name as key and hierarchy as value ['role_name' => hierarchy_int]
60
            // * Lower hierarchy number means higher privileged role
61 10
            $userRoleHierarchies = $this->authorizationUserRoleFinderRepository->getUserRolesHierarchies();
62
        }
63
64 21
        $userRoleHierarchiesById = $this->authorizationUserRoleFinderRepository->getUserRolesHierarchies(true);
65
66
        // Role higher (lower hierarchy number) than managing advisor may assign any role (admin)
67 21
        if ($authenticatedUserRoleHierarchy < $userRoleHierarchies[UserRole::MANAGING_ADVISOR->value]) {
68 8
            return true;
69
        }
70
71
        if (// Managing advisor can only attribute roles with lower or equal privilege than advisor
72 13
            !empty($newUserRoleId)
73 13
            && $authenticatedUserRoleHierarchy <= $userRoleHierarchies[UserRole::MANAGING_ADVISOR->value]
74 13
            && $userRoleHierarchiesById[$newUserRoleId] >= $userRoleHierarchies[UserRole::ADVISOR->value]
75
            // And managing advisor may only change advisors or newcomers
76 13
            && ($userRoleIdOfUserToMutate === null
77 13
                || $userRoleHierarchiesById[$userRoleIdOfUserToMutate] >=
78 13
                $userRoleHierarchies[UserRole::ADVISOR->value])
79
        ) {
80 4
            return true;
81
        }
82
83 11
        return false;
84
    }
85
}
86