Passed
Push — master ( 6eaef8...9a3a70 )
by Angel Fernando Quiroz
08:17
created

AuthenticationConfigHelper::getAuthSources()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 8
nc 6
nop 1
dl 0
loc 17
rs 9.2222
c 0
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\Helpers;
8
9
use Chamilo\CoreBundle\Entity\AccessUrl;
10
use Chamilo\CoreBundle\Entity\UserAuthSource;
11
use InvalidArgumentException;
12
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
13
14
readonly class AuthenticationConfigHelper
15
{
16
    public function __construct(
17
        private ParameterBagInterface $parameterBag,
18
        private AccessUrlHelper $accessUrlHelper,
19
    ) {}
20
21
    public function getOAuthProviderConfig(string $providerName, ?AccessUrl $url = null): array
22
    {
23
        $providers = $this->getOAuthProvidersForUrl($url);
24
25
        if ([] === $providers) {
26
            return [];
27
        }
28
29
        if (!isset($providers[$providerName])) {
30
            throw new InvalidArgumentException('Invalid authentication provider for access URL');
31
        }
32
33
        return $providers[$providerName];
34
    }
35
36
    /**
37
     * @return array<string, array<string, mixed>>
38
     */
39
    private function getOAuthProvidersForUrl(?AccessUrl $url): array
40
    {
41
        $authentication = $this->getAuthSources($url);
42
43
        if (isset($authentication['oauth2'])) {
44
            return $authentication['oauth2'];
45
        }
46
47
        return [];
48
    }
49
50
    private function getAuthSources(?AccessUrl $url): array
51
    {
52
        $urlId = $url ?: $this->accessUrlHelper->getCurrent();
53
54
        $authentication = $this->parameterBag->has('authentication')
55
            ? $this->parameterBag->get('authentication')
56
            : [];
57
58
        if ($urlId && isset($authentication[$urlId->getId()])) {
59
            return $authentication[$urlId->getId()];
60
        }
61
62
        if (isset($authentication['default'])) {
63
            return $authentication['default'];
64
        }
65
66
        return [];
67
    }
68
69
    /**
70
     * @return array<int, string>
71
     */
72
    public function getAuthSourceAuthentications(?AccessUrl $url): array
73
    {
74
        $authentications = [UserAuthSource::PLATFORM];
75
76
        if ($this->getLdapConfig($url)['enabled']) {
77
            $authentications[] = UserAuthSource::LDAP;
78
        }
79
80
        return array_merge(
81
            $authentications,
82
            array_keys($this->getEnabledOAuthProviders($url))
83
        );
84
    }
85
86
    /**
87
     * @return array<string, mixed>
88
     */
89
    public function getLdapConfig(?AccessUrl $url = null): array
90
    {
91
        $authentication = $this->getAuthSources($url);
92
        $ldapConfig = [];
93
94
        if (isset($authentication['ldap'])) {
95
            $ldapConfig = $authentication['ldap'];
96
        }
97
98
        return [
99
            'enabled' => $ldapConfig['enabled'] ?? false,
100
            'title' => $ldapConfig['title'] ?? 'LDAP',
101
            'force_as_login_method' => $ldapConfig['force_as_login_method'] ?? false,
102
            'connection_string' => $ldapConfig['connection_string'] ?? 'null://null',
103
            'protocol_version' => $ldapConfig['protocol_version'] ?? 3,
104
            'referrals' => $ldapConfig['referrals'] ?? false,
105
            'dn_string' => $ldapConfig['dn_string'] ?? '{user_identifier}',
106
            'query_string' => $ldapConfig['query_string'] ?? null,
107
            'base_dn' => $ldapConfig['base_dn'] ?? null,
108
            'search_dn' => $ldapConfig['search_dn'] ?? null,
109
            'search_password' => $ldapConfig['search_password'] ?? null,
110
            'filter' => $ldapConfig['filter'] ?? null,
111
            'uid_key' => $ldapConfig['uid_key'] ?? 'uid',
112
            'password_attribute' => $ldapConfig['password_attribute'] ?? null,
113
            'data_correspondence' => $this->getLdapDataCorrespondenceConfig(
114
                $ldapConfig['data_correspondence'] ?? []
115
            ),
116
        ];
117
    }
118
119
    /**
120
     * @param array<string, mixed> $dataCorrespondence
121
     *
122
     * @return array<string, mixed>
123
     */
124
    private function getLdapDataCorrespondenceConfig(array $dataCorrespondence): array
125
    {
126
        return [
127
            'firstname' => $dataCorrespondence['firstname'] ?? null,
128
            'lastname' => $dataCorrespondence['lastname'] ?? 'sn',
129
            'email' => $dataCorrespondence['email'] ?? 'mail',
130
            'locale' => $dataCorrespondence['locale'] ?? null,
131
            'role' => $dataCorrespondence['role'] ?? null,
132
            'phone' => $dataCorrespondence['phone'] ?? null,
133
            'active' => $dataCorrespondence['active'] ?? null,
134
            'admin' => $dataCorrespondence['admin'] ?? null,
135
        ];
136
    }
137
138
    /**
139
     * @return array<string, array<string, mixed>>
140
     */
141
    public function getEnabledOAuthProviders(?AccessUrl $url = null): array
142
    {
143
        $urlProviders = $this->getOAuthProvidersForUrl($url);
144
145
        return array_filter(
146
            $urlProviders,
147
            fn (array $providerParams) => $providerParams['enabled'] ?? false
148
        );
149
    }
150
151
    public function getOAuthProviderOptions(string $providerType, array $config): array
152
    {
153
        $defaults = match ($providerType) {
154
            'generic' => [
155
                'clientId' => $config['client_id'],
156
                'clientSecret' => $config['client_secret'],
157
                'urlAuthorize' => $config['urlAuthorize'],
158
                'urlAccessToken' => $config['urlAccessToken'],
159
                'urlResourceOwnerDetails' => $config['urlResourceOwnerDetails'],
160
                'accessTokenMethod' => $config['accessTokenMethod'] ?? null,
161
                'accessTokenResourceOwnerId' => $config['accessTokenResourceOwnerId'] ?? null,
162
                'scopeSeparator' => $config['scopeSeparator'] ?? null,
163
                'responseError' => $config['responseError'] ?? null,
164
                'responseCode' => $config['responseCode'] ?? null,
165
                'responseResourceOwnerId' => $config['responseResourceOwnerId'] ?? null,
166
                'scopes' => $config['scopes'] ?? null,
167
                'pkceMethod' => $config['pkceMethod'] ?? null,
168
            ],
169
            'facebook' => [
170
                'clientId' => $config['client_id'],
171
                'clientSecret' => $config['client_secret'],
172
                'graphApiVersion' => $config['graph_api_version'] ?? null,
173
            ],
174
            'keycloak' => [
175
                'clientId' => $config['client_id'],
176
                'clientSecret' => $config['client_secret'],
177
                'authServerUrl' => $config['auth_server_url'],
178
                'realm' => $config['realm'],
179
                'version' => $config['version'] ?? null,
180
                'encryptionAlgorithm' => $config['encryption_algorithm'] ?? null,
181
                'encryptionKeyPath' => $config['encryption_key_path'] ?? null,
182
                'encryptionKey' => $config['encryption_key'] ?? null,
183
            ],
184
            'azure' => [
185
                'clientId' => $config['client_id'],
186
                'clientSecret' => $config['client_secret'],
187
                'clientCertificatePrivateKey' => $config['client_certificate_private_key'] ?? null,
188
                'clientCertificateThumbprint' => $config['client_certificate_thumbprint'] ?? null,
189
                'urlLogin' => $config['url_login'] ?? null,
190
                'pathAuthorize' => $config['path_authorize'] ?? null,
191
                'pathToken' => $config['path_token'] ?? null,
192
                'scope' => $config['scope'] ?? null,
193
                'tenant' => $config['tenant'] ?? null,
194
                'urlAPI' => $config['url_api'] ?? null,
195
                'resource' => $config['resource'] ?? null,
196
                'API_VERSION' => $config['api_version'] ?? null,
197
                'authWithResource' => $config['auth_with_resource'] ?? null,
198
                'defaultEndPointVersion' => $config['default_end_point_version'] ?? null,
199
            ],
200
        };
201
202
        return array_filter($defaults, fn ($value) => null !== $value);
203
    }
204
205
    /**
206
     * Returns the first authentication method marked as "force_as_login_method" in the authentication configuration.
207
     * Checks LDAP first, then enabled OAuth providers. Returns the provider name or null if none is forced.
208
     */
209
    public function getForcedLoginMethod(?AccessUrl $url = null): ?string
210
    {
211
        $ldapConfig = $this->getLdapConfig($url);
212
213
        if ($ldapConfig['enabled'] && ($ldapConfig['force_as_login_method'] ?? false)) {
214
            return 'ldap';
215
        }
216
217
        $oauthProviders = $this->getEnabledOAuthProviders($url);
218
219
        foreach ($oauthProviders as $providerName => $providerConfig) {
220
            if ($providerConfig['force_as_login_method'] ?? false) {
221
                return $providerName;
222
            }
223
        }
224
225
        return null;
226
    }
227
}
228