]>
Commit | Line | Data |
---|---|---|
aebd817b IB |
1 | commit 4cd6e7f3bbcff7e2a1c5a39917176d28fa02911f |
2 | Author: Ismaël Bouya <ismael.bouya@normalesup.org> | |
3 | Date: Sat Jun 16 11:40:00 2018 +0200 | |
4 | ||
5 | Add ldap | |
6 | ||
7 | diff --git a/.travis.yml b/.travis.yml | |
8 | index 57b3aa53..3b7638eb 100644 | |
9 | --- a/.travis.yml | |
10 | +++ b/.travis.yml | |
11 | @@ -54,6 +54,7 @@ branches: | |
12 | ||
13 | before_script: | |
14 | - PHP=$TRAVIS_PHP_VERSION | |
15 | + - echo "extension=ldap.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini | |
16 | - if [[ ! $PHP = hhvm* ]]; then echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi; | |
17 | # xdebug isn't enable for PHP 7.1 | |
18 | - if [[ ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi | |
19 | diff --git a/app/AppKernel.php b/app/AppKernel.php | |
20 | index 40726f05..c4f465dc 100644 | |
21 | --- a/app/AppKernel.php | |
22 | +++ b/app/AppKernel.php | |
23 | @@ -42,6 +42,10 @@ class AppKernel extends Kernel | |
24 | new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(), | |
25 | ]; | |
26 | ||
27 | + if (class_exists('FR3D\\LdapBundle\\FR3DLdapBundle')) { | |
28 | + $bundles[] = new FR3D\LdapBundle\FR3DLdapBundle(); | |
29 | + } | |
30 | + | |
31 | if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { | |
32 | $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); | |
33 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); | |
34 | diff --git a/app/DoctrineMigrations/Version20170710113900.php b/app/DoctrineMigrations/Version20170710113900.php | |
35 | new file mode 100644 | |
36 | index 00000000..7be83110 | |
37 | --- /dev/null | |
38 | +++ b/app/DoctrineMigrations/Version20170710113900.php | |
39 | @@ -0,0 +1,54 @@ | |
40 | +<?php | |
41 | + | |
42 | +namespace Application\Migrations; | |
43 | + | |
44 | +use Doctrine\DBAL\Migrations\AbstractMigration; | |
45 | +use Doctrine\DBAL\Schema\Schema; | |
46 | +use Symfony\Component\DependencyInjection\ContainerAwareInterface; | |
47 | +use Symfony\Component\DependencyInjection\ContainerInterface; | |
48 | + | |
49 | +/** | |
50 | + * Added dn field on wallabag_users | |
51 | + */ | |
52 | +class Version20170710113900 extends AbstractMigration implements ContainerAwareInterface | |
53 | +{ | |
54 | + /** | |
55 | + * @var ContainerInterface | |
56 | + */ | |
57 | + private $container; | |
58 | + | |
59 | + public function setContainer(ContainerInterface $container = null) | |
60 | + { | |
61 | + $this->container = $container; | |
62 | + } | |
63 | + | |
64 | + private function getTable($tableName) | |
65 | + { | |
66 | + return $this->container->getParameter('database_table_prefix').$tableName; | |
67 | + } | |
68 | + | |
69 | + /** | |
70 | + * @param Schema $schema | |
71 | + */ | |
72 | + public function up(Schema $schema) | |
73 | + { | |
74 | + $usersTable = $schema->getTable($this->getTable('user')); | |
75 | + | |
76 | + $this->skipIf($usersTable->hasColumn('dn'), 'It seems that you already played this migration.'); | |
77 | + | |
78 | + $usersTable->addColumn('dn', 'text', [ | |
79 | + 'default' => null, | |
80 | + 'notnull' => false, | |
81 | + ]); | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * @param Schema $schema | |
86 | + */ | |
87 | + public function down(Schema $schema) | |
88 | + { | |
89 | + $usersTable = $schema->getTable($this->getTable('user')); | |
90 | + $usersTable->dropColumn('dn'); | |
91 | + } | |
92 | +} | |
93 | + | |
94 | diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist | |
95 | index 6b0cb8e8..cfd41b69 100644 | |
96 | --- a/app/config/parameters.yml.dist | |
97 | +++ b/app/config/parameters.yml.dist | |
98 | @@ -62,3 +62,23 @@ parameters: | |
99 | redis_port: 6379 | |
100 | redis_path: null | |
101 | redis_password: null | |
102 | + | |
103 | + # ldap configuration | |
104 | + # To enable, you need to require fr3d/ldap-bundle | |
105 | + ldap_enabled: false | |
106 | + ldap_host: localhost | |
107 | + ldap_port: 389 | |
108 | + ldap_tls: false | |
109 | + ldap_ssl: false | |
110 | + ldap_bind_requires_dn: true | |
111 | + ldap_base: dc=example,dc=com | |
112 | + ldap_manager_dn: ou=Manager,dc=example,dc=com | |
113 | + ldap_manager_pw: password | |
114 | + ldap_filter: (&(ObjectClass=Person)) | |
115 | + # optional (if null: no ldap user is admin) | |
116 | + ldap_admin_filter: (&(memberOf=ou=admins,dc=example,dc=com)(uid=%s)) | |
117 | + ldap_username_attribute: uid | |
118 | + ldap_email_attribute: mail | |
119 | + ldap_name_attribute: cn | |
120 | + # optional (default sets user as enabled unconditionally) | |
121 | + ldap_enabled_attribute: ~ | |
122 | diff --git a/app/config/security.yml b/app/config/security.yml | |
123 | index 796dc361..59f48626 100644 | |
124 | --- a/app/config/security.yml | |
125 | +++ b/app/config/security.yml | |
126 | @@ -6,6 +6,7 @@ security: | |
127 | ROLE_ADMIN: ROLE_USER | |
128 | ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ] | |
129 | ||
130 | + # /!\ This list is modified in WallabagUserBundle when LDAP is enabled | |
131 | providers: | |
132 | administrators: | |
133 | entity: | |
134 | @@ -36,6 +37,7 @@ security: | |
135 | pattern: ^/login$ | |
136 | anonymous: ~ | |
137 | ||
138 | + # /!\ This section is modified in WallabagUserBundle when LDAP is enabled | |
139 | secured_area: | |
140 | pattern: ^/ | |
141 | form_login: | |
142 | diff --git a/composer.json b/composer.json | |
143 | index dca274ed..f115d229 100644 | |
144 | --- a/composer.json | |
145 | +++ b/composer.json | |
146 | @@ -87,6 +87,9 @@ | |
147 | "defuse/php-encryption": "^2.1", | |
148 | "html2text/html2text": "^4.1" | |
149 | }, | |
150 | + "suggest": { | |
151 | + "fr3d/ldap-bundle": "If you want to authenticate via LDAP" | |
152 | + }, | |
153 | "require-dev": { | |
154 | "doctrine/doctrine-fixtures-bundle": "~2.2", | |
155 | "doctrine/data-fixtures": "~1.1", | |
156 | diff --git a/scripts/install.sh b/scripts/install.sh | |
157 | index 62a46f4f..5ea3933c 100644 | |
158 | --- a/scripts/install.sh | |
159 | +++ b/scripts/install.sh | |
160 | @@ -12,5 +12,8 @@ ENV=$1 | |
161 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) | |
162 | ||
163 | git checkout $TAG | |
164 | +if [ -n "$LDAP_ENABLED" ]; then | |
165 | + SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle | |
166 | +fi | |
167 | SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist | |
168 | php bin/console wallabag:install --env=$ENV | |
169 | diff --git a/scripts/update.sh b/scripts/update.sh | |
170 | index d0598135..753ccbc3 100644 | |
171 | --- a/scripts/update.sh | |
172 | +++ b/scripts/update.sh | |
173 | @@ -18,6 +18,9 @@ git fetch origin | |
174 | git fetch --tags | |
175 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) | |
176 | git checkout $TAG --force | |
177 | +if [ -n "$LDAP_ENABLED" ]; then | |
178 | + SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle | |
179 | +fi | |
180 | SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist | |
181 | php bin/console doctrine:migrations:migrate --no-interaction --env=$ENV | |
182 | php bin/console cache:clear --env=$ENV | |
183 | diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | |
184 | index 5ca3482e..904a6af1 100644 | |
185 | --- a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | |
186 | +++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | |
187 | @@ -6,9 +6,34 @@ use Symfony\Component\Config\FileLocator; | |
188 | use Symfony\Component\DependencyInjection\ContainerBuilder; | |
189 | use Symfony\Component\DependencyInjection\Loader; | |
190 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; | |
191 | +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; | |
192 | ||
193 | -class WallabagUserExtension extends Extension | |
194 | +class WallabagUserExtension extends Extension implements PrependExtensionInterface | |
195 | { | |
196 | + public function prepend(ContainerBuilder $container) | |
197 | + { | |
198 | + $ldap = $container->getParameter('ldap_enabled'); | |
199 | + | |
200 | + if ($ldap) { | |
201 | + $container->prependExtensionConfig('security', array( | |
202 | + 'providers' => array( | |
203 | + 'chain_provider' => array(), | |
204 | + ), | |
205 | + )); | |
206 | + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | |
207 | + $loader->load('ldap.yml'); | |
208 | + } elseif ($container->hasExtension('fr3d_ldap')) { | |
209 | + $container->prependExtensionConfig('fr3_d_ldap', array( | |
210 | + 'driver' => array( | |
211 | + 'host' => 'localhost', | |
212 | + ), | |
213 | + 'user' => array( | |
214 | + 'baseDn' => 'dc=example,dc=com', | |
215 | + ), | |
216 | + )); | |
217 | + } | |
218 | + } | |
219 | + | |
220 | public function load(array $configs, ContainerBuilder $container) | |
221 | { | |
222 | $configuration = new Configuration(); | |
223 | @@ -16,6 +41,9 @@ class WallabagUserExtension extends Extension | |
224 | ||
225 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); | |
226 | $loader->load('services.yml'); | |
227 | + if ($container->getParameter('ldap_enabled')) { | |
228 | + $loader->load('ldap_services.yml'); | |
229 | + } | |
230 | $container->setParameter('wallabag_user.registration_enabled', $config['registration_enabled']); | |
231 | } | |
232 | ||
233 | diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php | |
234 | index 48446e3c..f93c59c7 100644 | |
235 | --- a/src/Wallabag/UserBundle/Entity/User.php | |
236 | +++ b/src/Wallabag/UserBundle/Entity/User.php | |
237 | @@ -1,5 +1,15 @@ | |
238 | <?php | |
239 | ||
240 | +// This permits to have the LdapUserInterface even when fr3d/ldap-bundle is not | |
241 | +// in the packages | |
242 | +namespace FR3D\LdapBundle\Model; | |
243 | + | |
244 | +interface LdapUserInterface | |
245 | +{ | |
246 | + public function setDn($dn); | |
247 | + public function getDn(); | |
248 | +} | |
249 | + | |
250 | namespace Wallabag\UserBundle\Entity; | |
251 | ||
252 | use Doctrine\Common\Collections\ArrayCollection; | |
253 | @@ -16,6 +26,7 @@ use Wallabag\ApiBundle\Entity\Client; | |
254 | use Wallabag\CoreBundle\Entity\Config; | |
255 | use Wallabag\CoreBundle\Entity\Entry; | |
256 | use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; | |
257 | +use FR3D\LdapBundle\Model\LdapUserInterface; | |
258 | ||
259 | /** | |
260 | * User. | |
261 | @@ -28,7 +39,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; | |
262 | * @UniqueEntity("email") | |
263 | * @UniqueEntity("username") | |
264 | */ | |
265 | -class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface | |
266 | +class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface, LdapUserInterface | |
267 | { | |
268 | use EntityTimestampsTrait; | |
269 | ||
270 | @@ -67,6 +78,13 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |
271 | */ | |
272 | protected $email; | |
273 | ||
274 | + /** | |
275 | + * @var string | |
276 | + * | |
277 | + * @ORM\Column(name="dn", type="text", nullable=true) | |
278 | + */ | |
279 | + protected $dn; | |
280 | + | |
281 | /** | |
282 | * @var \DateTime | |
283 | * | |
284 | @@ -309,4 +327,33 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |
285 | return $this->clients->first(); | |
286 | } | |
287 | } | |
288 | + | |
289 | + /** | |
290 | + * Set dn. | |
291 | + * | |
292 | + * @param string $dn | |
293 | + * | |
294 | + * @return User | |
295 | + */ | |
296 | + public function setDn($dn) | |
297 | + { | |
298 | + $this->dn = $dn; | |
299 | + | |
300 | + return $this; | |
301 | + } | |
302 | + | |
303 | + /** | |
304 | + * Get dn. | |
305 | + * | |
306 | + * @return string | |
307 | + */ | |
308 | + public function getDn() | |
309 | + { | |
310 | + return $this->dn; | |
311 | + } | |
312 | + | |
313 | + public function isLdapUser() | |
314 | + { | |
315 | + return $this->dn !== null; | |
316 | + } | |
317 | } | |
318 | diff --git a/src/Wallabag/UserBundle/LdapHydrator.php b/src/Wallabag/UserBundle/LdapHydrator.php | |
319 | new file mode 100644 | |
320 | index 00000000..cea2450f | |
321 | --- /dev/null | |
322 | +++ b/src/Wallabag/UserBundle/LdapHydrator.php | |
323 | @@ -0,0 +1,103 @@ | |
324 | +<?php | |
325 | + | |
326 | +namespace Wallabag\UserBundle; | |
327 | + | |
328 | +use FR3D\LdapBundle\Hydrator\HydratorInterface; | |
329 | +use FOS\UserBundle\FOSUserEvents; | |
330 | +use FOS\UserBundle\Event\UserEvent; | |
331 | + | |
332 | +class LdapHydrator implements HydratorInterface | |
333 | +{ | |
334 | + private $userManager; | |
335 | + private $eventDispatcher; | |
336 | + private $attributesMap; | |
337 | + private $enabledAttribute; | |
338 | + private $ldapBaseDn; | |
339 | + private $ldapAdminFilter; | |
340 | + private $ldapDriver; | |
341 | + | |
342 | + public function __construct( | |
343 | + $user_manager, | |
344 | + $event_dispatcher, | |
345 | + array $attributes_map, | |
346 | + $ldap_base_dn, | |
347 | + $ldap_admin_filter, | |
348 | + $ldap_driver | |
349 | + ) { | |
350 | + $this->userManager = $user_manager; | |
351 | + $this->eventDispatcher = $event_dispatcher; | |
352 | + | |
353 | + $this->attributesMap = array( | |
354 | + 'setUsername' => $attributes_map[0], | |
355 | + 'setEmail' => $attributes_map[1], | |
356 | + 'setName' => $attributes_map[2], | |
357 | + ); | |
358 | + $this->enabledAttribute = $attributes_map[3]; | |
359 | + | |
360 | + $this->ldapBaseDn = $ldap_base_dn; | |
361 | + $this->ldapAdminFilter = $ldap_admin_filter; | |
362 | + $this->ldapDriver = $ldap_driver; | |
363 | + } | |
364 | + | |
365 | + public function hydrate(array $ldapEntry) | |
366 | + { | |
367 | + $user = $this->userManager->findUserBy(array('dn' => $ldapEntry['dn'])); | |
368 | + | |
369 | + if (!$user) { | |
370 | + $user = $this->userManager->createUser(); | |
371 | + $user->setDn($ldapEntry['dn']); | |
372 | + $user->setPassword(''); | |
373 | + $user->setSalt(''); | |
374 | + $this->updateUserFields($user, $ldapEntry); | |
375 | + | |
376 | + $event = new UserEvent($user); | |
377 | + $this->eventDispatcher->dispatch(FOSUserEvents::USER_CREATED, $event); | |
378 | + | |
379 | + $this->userManager->reloadUser($user); | |
380 | + } else { | |
381 | + $this->updateUserFields($user, $ldapEntry); | |
382 | + } | |
383 | + | |
384 | + return $user; | |
385 | + } | |
386 | + | |
387 | + private function updateUserFields($user, $ldapEntry) | |
388 | + { | |
389 | + foreach ($this->attributesMap as $key => $value) { | |
390 | + if (is_array($ldapEntry[$value])) { | |
391 | + $ldap_value = $ldapEntry[$value][0]; | |
392 | + } else { | |
393 | + $ldap_value = $ldapEntry[$value]; | |
394 | + } | |
395 | + | |
396 | + call_user_func([$user, $key], $ldap_value); | |
397 | + } | |
398 | + | |
399 | + if ($this->enabledAttribute !== null) { | |
400 | + $user->setEnabled($ldapEntry[$this->enabledAttribute]); | |
401 | + } else { | |
402 | + $user->setEnabled(true); | |
403 | + } | |
404 | + | |
405 | + if ($this->isAdmin($user)) { | |
406 | + $user->addRole('ROLE_SUPER_ADMIN'); | |
407 | + } else { | |
408 | + $user->removeRole('ROLE_SUPER_ADMIN'); | |
409 | + } | |
410 | + | |
411 | + $this->userManager->updateUser($user, true); | |
412 | + } | |
413 | + | |
414 | + private function isAdmin($user) | |
415 | + { | |
416 | + if ($this->ldapAdminFilter === null) { | |
417 | + return false; | |
418 | + } | |
419 | + | |
420 | + $escaped_username = ldap_escape($user->getUsername(), '', LDAP_ESCAPE_FILTER); | |
421 | + $filter = sprintf($this->ldapAdminFilter, $escaped_username); | |
422 | + $entries = $this->ldapDriver->search($this->ldapBaseDn, $filter); | |
423 | + | |
424 | + return $entries['count'] == 1; | |
425 | + } | |
426 | +} | |
427 | diff --git a/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php | |
428 | new file mode 100644 | |
429 | index 00000000..8a851f12 | |
430 | --- /dev/null | |
431 | +++ b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php | |
432 | @@ -0,0 +1,43 @@ | |
433 | +<?php | |
434 | + | |
435 | +namespace Wallabag\UserBundle; | |
436 | + | |
437 | +use FOS\OAuthServerBundle\Storage\OAuthStorage; | |
438 | +use OAuth2\Model\IOAuth2Client; | |
439 | +use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
440 | + | |
441 | +class OAuthStorageLdapWrapper extends OAuthStorage | |
442 | +{ | |
443 | + private $ldapManager; | |
444 | + | |
445 | + public function setLdapManager($ldap_manager) | |
446 | + { | |
447 | + $this->ldapManager = $ldap_manager; | |
448 | + } | |
449 | + | |
450 | + public function checkUserCredentials(IOAuth2Client $client, $username, $password) | |
451 | + { | |
452 | + try { | |
453 | + $user = $this->userProvider->loadUserByUsername($username); | |
454 | + } catch (AuthenticationException $e) { | |
455 | + return false; | |
456 | + } | |
457 | + | |
458 | + if ($user->isLdapUser()) { | |
459 | + return $this->checkLdapUserCredentials($user, $password); | |
460 | + } else { | |
461 | + return parent::checkUserCredentials($client, $username, $password); | |
462 | + } | |
463 | + } | |
464 | + | |
465 | + private function checkLdapUserCredentials($user, $password) | |
466 | + { | |
467 | + if ($this->ldapManager->bind($user, $password)) { | |
468 | + return array( | |
469 | + 'data' => $user, | |
470 | + ); | |
471 | + } else { | |
472 | + return false; | |
473 | + } | |
474 | + } | |
475 | +} | |
476 | diff --git a/src/Wallabag/UserBundle/Resources/config/ldap.yml b/src/Wallabag/UserBundle/Resources/config/ldap.yml | |
477 | new file mode 100644 | |
478 | index 00000000..5ec16088 | |
479 | --- /dev/null | |
480 | +++ b/src/Wallabag/UserBundle/Resources/config/ldap.yml | |
481 | @@ -0,0 +1,28 @@ | |
482 | +fr3d_ldap: | |
483 | + service: | |
484 | + user_hydrator: ldap_user_hydrator | |
485 | + driver: | |
486 | + host: "%ldap_host%" | |
487 | + port: "%ldap_port%" | |
488 | + useSsl: "%ldap_ssl%" | |
489 | + useStartTls: "%ldap_tls%" | |
490 | + bindRequiresDn: "%ldap_bind_requires_dn%" | |
491 | + username: "%ldap_manager_dn%" | |
492 | + password: "%ldap_manager_pw%" | |
493 | + user: | |
494 | + baseDn: "%ldap_base%" | |
495 | + filter: "%ldap_filter%" | |
496 | + usernameAttribute: "%ldap_username_attribute%" | |
497 | +security: | |
498 | + providers: | |
499 | + chain_provider: | |
500 | + chain: | |
501 | + providers: [ fr3d_ldapbundle, fos_userbundle ] | |
502 | + fr3d_ldapbundle: | |
503 | + id: fr3d_ldap.security.user.provider | |
504 | + firewalls: | |
505 | + secured_area: | |
506 | + fr3d_ldap: ~ | |
507 | + form_login: | |
508 | + provider: chain_provider | |
509 | + | |
510 | diff --git a/src/Wallabag/UserBundle/Resources/config/ldap_services.yml b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml | |
511 | new file mode 100644 | |
512 | index 00000000..b3e3fd8a | |
513 | --- /dev/null | |
514 | +++ b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml | |
515 | @@ -0,0 +1,22 @@ | |
516 | +services: | |
517 | + fos_oauth_server.server: | |
518 | + class: OAuth2\OAuth2 | |
519 | + arguments: | |
520 | + - "@oauth_storage_ldap_wrapper" | |
521 | + - "%fos_oauth_server.server.options%" | |
522 | + oauth_storage_ldap_wrapper: | |
523 | + class: Wallabag\UserBundle\OAuthStorageLdapWrapper | |
524 | + parent: fos_oauth_server.storage | |
525 | + calls: | |
526 | + - [setLdapManager, ["@fr3d_ldap.ldap_manager"]] | |
527 | + | |
528 | + ldap_user_hydrator: | |
529 | + class: Wallabag\UserBundle\LdapHydrator | |
530 | + arguments: | |
531 | + - "@fos_user.user_manager" | |
532 | + - "@event_dispatcher" | |
533 | + - [ "%ldap_username_attribute%", "%ldap_email_attribute%", "%ldap_name_attribute%", "%ldap_enabled_attribute%" ] | |
534 | + - "%ldap_base%" | |
535 | + - "%ldap_admin_filter%" | |
536 | + - "@fr3d_ldap.ldap_driver" | |
537 | + |