Passed
Push — dependabot/npm_and_yarn/nanoid... ( aaf2c9...c4aa90 )
by
unknown
14:37 queued 06:22
created

AzureAuthenticatorHelper::formatUserData()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 36
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 26
nc 8
nop 2
dl 0
loc 36
rs 9.1928
c 1
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\ServiceHelper;
8
9
use Chamilo\CoreBundle\Entity\ExtraField;
10
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
11
use Chamilo\CoreBundle\Entity\User;
12
use Chamilo\CoreBundle\Repository\ExtraFieldRepository;
13
use Chamilo\CoreBundle\Repository\ExtraFieldValuesRepository;
14
use Chamilo\CoreBundle\Repository\Node\UserRepository;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Doctrine\ORM\NonUniqueResultException;
17
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
18
19
readonly class AzureAuthenticatorHelper
20
{
21
    public const EXTRA_FIELD_ORGANISATION_EMAIL = 'organisationemail';
22
    public const EXTRA_FIELD_AZURE_ID = 'azure_id';
23
    public const EXTRA_FIELD_AZURE_UID = 'azure_uid';
24
25
    public function __construct(
26
        private ExtraFieldValuesRepository $extraFieldValuesRepo,
27
        private ExtraFieldRepository $extraFieldRepo,
28
        private UserRepository $userRepository,
29
        private EntityManagerInterface $entityManager,
30
        private AccessUrlHelper $urlHelper,
31
    ) {}
32
33
    /**
34
     * @throws NonUniqueResultException
35
     */
36
    public function registerUser(array $azureUserInfo, string $azureUidKey = 'objectId'): User
37
    {
38
        if (empty($azureUserInfo)) {
39
            throw new UnauthorizedHttpException('User info not found.');
40
        }
41
42
        [
43
            $firstNme,
44
            $lastName,
45
            $username,
46
            $email,
47
            $phone,
48
            $authSource,
49
            $active,
50
            $extra,
51
        ] = $this->formatUserData($azureUserInfo, $azureUidKey);
52
53
        $userId = $this->getUserIdByVerificationOrder($azureUserInfo, $azureUidKey);
54
55
        if (empty($userId)) {
56
            $user = (new User())
57
                ->setCreatorId($this->userRepository->getRootUser()->getId())
58
            ;
59
        } else {
60
            $user = $this->userRepository->find($userId);
61
        }
62
63
        $user
64
            ->setFirstname($firstNme)
65
            ->setLastname($lastName)
66
            ->setEmail($email)
67
            ->setUsername($username)
68
            ->setPlainPassword('azure')
69
            ->setStatus(STUDENT)
70
            ->setAuthSource($authSource)
71
            ->setPhone($phone)
72
            ->setActive($active)
73
            ->setRoleFromStatus(STUDENT)
74
        ;
75
76
        $this->userRepository->updateUser($user);
77
78
        $url = $this->urlHelper->getCurrent();
79
        $url->addUser($user);
80
81
        $this->entityManager->flush();
82
83
        $this->extraFieldValuesRepo->updateItemData(
84
            $this->getOrganizationEmailField(),
85
            $user,
86
            $extra['extra_'.self::EXTRA_FIELD_ORGANISATION_EMAIL]
87
        );
88
89
        $this->extraFieldValuesRepo->updateItemData(
90
            $this->getAzureIdField(),
91
            $user,
92
            $extra['extra_'.self::EXTRA_FIELD_AZURE_ID]
93
        );
94
95
        $this->extraFieldValuesRepo->updateItemData(
96
            $this->getAzureUidField(),
97
            $user,
98
            $extra['extra_'.self::EXTRA_FIELD_AZURE_UID]
99
        );
100
101
        return $user;
102
    }
103
104
    private function getOrganizationEmailField()
105
    {
106
        return $this->extraFieldRepo->findByVariable(
107
            ExtraField::USER_FIELD_TYPE,
108
            self::EXTRA_FIELD_ORGANISATION_EMAIL
109
        );
110
    }
111
112
    private function getAzureIdField()
113
    {
114
        return $this->extraFieldRepo->findByVariable(
115
            ExtraField::USER_FIELD_TYPE,
116
            self::EXTRA_FIELD_AZURE_ID
117
        );
118
    }
119
120
    private function getAzureUidField()
121
    {
122
        return $this->extraFieldRepo->findByVariable(
123
            ExtraField::USER_FIELD_TYPE,
124
            self::EXTRA_FIELD_AZURE_UID
125
        );
126
    }
127
128
    /**
129
     * @throws NonUniqueResultException
130
     */
131
    public function getUserIdByVerificationOrder(array $azureUserData, string $azureUidKey = 'objectId'): ?int
132
    {
133
        $selectedOrder = $this->getExistingUserVerificationOrder();
134
135
        $organisationEmailField = $this->getOrganizationEmailField();
136
        $azureIdField = $this->getAzureIdField();
137
        $azureUidField = $this->getAzureUidField();
138
139
        /** @var array<int, ExtraFieldValues> $positionsAndFields */
140
        $positionsAndFields = [
141
            1 => $this->extraFieldValuesRepo->findByVariableAndValue($organisationEmailField, $azureUserData['mail']),
142
            2 => $this->extraFieldValuesRepo->findByVariableAndValue($azureIdField, $azureUserData['mailNickname']),
143
            3 => $this->extraFieldValuesRepo->findByVariableAndValue($azureUidField, $azureUserData[$azureUidKey]),
144
        ];
145
146
        foreach ($selectedOrder as $position) {
147
            if (!empty($positionsAndFields[$position])) {
148
                return $positionsAndFields[$position]->getItemId();
149
            }
150
        }
151
152
        return null;
153
    }
154
155
    public function getExistingUserVerificationOrder(): array
156
    {
157
        return [1, 2, 3];
158
    }
159
160
    private function formatUserData(
161
        array $azureUserData,
162
        string $azureUidKey
163
    ): array {
164
        $phone = null;
165
166
        if (isset($azureUserData['telephoneNumber'])) {
167
            $phone = $azureUserData['telephoneNumber'];
168
        } elseif (isset($azureUserData['businessPhones'][0])) {
169
            $phone = $azureUserData['businessPhones'][0];
170
        } elseif (isset($azureUserData['mobilePhone'])) {
171
            $phone = $azureUserData['mobilePhone'];
172
        }
173
174
        // If the option is set to create users, create it
175
        $firstNme = $azureUserData['givenName'];
176
        $lastName = $azureUserData['surname'];
177
        $email = $azureUserData['mail'];
178
        $username = $azureUserData['userPrincipalName'];
179
        $authSource = 'azure';
180
        $active = ($azureUserData['accountEnabled'] ? 1 : 0);
181
        $extra = [
182
            'extra_'.self::EXTRA_FIELD_ORGANISATION_EMAIL => $azureUserData['mail'],
183
            'extra_'.self::EXTRA_FIELD_AZURE_ID => $azureUserData['mailNickname'],
184
            'extra_'.self::EXTRA_FIELD_AZURE_UID => $azureUserData[$azureUidKey],
185
        ];
186
187
        return [
188
            $firstNme,
189
            $lastName,
190
            $username,
191
            $email,
192
            $phone,
193
            $authSource,
194
            $active,
195
            $extra,
196
        ];
197
    }
198
}
199