ClientUpdateAuthorizationChecker::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 5
dl 0
loc 8
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace App\Module\Client\Update\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\Client\AssignUser\Service\ClientAssignUserAuthorizationChecker;
8
use App\Module\Client\Delete\Service\ClientDeleteAuthorizationChecker;
9
use App\Module\Note\Update\Service\NoteUpdateAuthorizationChecker;
0 ignored issues
show
Bug introduced by
The type App\Module\Note\Update\S...ateAuthorizationChecker 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...
10
use App\Module\User\Enum\UserRole;
11
use Psr\Log\LoggerInterface;
12
13
/**
14
 * Check if the authenticated user is permitted to do actions.
15
 * Roles: newcomer < advisor < managing_advisor < administrator.
16
 */
17
final class ClientUpdateAuthorizationChecker
18
{
19
    private ?int $loggedInUserId = null;
20
21 30
    public function __construct(
22
        private readonly AuthorizationUserRoleFinderRepository $authorizationUserRoleFinderRepository,
23
        private readonly ClientAssignUserAuthorizationChecker $clientAssignUserAuthorizationChecker,
24
        private readonly ClientDeleteAuthorizationChecker $clientDeleteAuthorizationChecker,
25
        private readonly UserNetworkSessionData $userNetworkSessionData,
26
        private readonly LoggerInterface $logger,
27
    ) {
28 30
        $this->loggedInUserId = $this->userNetworkSessionData->userId;
29
    }
30
31
    /**
32
     * Logic to check if authenticated user is granted to update client.
33
     *
34
     * @param array $clientDataToUpdate validated array with as key the column to
35
     * update and value the new value (or fictive "value").
36
     * There may be one or multiple entries, depending on what the user wants to update.
37
     * @param int|null $ownerId user_id linked to client
38
     * @param bool $log log if forbidden (expected false when function is called for privilege setting)
39
     *
40
     * @return bool
41
     */
42 19
    public function isGrantedToUpdate(array $clientDataToUpdate, ?int $ownerId, bool $log = true): bool
43
    {
44 19
        $grantedUpdateKeys = [];
45 19
        if ($this->loggedInUserId === null) {
46
            $this->logger->error(
47
                'loggedInUserId not set while isGrantedToUpdate authorization check $clientDataToUpdate: '
48
                . json_encode($clientDataToUpdate, JSON_PARTIAL_OUTPUT_ON_ERROR)
49
            );
50
51
            return false;
52
        }
53 19
        $authenticatedUserRoleHierarchy = $this->authorizationUserRoleFinderRepository->getRoleHierarchyByUserId(
54 19
            $this->loggedInUserId
55 19
        );
56
        // Returns array with role name as key and hierarchy as value ['role_name' => hierarchy_int]
57
        // * Lower hierarchy number means higher privileged role
58 19
        $userRoleHierarchies = $this->authorizationUserRoleFinderRepository->getUserRolesHierarchies();
59
60
        // Roles: newcomer < advisor < managing_advisor < administrator
61
        // If logged-in hierarchy value is smaller or equal advisor -> granted
62 19
        if ($authenticatedUserRoleHierarchy <= $userRoleHierarchies[UserRole::ADVISOR->value]) {
63
            // Things that advisor is allowed to change for all client records even when not owner
64
            // "personal_info" is the same as the group of columns that follows it
65 9
            $grantedUpdateKeys[] = 'personal_info';
66
            // Same as personal info but in separate columns to be returned as granted keys
67 9
            $grantedUpdateKeys[] = 'first_name';
68 9
            $grantedUpdateKeys[] = 'last_name';
69 9
            $grantedUpdateKeys[] = 'birthdate';
70 9
            $grantedUpdateKeys[] = 'location';
71 9
            $grantedUpdateKeys[] = 'phone';
72 9
            $grantedUpdateKeys[] = 'email';
73 9
            $grantedUpdateKeys[] = 'sex';
74 9
            $grantedUpdateKeys[] = 'vigilance_level';
75
76
            /** Update main note authorization is in @see NoteUpdateAuthorizationChecker::isGrantedToUpdate () */
77
78
            // Everything that owner and managing_advisor is permitted to do
79
            // advisor may only edit client_status_id if they are owner | managing_advisor and higher is allowed
80 9
            if ($this->loggedInUserId === $ownerId
81 9
                || $authenticatedUserRoleHierarchy <= $userRoleHierarchies[UserRole::MANAGING_ADVISOR->value]) {
82
                // Check if client_status_id is among data to be changed if yes add it to $grantedUpdateKeys array
83 5
                if (array_key_exists('client_status_id', $clientDataToUpdate)) {
84 2
                    $grantedUpdateKeys[] = 'client_status_id';
85
                }
86
            }
87
88
            // Assign user to client
89 9
            if (array_key_exists('user_id', $clientDataToUpdate)
90 9
                && $this->clientAssignUserAuthorizationChecker->isGrantedToAssignUserToClient(
91 9
                    $clientDataToUpdate['user_id'],
92 9
                    $authenticatedUserRoleHierarchy,
93 9
                    $userRoleHierarchies
94 9
                )
95
96
                //         // Advisors (already checked above) may only assign clients to themselves or unassign themselves
97
                //         ($this->loggedInUserId === $clientDataToUpdate['user_id'] || $clientDataToUpdate['user_id'] === null)
98
                //         // Managing_advisor and higher may assign clients to any advisor
99
                //         || ($authenticatedUserRoleHierarchy <= $userRoleHierarchies[UserRole::MANAGING_ADVISOR->value])
100
                //     )
101
102
                // isGrantedToAssignUserToClient CANNOT be used as it expects a real user_id which is not provided
103
                // in the case where user_id value is the string "value" from (ClientPrivilegeDeterminer) to check if
104
                // the authenticated user is allowed to change the assigned user. (To enable/disable html <select>)
105
106
            ) {
107 1
                $grantedUpdateKeys[] = 'user_id';
108
            }
109
110
            // If there is a request to undelete coming from the client,
111
            // the same authorization rules than deletion are valid
112 9
            if (array_key_exists('deleted_at', $clientDataToUpdate)
113 9
                && $this->clientDeleteAuthorizationChecker->isGrantedToDelete($ownerId, $log)) {
114 1
                $grantedUpdateKeys[] = 'deleted_at';
115
            }
116
        }
117
        // If data that the user wanted to update and the grantedUpdateKeys are equal by having the same keys -> granted
118 19
        foreach ($clientDataToUpdate as $key => $value) {
119
            // If at least one array key doesn't exist in $grantedUpdateKeys it means that user is not permitted
120 19
            if (!in_array($key, $grantedUpdateKeys, true)) {
121 14
                if ($log === true) {
122 4
                    $this->logger->notice(
123 4
                        'User ' . $this->loggedInUserId . ' tried to update client but isn\'t allowed to change' .
124 4
                        $key . ' to "' . $value . '".'
125 4
                    );
126
                }
127
128 14
                return false;
129
            }
130
        }
131
132 6
        return true;
133
    }
134
}
135