Passed
Push — master ( c5fe4d...3f6d29 )
by Angel Fernando Quiroz
08:23 queued 14s
created

AzureAuthenticator::userLoader()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 50
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 9
eloc 25
nc 6
nop 1
dl 0
loc 50
rs 8.0555
c 2
b 1
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Security\Authenticator\OAuth2;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Helpers\AccessUrlHelper;
11
use Chamilo\CoreBundle\Helpers\AuthenticationConfigHelper;
12
use Chamilo\CoreBundle\Helpers\AzureAuthenticatorHelper;
13
use Chamilo\CoreBundle\Repository\Node\UserRepository;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Doctrine\ORM\NonUniqueResultException;
16
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
17
use League\OAuth2\Client\Token\AccessToken;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
20
use Symfony\Component\Routing\RouterInterface;
21
use TheNetworg\OAuth2\Client\Provider\Azure;
22
23
class AzureAuthenticator extends AbstractAuthenticator
24
{
25
    protected string $providerName = 'azure';
26
27
    public function __construct(
28
        ClientRegistry $clientRegistry,
29
        RouterInterface $router,
30
        UserRepository $userRepository,
31
        AuthenticationConfigHelper $authenticationConfigHelper,
32
        AccessUrlHelper $urlHelper,
33
        EntityManagerInterface $entityManager,
34
        private readonly AzureAuthenticatorHelper $azureHelper,
35
    ) {
36
        parent::__construct(
37
            $clientRegistry,
38
            $router,
39
            $userRepository,
40
            $authenticationConfigHelper,
41
            $urlHelper,
42
            $entityManager
43
        );
44
    }
45
46
    public function supports(Request $request): ?bool
47
    {
48
        return 'chamilo.oauth2_azure_check' === $request->attributes->get('_route');
49
    }
50
51
    /**
52
     * @throws NonUniqueResultException
53
     */
54
    protected function userLoader(AccessToken $accessToken): User
55
    {
56
        /** @var Azure $provider */
57
        $provider = $this->client->getOAuth2Provider();
58
59
        $me = $provider->get(
60
            \sprintf('/v1.0/me?$select=%s', implode(',', AzureAuthenticatorHelper::QUERY_USER_FIELDS)),
61
            $accessToken
62
        );
63
64
        if (empty($me['mail'])) {
65
            throw new UnauthorizedHttpException('The mail field is empty in Azure AD and is needed to set the organisation email for this user.');
66
        }
67
68
        if (empty($me['mailNickname'])) {
69
            throw new UnauthorizedHttpException('The mailNickname field is empty in Azure AD and is needed to set the unique username for this user.');
70
        }
71
72
        if (empty($me['id'])) {
73
            throw new UnauthorizedHttpException('The id field is empty in Azure AD and is needed to set the unique Azure ID for this user.');
74
        }
75
76
        $providerParams = $this->authenticationConfigHelper->getProviderConfig($this->providerName);
77
78
        $user = $this->azureHelper->registerUser($me);
79
80
        $roleActions = $this->azureHelper->getUpdateActionByRole();
81
82
        if ($roleActions) {
0 ignored issues
show
introduced by
$roleActions is a non-empty array, thus is always true.
Loading history...
Bug Best Practice introduced by
The expression $roleActions of type array<string,callable> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
83
            $azureGroups = $provider->get('/v1.0/me/memberOf', $accessToken);
84
85
            foreach ($providerParams['group_id'] as $userRole => $groupUid) {
86
                if (empty($groupUid)) {
87
                    continue;
88
                }
89
90
                foreach ($azureGroups as $azureGroup) {
91
                    $azureGroupUid = $azureGroup['id'];
92
                    if ($azureGroupUid === $groupUid) {
93
                        $roleActions[$userRole]($user);
94
95
                        break 2;
96
                    }
97
                }
98
            }
99
100
            $this->entityManager->flush();
101
        }
102
103
        return $user;
104
    }
105
}
106