Passed
Pull Request — master (#6396)
by Angel Fernando Quiroz
08:39
created

AzureAuthenticatorHelper   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 99
dl 0
loc 180
rs 10
c 0
b 0
f 0
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A registerUser() 0 69 3
A formatUserData() 0 36 5
A getAzureUidField() 0 5 1
A getUserIdByVerificationOrder() 0 22 3
A getAzureIdField() 0 5 1
A getOrganizationEmailField() 0 5 1
A getExistingUserVerificationOrder() 0 3 1
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Helpers;
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 $accessUrlHelper,
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
            ->addAuthSourceByAuthentication(
71
                $authSource,
72
                $this->accessUrlHelper->getCurrent()
73
            )
74
            ->setPhone($phone)
75
            ->setActive($active)
76
            ->setRoleFromStatus(STUDENT)
77
        ;
78
79
        $this->userRepository->updateUser($user);
80
81
        $url = $this->accessUrlHelper->getCurrent();
82
        $url->addUser($user);
83
84
        $this->entityManager->flush();
85
86
        $this->extraFieldValuesRepo->updateItemData(
87
            $this->getOrganizationEmailField(),
88
            $user,
89
            $extra['extra_'.self::EXTRA_FIELD_ORGANISATION_EMAIL]
90
        );
91
92
        $this->extraFieldValuesRepo->updateItemData(
93
            $this->getAzureIdField(),
94
            $user,
95
            $extra['extra_'.self::EXTRA_FIELD_AZURE_ID]
96
        );
97
98
        $this->extraFieldValuesRepo->updateItemData(
99
            $this->getAzureUidField(),
100
            $user,
101
            $extra['extra_'.self::EXTRA_FIELD_AZURE_UID]
102
        );
103
104
        return $user;
105
    }
106
107
    private function getOrganizationEmailField()
108
    {
109
        return $this->extraFieldRepo->findByVariable(
110
            ExtraField::USER_FIELD_TYPE,
111
            self::EXTRA_FIELD_ORGANISATION_EMAIL
112
        );
113
    }
114
115
    private function getAzureIdField()
116
    {
117
        return $this->extraFieldRepo->findByVariable(
118
            ExtraField::USER_FIELD_TYPE,
119
            self::EXTRA_FIELD_AZURE_ID
120
        );
121
    }
122
123
    private function getAzureUidField()
124
    {
125
        return $this->extraFieldRepo->findByVariable(
126
            ExtraField::USER_FIELD_TYPE,
127
            self::EXTRA_FIELD_AZURE_UID
128
        );
129
    }
130
131
    /**
132
     * @throws NonUniqueResultException
133
     */
134
    public function getUserIdByVerificationOrder(array $azureUserData, string $azureUidKey = 'objectId'): ?int
135
    {
136
        $selectedOrder = $this->getExistingUserVerificationOrder();
137
138
        $organisationEmailField = $this->getOrganizationEmailField();
139
        $azureIdField = $this->getAzureIdField();
140
        $azureUidField = $this->getAzureUidField();
141
142
        /** @var array<int, ExtraFieldValues> $positionsAndFields */
143
        $positionsAndFields = [
144
            1 => $this->extraFieldValuesRepo->findByVariableAndValue($organisationEmailField, $azureUserData['mail']),
145
            2 => $this->extraFieldValuesRepo->findByVariableAndValue($azureIdField, $azureUserData['mailNickname']),
146
            3 => $this->extraFieldValuesRepo->findByVariableAndValue($azureUidField, $azureUserData[$azureUidKey]),
147
        ];
148
149
        foreach ($selectedOrder as $position) {
150
            if (!empty($positionsAndFields[$position])) {
151
                return $positionsAndFields[$position]->getItemId();
152
            }
153
        }
154
155
        return null;
156
    }
157
158
    public function getExistingUserVerificationOrder(): array
159
    {
160
        return [1, 2, 3];
161
    }
162
163
    private function formatUserData(
164
        array $azureUserData,
165
        string $azureUidKey
166
    ): array {
167
        $phone = null;
168
169
        if (isset($azureUserData['telephoneNumber'])) {
170
            $phone = $azureUserData['telephoneNumber'];
171
        } elseif (isset($azureUserData['businessPhones'][0])) {
172
            $phone = $azureUserData['businessPhones'][0];
173
        } elseif (isset($azureUserData['mobilePhone'])) {
174
            $phone = $azureUserData['mobilePhone'];
175
        }
176
177
        // If the option is set to create users, create it
178
        $firstNme = $azureUserData['givenName'];
179
        $lastName = $azureUserData['surname'];
180
        $email = $azureUserData['mail'];
181
        $username = $azureUserData['userPrincipalName'];
182
        $authSource = 'azure';
183
        $active = ($azureUserData['accountEnabled'] ? 1 : 0);
184
        $extra = [
185
            'extra_'.self::EXTRA_FIELD_ORGANISATION_EMAIL => $azureUserData['mail'],
186
            'extra_'.self::EXTRA_FIELD_AZURE_ID => $azureUserData['mailNickname'],
187
            'extra_'.self::EXTRA_FIELD_AZURE_UID => $azureUserData[$azureUidKey],
188
        ];
189
190
        return [
191
            $firstNme,
192
            $lastName,
193
            $username,
194
            $email,
195
            $phone,
196
            $authSource,
197
            $active,
198
            $extra,
199
        ];
200
    }
201
}
202