]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - pkgs/webapps/wallabag/ldap.patch
Upgrade Wallabag
[perso/Immae/Config/Nix.git] / pkgs / webapps / wallabag / ldap.patch
CommitLineData
aebd817b 1diff --git a/.travis.yml b/.travis.yml
a3d281ea 2index 04cea258..56b1f576 100644
aebd817b
IB
3--- a/.travis.yml
4+++ b/.travis.yml
a3d281ea 5@@ -58,6 +58,7 @@ install:
aebd817b
IB
6
7 before_script:
8 - PHP=$TRAVIS_PHP_VERSION
9+ - echo "extension=ldap.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
10 - if [[ ! $PHP = hhvm* ]]; then echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi;
11 # xdebug isn't enable for PHP 7.1
12 - if [[ ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
13diff --git a/app/AppKernel.php b/app/AppKernel.php
14index 40726f05..c4f465dc 100644
15--- a/app/AppKernel.php
16+++ b/app/AppKernel.php
17@@ -42,6 +42,10 @@ class AppKernel extends Kernel
18 new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
19 ];
20
21+ if (class_exists('FR3D\\LdapBundle\\FR3DLdapBundle')) {
22+ $bundles[] = new FR3D\LdapBundle\FR3DLdapBundle();
23+ }
24+
25 if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
26 $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
27 $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
28diff --git a/app/DoctrineMigrations/Version20170710113900.php b/app/DoctrineMigrations/Version20170710113900.php
29new file mode 100644
30index 00000000..7be83110
31--- /dev/null
32+++ b/app/DoctrineMigrations/Version20170710113900.php
33@@ -0,0 +1,54 @@
34+<?php
35+
36+namespace Application\Migrations;
37+
38+use Doctrine\DBAL\Migrations\AbstractMigration;
39+use Doctrine\DBAL\Schema\Schema;
40+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
41+use Symfony\Component\DependencyInjection\ContainerInterface;
42+
43+/**
44+ * Added dn field on wallabag_users
45+ */
46+class Version20170710113900 extends AbstractMigration implements ContainerAwareInterface
47+{
48+ /**
49+ * @var ContainerInterface
50+ */
51+ private $container;
52+
53+ public function setContainer(ContainerInterface $container = null)
54+ {
55+ $this->container = $container;
56+ }
57+
58+ private function getTable($tableName)
59+ {
60+ return $this->container->getParameter('database_table_prefix').$tableName;
61+ }
62+
63+ /**
64+ * @param Schema $schema
65+ */
66+ public function up(Schema $schema)
67+ {
68+ $usersTable = $schema->getTable($this->getTable('user'));
69+
70+ $this->skipIf($usersTable->hasColumn('dn'), 'It seems that you already played this migration.');
71+
72+ $usersTable->addColumn('dn', 'text', [
73+ 'default' => null,
74+ 'notnull' => false,
75+ ]);
76+ }
77+
78+ /**
79+ * @param Schema $schema
80+ */
81+ public function down(Schema $schema)
82+ {
83+ $usersTable = $schema->getTable($this->getTable('user'));
84+ $usersTable->dropColumn('dn');
85+ }
86+}
87+
88diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
89index 6b0cb8e8..cfd41b69 100644
90--- a/app/config/parameters.yml.dist
91+++ b/app/config/parameters.yml.dist
92@@ -62,3 +62,23 @@ parameters:
93 redis_port: 6379
94 redis_path: null
95 redis_password: null
96+
97+ # ldap configuration
98+ # To enable, you need to require fr3d/ldap-bundle
99+ ldap_enabled: false
100+ ldap_host: localhost
101+ ldap_port: 389
102+ ldap_tls: false
103+ ldap_ssl: false
104+ ldap_bind_requires_dn: true
105+ ldap_base: dc=example,dc=com
106+ ldap_manager_dn: ou=Manager,dc=example,dc=com
107+ ldap_manager_pw: password
108+ ldap_filter: (&(ObjectClass=Person))
109+ # optional (if null: no ldap user is admin)
110+ ldap_admin_filter: (&(memberOf=ou=admins,dc=example,dc=com)(uid=%s))
111+ ldap_username_attribute: uid
112+ ldap_email_attribute: mail
113+ ldap_name_attribute: cn
114+ # optional (default sets user as enabled unconditionally)
115+ ldap_enabled_attribute: ~
116diff --git a/app/config/security.yml b/app/config/security.yml
a3d281ea 117index 02afc9ea..48fbb553 100644
aebd817b
IB
118--- a/app/config/security.yml
119+++ b/app/config/security.yml
120@@ -6,6 +6,7 @@ security:
121 ROLE_ADMIN: ROLE_USER
122 ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
123
124+ # /!\ This list is modified in WallabagUserBundle when LDAP is enabled
125 providers:
126 administrators:
127 entity:
128@@ -36,6 +37,7 @@ security:
129 pattern: ^/login$
130 anonymous: ~
131
132+ # /!\ This section is modified in WallabagUserBundle when LDAP is enabled
133 secured_area:
134 pattern: ^/
135 form_login:
136diff --git a/composer.json b/composer.json
46c99b57 137index 0483da1d..e3e47bdc 100644
aebd817b
IB
138--- a/composer.json
139+++ b/composer.json
46c99b57 140@@ -87,7 +87,11 @@
a3d281ea 141 "bdunogier/guzzle-site-authenticator": "^1.0.0",
aebd817b 142 "defuse/php-encryption": "^2.1",
46c99b57
IB
143 "html2text/html2text": "^4.1",
144- "sulu/symfony-intl-fix": "^1.0"
145+ "sulu/symfony-intl-fix": "^1.0",
a3d281ea
IB
146+ "fr3d/ldap-bundle": "^3.0"
147+ },
aebd817b
IB
148+ "suggest": {
149+ "fr3d/ldap-bundle": "If you want to authenticate via LDAP"
a3d281ea 150 },
aebd817b
IB
151 "require-dev": {
152 "doctrine/doctrine-fixtures-bundle": "~2.2",
a3d281ea 153diff --git a/composer.lock b/composer.lock
46c99b57 154index b3b0a4c6..8c8a87ee 100644
a3d281ea
IB
155--- a/composer.lock
156+++ b/composer.lock
a3d281ea
IB
157@@ -1346,6 +1346,65 @@
158 ],
46c99b57 159 "time": "2019-05-09T11:53:40+00:00"
a3d281ea
IB
160 },
161+ {
162+ "name": "fr3d/ldap-bundle",
163+ "version": "v3.0.0",
164+ "source": {
165+ "type": "git",
166+ "url": "https://github.com/Maks3w/FR3DLdapBundle.git",
167+ "reference": "5a8927c11af45fa06331b97221c6da1a4a237475"
168+ },
169+ "dist": {
170+ "type": "zip",
171+ "url": "https://api.github.com/repos/Maks3w/FR3DLdapBundle/zipball/5a8927c11af45fa06331b97221c6da1a4a237475",
172+ "reference": "5a8927c11af45fa06331b97221c6da1a4a237475",
173+ "shasum": ""
174+ },
175+ "require": {
176+ "php": ">=5.5",
177+ "psr/log": "~1.0",
178+ "symfony/config": "2.3 - 3",
179+ "symfony/dependency-injection": "2.3 - 3",
180+ "symfony/polyfill-php56": "^1.1",
181+ "symfony/security": "2.3 - 3",
182+ "symfony/security-bundle": "2.3 - 3",
183+ "zendframework/zend-ldap": "2.5 - 3"
184+ },
185+ "require-dev": {
186+ "fabpot/php-cs-fixer": "1.11.*",
187+ "fr3d/psr3-message-assertions": "0.1.*",
188+ "friendsofsymfony/user-bundle": "~1.3",
189+ "maks3w/phpunit-methods-trait": "^4.6",
190+ "phpunit/phpunit": "^4.6",
191+ "symfony/validator": "2.3 - 3"
192+ },
193+ "suggest": {
194+ "friendsofsymfony/user-bundle": "Integrate authentication and management for DB users, useful for unmanned LDAP servers",
195+ "symfony/validator": "Allow pre-validate for existing users before register new ones"
196+ },
197+ "type": "symfony-bundle",
198+ "autoload": {
199+ "psr-4": {
200+ "FR3D\\LdapBundle\\": ""
201+ }
202+ },
203+ "notification-url": "https://packagist.org/downloads/",
204+ "license": [
205+ "MIT"
206+ ],
207+ "authors": [
208+ {
209+ "name": "Maks3w"
210+ }
211+ ],
212+ "description": "This package provide users and authentication services based on LDAP directories for Symfony2 framework",
213+ "homepage": "https://github.com/Maks3w/FR3DLdapBundle",
214+ "keywords": [
215+ "Authentication",
216+ "ldap"
217+ ],
218+ "time": "2016-02-12T17:45:14+00:00"
219+ },
220 {
221 "name": "friendsofsymfony/jsrouting-bundle",
222 "version": "1.6.3",
46c99b57 223@@ -7069,6 +7128,59 @@
a3d281ea
IB
224 "zf2"
225 ],
226 "time": "2018-04-25T15:33:34+00:00"
227+ },
228+ {
229+ "name": "zendframework/zend-ldap",
230+ "version": "2.10.0",
231+ "source": {
232+ "type": "git",
233+ "url": "https://github.com/zendframework/zend-ldap.git",
234+ "reference": "b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49"
235+ },
236+ "dist": {
237+ "type": "zip",
238+ "url": "https://api.github.com/repos/zendframework/zend-ldap/zipball/b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49",
239+ "reference": "b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49",
240+ "shasum": ""
241+ },
242+ "require": {
243+ "ext-ldap": "*",
244+ "php": "^5.6 || ^7.0"
245+ },
246+ "require-dev": {
247+ "php-mock/php-mock-phpunit": "^1.1.2 || ^2.1.1",
248+ "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2",
249+ "zendframework/zend-coding-standard": "~1.0.0",
250+ "zendframework/zend-config": "^2.5",
251+ "zendframework/zend-eventmanager": "^2.6.3 || ^3.0.1",
252+ "zendframework/zend-stdlib": "^2.7 || ^3.0"
253+ },
254+ "suggest": {
255+ "zendframework/zend-eventmanager": "Zend\\EventManager component"
256+ },
257+ "type": "library",
258+ "extra": {
259+ "branch-alias": {
260+ "dev-master": "2.10.x-dev",
261+ "dev-develop": "2.11.x-dev"
262+ }
263+ },
264+ "autoload": {
265+ "psr-4": {
266+ "Zend\\Ldap\\": "src/"
267+ }
268+ },
269+ "notification-url": "https://packagist.org/downloads/",
270+ "license": [
271+ "BSD-3-Clause"
272+ ],
273+ "description": "Provides support for LDAP operations including but not limited to binding, searching and modifying entries in an LDAP directory",
274+ "keywords": [
275+ "ZendFramework",
276+ "ldap",
277+ "zf"
278+ ],
279+ "time": "2018-07-05T05:05:12+00:00"
280 }
281 ],
282 "packages-dev": [
aebd817b 283diff --git a/scripts/install.sh b/scripts/install.sh
46c99b57 284index affa715f..45254212 100755
aebd817b
IB
285--- a/scripts/install.sh
286+++ b/scripts/install.sh
46c99b57 287@@ -37,5 +37,8 @@ fi
aebd817b
IB
288 TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
289
290 git checkout $TAG
291+if [ -n "$LDAP_ENABLED" ]; then
292+ SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle
293+fi
294 SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist
295 php bin/console wallabag:install --env=$ENV
296diff --git a/scripts/update.sh b/scripts/update.sh
46c99b57 297index 3ef10439..eeee28d6 100755
aebd817b
IB
298--- a/scripts/update.sh
299+++ b/scripts/update.sh
46c99b57 300@@ -42,6 +42,9 @@ git fetch origin
aebd817b
IB
301 git fetch --tags
302 TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
303 git checkout $TAG --force
304+if [ -n "$LDAP_ENABLED" ]; then
305+ SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle
306+fi
307 SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist
308 php bin/console doctrine:migrations:migrate --no-interaction --env=$ENV
309 php bin/console cache:clear --env=$ENV
310diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
311index 5ca3482e..904a6af1 100644
312--- a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
313+++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
314@@ -6,9 +6,34 @@ use Symfony\Component\Config\FileLocator;
315 use Symfony\Component\DependencyInjection\ContainerBuilder;
316 use Symfony\Component\DependencyInjection\Loader;
317 use Symfony\Component\HttpKernel\DependencyInjection\Extension;
318+use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
319
320-class WallabagUserExtension extends Extension
321+class WallabagUserExtension extends Extension implements PrependExtensionInterface
322 {
323+ public function prepend(ContainerBuilder $container)
324+ {
325+ $ldap = $container->getParameter('ldap_enabled');
326+
327+ if ($ldap) {
328+ $container->prependExtensionConfig('security', array(
329+ 'providers' => array(
330+ 'chain_provider' => array(),
331+ ),
332+ ));
333+ $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
334+ $loader->load('ldap.yml');
335+ } elseif ($container->hasExtension('fr3d_ldap')) {
336+ $container->prependExtensionConfig('fr3_d_ldap', array(
337+ 'driver' => array(
338+ 'host' => 'localhost',
339+ ),
340+ 'user' => array(
341+ 'baseDn' => 'dc=example,dc=com',
342+ ),
343+ ));
344+ }
345+ }
346+
347 public function load(array $configs, ContainerBuilder $container)
348 {
349 $configuration = new Configuration();
350@@ -16,6 +41,9 @@ class WallabagUserExtension extends Extension
351
352 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
353 $loader->load('services.yml');
354+ if ($container->getParameter('ldap_enabled')) {
355+ $loader->load('ldap_services.yml');
356+ }
357 $container->setParameter('wallabag_user.registration_enabled', $config['registration_enabled']);
358 }
359
360diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php
361index 48446e3c..f93c59c7 100644
362--- a/src/Wallabag/UserBundle/Entity/User.php
363+++ b/src/Wallabag/UserBundle/Entity/User.php
364@@ -1,5 +1,15 @@
365 <?php
366
367+// This permits to have the LdapUserInterface even when fr3d/ldap-bundle is not
368+// in the packages
369+namespace FR3D\LdapBundle\Model;
370+
371+interface LdapUserInterface
372+{
373+ public function setDn($dn);
374+ public function getDn();
375+}
376+
377 namespace Wallabag\UserBundle\Entity;
378
379 use Doctrine\Common\Collections\ArrayCollection;
380@@ -16,6 +26,7 @@ use Wallabag\ApiBundle\Entity\Client;
381 use Wallabag\CoreBundle\Entity\Config;
382 use Wallabag\CoreBundle\Entity\Entry;
383 use Wallabag\CoreBundle\Helper\EntityTimestampsTrait;
384+use FR3D\LdapBundle\Model\LdapUserInterface;
385
386 /**
387 * User.
388@@ -28,7 +39,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait;
389 * @UniqueEntity("email")
390 * @UniqueEntity("username")
391 */
392-class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface
393+class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface, LdapUserInterface
394 {
395 use EntityTimestampsTrait;
396
397@@ -67,6 +78,13 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
398 */
399 protected $email;
400
401+ /**
402+ * @var string
403+ *
404+ * @ORM\Column(name="dn", type="text", nullable=true)
405+ */
406+ protected $dn;
407+
408 /**
409 * @var \DateTime
410 *
411@@ -309,4 +327,33 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
412 return $this->clients->first();
413 }
414 }
415+
416+ /**
417+ * Set dn.
418+ *
419+ * @param string $dn
420+ *
421+ * @return User
422+ */
423+ public function setDn($dn)
424+ {
425+ $this->dn = $dn;
426+
427+ return $this;
428+ }
429+
430+ /**
431+ * Get dn.
432+ *
433+ * @return string
434+ */
435+ public function getDn()
436+ {
437+ return $this->dn;
438+ }
439+
440+ public function isLdapUser()
441+ {
442+ return $this->dn !== null;
443+ }
444 }
445diff --git a/src/Wallabag/UserBundle/LdapHydrator.php b/src/Wallabag/UserBundle/LdapHydrator.php
446new file mode 100644
447index 00000000..cea2450f
448--- /dev/null
449+++ b/src/Wallabag/UserBundle/LdapHydrator.php
450@@ -0,0 +1,103 @@
451+<?php
452+
453+namespace Wallabag\UserBundle;
454+
455+use FR3D\LdapBundle\Hydrator\HydratorInterface;
456+use FOS\UserBundle\FOSUserEvents;
457+use FOS\UserBundle\Event\UserEvent;
458+
459+class LdapHydrator implements HydratorInterface
460+{
461+ private $userManager;
462+ private $eventDispatcher;
463+ private $attributesMap;
464+ private $enabledAttribute;
465+ private $ldapBaseDn;
466+ private $ldapAdminFilter;
467+ private $ldapDriver;
468+
469+ public function __construct(
470+ $user_manager,
471+ $event_dispatcher,
472+ array $attributes_map,
473+ $ldap_base_dn,
474+ $ldap_admin_filter,
475+ $ldap_driver
476+ ) {
477+ $this->userManager = $user_manager;
478+ $this->eventDispatcher = $event_dispatcher;
479+
480+ $this->attributesMap = array(
481+ 'setUsername' => $attributes_map[0],
482+ 'setEmail' => $attributes_map[1],
483+ 'setName' => $attributes_map[2],
484+ );
485+ $this->enabledAttribute = $attributes_map[3];
486+
487+ $this->ldapBaseDn = $ldap_base_dn;
488+ $this->ldapAdminFilter = $ldap_admin_filter;
489+ $this->ldapDriver = $ldap_driver;
490+ }
491+
492+ public function hydrate(array $ldapEntry)
493+ {
494+ $user = $this->userManager->findUserBy(array('dn' => $ldapEntry['dn']));
495+
496+ if (!$user) {
497+ $user = $this->userManager->createUser();
498+ $user->setDn($ldapEntry['dn']);
499+ $user->setPassword('');
500+ $user->setSalt('');
501+ $this->updateUserFields($user, $ldapEntry);
502+
503+ $event = new UserEvent($user);
504+ $this->eventDispatcher->dispatch(FOSUserEvents::USER_CREATED, $event);
505+
506+ $this->userManager->reloadUser($user);
507+ } else {
508+ $this->updateUserFields($user, $ldapEntry);
509+ }
510+
511+ return $user;
512+ }
513+
514+ private function updateUserFields($user, $ldapEntry)
515+ {
516+ foreach ($this->attributesMap as $key => $value) {
517+ if (is_array($ldapEntry[$value])) {
518+ $ldap_value = $ldapEntry[$value][0];
519+ } else {
520+ $ldap_value = $ldapEntry[$value];
521+ }
522+
523+ call_user_func([$user, $key], $ldap_value);
524+ }
525+
526+ if ($this->enabledAttribute !== null) {
527+ $user->setEnabled($ldapEntry[$this->enabledAttribute]);
528+ } else {
529+ $user->setEnabled(true);
530+ }
531+
532+ if ($this->isAdmin($user)) {
533+ $user->addRole('ROLE_SUPER_ADMIN');
534+ } else {
535+ $user->removeRole('ROLE_SUPER_ADMIN');
536+ }
537+
538+ $this->userManager->updateUser($user, true);
539+ }
540+
541+ private function isAdmin($user)
542+ {
543+ if ($this->ldapAdminFilter === null) {
544+ return false;
545+ }
546+
547+ $escaped_username = ldap_escape($user->getUsername(), '', LDAP_ESCAPE_FILTER);
548+ $filter = sprintf($this->ldapAdminFilter, $escaped_username);
549+ $entries = $this->ldapDriver->search($this->ldapBaseDn, $filter);
550+
551+ return $entries['count'] == 1;
552+ }
553+}
554diff --git a/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php
555new file mode 100644
556index 00000000..8a851f12
557--- /dev/null
558+++ b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php
559@@ -0,0 +1,43 @@
560+<?php
561+
562+namespace Wallabag\UserBundle;
563+
564+use FOS\OAuthServerBundle\Storage\OAuthStorage;
565+use OAuth2\Model\IOAuth2Client;
566+use Symfony\Component\Security\Core\Exception\AuthenticationException;
567+
568+class OAuthStorageLdapWrapper extends OAuthStorage
569+{
570+ private $ldapManager;
571+
572+ public function setLdapManager($ldap_manager)
573+ {
574+ $this->ldapManager = $ldap_manager;
575+ }
576+
577+ public function checkUserCredentials(IOAuth2Client $client, $username, $password)
578+ {
579+ try {
580+ $user = $this->userProvider->loadUserByUsername($username);
581+ } catch (AuthenticationException $e) {
582+ return false;
583+ }
584+
585+ if ($user->isLdapUser()) {
586+ return $this->checkLdapUserCredentials($user, $password);
587+ } else {
588+ return parent::checkUserCredentials($client, $username, $password);
589+ }
590+ }
591+
592+ private function checkLdapUserCredentials($user, $password)
593+ {
594+ if ($this->ldapManager->bind($user, $password)) {
595+ return array(
596+ 'data' => $user,
597+ );
598+ } else {
599+ return false;
600+ }
601+ }
602+}
603diff --git a/src/Wallabag/UserBundle/Resources/config/ldap.yml b/src/Wallabag/UserBundle/Resources/config/ldap.yml
604new file mode 100644
605index 00000000..5ec16088
606--- /dev/null
607+++ b/src/Wallabag/UserBundle/Resources/config/ldap.yml
608@@ -0,0 +1,28 @@
609+fr3d_ldap:
610+ service:
611+ user_hydrator: ldap_user_hydrator
612+ driver:
613+ host: "%ldap_host%"
614+ port: "%ldap_port%"
615+ useSsl: "%ldap_ssl%"
616+ useStartTls: "%ldap_tls%"
617+ bindRequiresDn: "%ldap_bind_requires_dn%"
618+ username: "%ldap_manager_dn%"
619+ password: "%ldap_manager_pw%"
620+ user:
621+ baseDn: "%ldap_base%"
622+ filter: "%ldap_filter%"
623+ usernameAttribute: "%ldap_username_attribute%"
624+security:
625+ providers:
626+ chain_provider:
627+ chain:
628+ providers: [ fr3d_ldapbundle, fos_userbundle ]
629+ fr3d_ldapbundle:
630+ id: fr3d_ldap.security.user.provider
631+ firewalls:
632+ secured_area:
633+ fr3d_ldap: ~
634+ form_login:
635+ provider: chain_provider
636+
637diff --git a/src/Wallabag/UserBundle/Resources/config/ldap_services.yml b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml
638new file mode 100644
639index 00000000..b3e3fd8a
640--- /dev/null
641+++ b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml
642@@ -0,0 +1,22 @@
643+services:
644+ fos_oauth_server.server:
645+ class: OAuth2\OAuth2
646+ arguments:
647+ - "@oauth_storage_ldap_wrapper"
648+ - "%fos_oauth_server.server.options%"
649+ oauth_storage_ldap_wrapper:
650+ class: Wallabag\UserBundle\OAuthStorageLdapWrapper
651+ parent: fos_oauth_server.storage
652+ calls:
653+ - [setLdapManager, ["@fr3d_ldap.ldap_manager"]]
654+
655+ ldap_user_hydrator:
656+ class: Wallabag\UserBundle\LdapHydrator
657+ arguments:
658+ - "@fos_user.user_manager"
659+ - "@event_dispatcher"
660+ - [ "%ldap_username_attribute%", "%ldap_email_attribute%", "%ldap_name_attribute%", "%ldap_enabled_attribute%" ]
661+ - "%ldap_base%"
662+ - "%ldap_admin_filter%"
663+ - "@fr3d_ldap.ldap_driver"
664+