--- /dev/null
+{ stdenv, fetchurl, writeText, checkEnv, phpPackages, php, which }:
+let
+ wallabag = rec {
+ varDir = "/var/lib/wallabag";
+ parameters =
+ assert checkEnv "NIXOPS_WALLABAG_SQL_PASSWORD";
+ assert checkEnv "NIXOPS_WALLABAG_SECRET";
+ assert checkEnv "NIXOPS_WALLABAG_LDAP_PASSWORD";
+ writeText "parameters.yml" ''
+ # This file is auto-generated during the composer install
+ parameters:
+ database_driver: pdo_pgsql
+ database_driver_class: Wallabag\CoreBundle\Doctrine\DBAL\Driver\CustomPostgreSQLDriver
+ database_host: db-1.immae.eu
+ database_port: null
+ database_name: webapps
+ database_user: wallabag
+ database_password: ${builtins.getEnv "NIXOPS_WALLABAG_SQL_PASSWORD"}
+ database_path: null
+ database_table_prefix: wallabag_
+ database_socket: null
+ database_charset: utf8
+ domain_name: https://tools.immae.eu/wallabag
+ mailer_transport: smtp
+ mailer_host: mail.immae.eu
+ mailer_user: null
+ mailer_password: null
+ locale: fr
+ secret: ${builtins.getEnv "NIXOPS_WALLABAG_SECRET"}
+ twofactor_auth: true
+ twofactor_sender: wallabag@immae.eu
+ fosuser_registration: false
+ fosuser_confirmation: true
+ from_email: wallabag@immae.eu
+ rss_limit: 50
+ rabbitmq_host: localhost
+ rabbitmq_port: 5672
+ rabbitmq_user: guest
+ rabbitmq_password: guest
+ rabbitmq_prefetch_count: 10
+ redis_scheme: tcp
+ redis_host: localhost
+ redis_port: 6379
+ redis_path: null
+ redis_password: null
+ sites_credentials: { }
+ ldap_enabled: true
+ ldap_host: ldap.immae.eu
+ ldap_port: 636
+ ldap_tls: false
+ ldap_ssl: true
+ ldap_bind_requires_dn: true
+ ldap_base: 'dc=immae,dc=eu'
+ ldap_manager_dn: 'cn=wallabag,ou=services,dc=immae,dc=eu'
+ ldap_manager_pw: ${builtins.getEnv "NIXOPS_WALLABAG_LDAP_PASSWORD"}
+ ldap_filter: '(&(memberOf=cn=users,cn=wallabag,ou=services,dc=immae,dc=eu))'
+ ldap_admin_filter: '(&(memberOf=cn=admins,cn=wallabag,ou=services,dc=immae,dc=eu)(uid=%s))'
+ ldap_username_attribute: uid
+ ldap_email_attribute: mail
+ ldap_name_attribute: cn
+ ldap_enabled_attribute: null
+ '';
+ webappDir = stdenv.mkDerivation rec {
+ # Beware when upgrading, I probably messed up with the migrations table
+ # (due to a psql bug in wallabag)
+ version = "2.3.2";
+ name = "wallabag-${version}";
+ src = fetchurl {
+ url = "https://static.wallabag.org/releases/wallabag-release-${version}.tar.gz";
+ sha256 = "17yczdvgl43j6wa7hksxi2b51afvyd56vdya6hbbv68iiba4jyh4";
+ };
+ patches = [ ./wallabag_ldap.patch ];
+ dontBuild = "true";
+ installPhase = ''
+ cp -a . $out
+ cd $out
+ export SYMFONY_ENV=prod
+ php -d memory_limit=-1 ${phpPackages.composer}/libexec/composer/composer.phar require --update-no-dev -o --prefer-dist fr3d/ldap-bundle
+ rm -rf web/assets var/cache app/config/parameters.yml data
+ mv var var_old
+ ln -sf ${parameters} app/config/parameters.yml
+ ln -sf ../../../../../${varDir}/var var
+ ln -sf ../../../../../${varDir}/data data
+ ln -sf ../../../../../../${varDir}/assets web/assets
+ '';
+ buildInputs = [ php phpPackages.composer ];
+ };
+ activationScript = ''
+ install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \
+ ${varDir}/var ${varDir}/data/db ${varDir}/assets/images
+ if [ ! -f "${varDir}/currentWebappDir" -o \
+ "${webappDir}" != "$(cat ${varDir}/currentWebappDir 2>/dev/null)" ]; then
+ pushd ${webappDir} > /dev/null
+ $wrapperDir/sudo -u wwwrun ./bin/console --env=prod doctrine:migrations:migrate --no-interaction
+ $wrapperDir/sudo -u wwwrun ./bin/console --env=prod cache:clear
+ popd > /dev/null
+ echo -n "${webappDir}" > ${varDir}/currentWebappDir
+ fi
+ '';
+ webRoot = "${webappDir}/web";
+ apache = {
+ user = "wwwrun";
+ group = "wwwrun";
+ modules = [ "proxy_fcgi" ];
+ vhostConf = ''
+ # FIXME
+ Alias /assets "${varDir}/assets"
+ Alias /wallabag "${webRoot}"
+ <Directory "${webRoot}">
+ AllowOverride None
+ Require all granted
+ # For OAuth (apps)
+ CGIPassAuth On
+
+ <FilesMatch "\.php$">
+ SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost"
+ </FilesMatch>
+
+ <IfModule mod_rewrite.c>
+ Options -MultiViews
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ app.php [QSA,L]
+ </IfModule>
+ </Directory>
+ <Directory "${webRoot}/bundles">
+ <IfModule mod_rewrite.c>
+ RewriteEngine Off
+ </IfModule>
+ </Directory>
+ <Directory "${varDir}/assets">
+ AllowOverride None
+ Require all granted
+ </Directory>
+ '';
+ };
+ phpFpm = rec {
+ basedir = builtins.concatStringsSep ":" [ webappDir parameters varDir ];
+ socket = "/var/run/phpfpm/wallabag.sock";
+ pool = ''
+ listen = ${socket}
+ user = ${apache.user}
+ group = ${apache.group}
+ listen.owner = ${apache.user}
+ listen.group = ${apache.group}
+ pm = dynamic
+ pm.max_children = 60
+ pm.start_servers = 2
+ pm.min_spare_servers = 1
+ pm.max_spare_servers = 10
+
+ ; Needed to avoid clashes in browser cookies (same domain)
+ php_value[session.name] = WallabagPHPSESSID
+ php_admin_value[open_basedir] = "${basedir}:/tmp"
+ php_value[max_execution_time] = 300
+ '';
+ };
+ };
+in
+ wallabag
--- /dev/null
+commit 4cd6e7f3bbcff7e2a1c5a39917176d28fa02911f
+Author: Ismaël Bouya <ismael.bouya@normalesup.org>
+Date: Sat Jun 16 11:40:00 2018 +0200
+
+ Add ldap
+
+diff --git a/.travis.yml b/.travis.yml
+index 57b3aa53..3b7638eb 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -54,6 +54,7 @@ branches:
+
+ before_script:
+ - PHP=$TRAVIS_PHP_VERSION
++ - echo "extension=ldap.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+ - if [[ ! $PHP = hhvm* ]]; then echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi;
+ # xdebug isn't enable for PHP 7.1
+ - if [[ ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
+diff --git a/app/AppKernel.php b/app/AppKernel.php
+index 40726f05..c4f465dc 100644
+--- a/app/AppKernel.php
++++ b/app/AppKernel.php
+@@ -42,6 +42,10 @@ class AppKernel extends Kernel
+ new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
+ ];
+
++ if (class_exists('FR3D\\LdapBundle\\FR3DLdapBundle')) {
++ $bundles[] = new FR3D\LdapBundle\FR3DLdapBundle();
++ }
++
+ if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
+ $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
+ $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
+diff --git a/app/DoctrineMigrations/Version20170710113900.php b/app/DoctrineMigrations/Version20170710113900.php
+new file mode 100644
+index 00000000..7be83110
+--- /dev/null
++++ b/app/DoctrineMigrations/Version20170710113900.php
+@@ -0,0 +1,54 @@
++<?php
++
++namespace Application\Migrations;
++
++use Doctrine\DBAL\Migrations\AbstractMigration;
++use Doctrine\DBAL\Schema\Schema;
++use Symfony\Component\DependencyInjection\ContainerAwareInterface;
++use Symfony\Component\DependencyInjection\ContainerInterface;
++
++/**
++ * Added dn field on wallabag_users
++ */
++class Version20170710113900 extends AbstractMigration implements ContainerAwareInterface
++{
++ /**
++ * @var ContainerInterface
++ */
++ private $container;
++
++ public function setContainer(ContainerInterface $container = null)
++ {
++ $this->container = $container;
++ }
++
++ private function getTable($tableName)
++ {
++ return $this->container->getParameter('database_table_prefix').$tableName;
++ }
++
++ /**
++ * @param Schema $schema
++ */
++ public function up(Schema $schema)
++ {
++ $usersTable = $schema->getTable($this->getTable('user'));
++
++ $this->skipIf($usersTable->hasColumn('dn'), 'It seems that you already played this migration.');
++
++ $usersTable->addColumn('dn', 'text', [
++ 'default' => null,
++ 'notnull' => false,
++ ]);
++ }
++
++ /**
++ * @param Schema $schema
++ */
++ public function down(Schema $schema)
++ {
++ $usersTable = $schema->getTable($this->getTable('user'));
++ $usersTable->dropColumn('dn');
++ }
++}
++
+diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
+index 6b0cb8e8..cfd41b69 100644
+--- a/app/config/parameters.yml.dist
++++ b/app/config/parameters.yml.dist
+@@ -62,3 +62,23 @@ parameters:
+ redis_port: 6379
+ redis_path: null
+ redis_password: null
++
++ # ldap configuration
++ # To enable, you need to require fr3d/ldap-bundle
++ ldap_enabled: false
++ ldap_host: localhost
++ ldap_port: 389
++ ldap_tls: false
++ ldap_ssl: false
++ ldap_bind_requires_dn: true
++ ldap_base: dc=example,dc=com
++ ldap_manager_dn: ou=Manager,dc=example,dc=com
++ ldap_manager_pw: password
++ ldap_filter: (&(ObjectClass=Person))
++ # optional (if null: no ldap user is admin)
++ ldap_admin_filter: (&(memberOf=ou=admins,dc=example,dc=com)(uid=%s))
++ ldap_username_attribute: uid
++ ldap_email_attribute: mail
++ ldap_name_attribute: cn
++ # optional (default sets user as enabled unconditionally)
++ ldap_enabled_attribute: ~
+diff --git a/app/config/security.yml b/app/config/security.yml
+index 796dc361..59f48626 100644
+--- a/app/config/security.yml
++++ b/app/config/security.yml
+@@ -6,6 +6,7 @@ security:
+ ROLE_ADMIN: ROLE_USER
+ ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
+
++ # /!\ This list is modified in WallabagUserBundle when LDAP is enabled
+ providers:
+ administrators:
+ entity:
+@@ -36,6 +37,7 @@ security:
+ pattern: ^/login$
+ anonymous: ~
+
++ # /!\ This section is modified in WallabagUserBundle when LDAP is enabled
+ secured_area:
+ pattern: ^/
+ form_login:
+diff --git a/composer.json b/composer.json
+index dca274ed..f115d229 100644
+--- a/composer.json
++++ b/composer.json
+@@ -87,6 +87,9 @@
+ "defuse/php-encryption": "^2.1",
+ "html2text/html2text": "^4.1"
+ },
++ "suggest": {
++ "fr3d/ldap-bundle": "If you want to authenticate via LDAP"
++ },
+ "require-dev": {
+ "doctrine/doctrine-fixtures-bundle": "~2.2",
+ "doctrine/data-fixtures": "~1.1",
+diff --git a/scripts/install.sh b/scripts/install.sh
+index 62a46f4f..5ea3933c 100644
+--- a/scripts/install.sh
++++ b/scripts/install.sh
+@@ -12,5 +12,8 @@ ENV=$1
+ TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
+
+ git checkout $TAG
++if [ -n "$LDAP_ENABLED" ]; then
++ SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle
++fi
+ SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist
+ php bin/console wallabag:install --env=$ENV
+diff --git a/scripts/update.sh b/scripts/update.sh
+index d0598135..753ccbc3 100644
+--- a/scripts/update.sh
++++ b/scripts/update.sh
+@@ -18,6 +18,9 @@ git fetch origin
+ git fetch --tags
+ TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
+ git checkout $TAG --force
++if [ -n "$LDAP_ENABLED" ]; then
++ SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle
++fi
+ SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist
+ php bin/console doctrine:migrations:migrate --no-interaction --env=$ENV
+ php bin/console cache:clear --env=$ENV
+diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
+index 5ca3482e..904a6af1 100644
+--- a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
++++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php
+@@ -6,9 +6,34 @@ use Symfony\Component\Config\FileLocator;
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
+ use Symfony\Component\DependencyInjection\Loader;
+ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
++use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
+
+-class WallabagUserExtension extends Extension
++class WallabagUserExtension extends Extension implements PrependExtensionInterface
+ {
++ public function prepend(ContainerBuilder $container)
++ {
++ $ldap = $container->getParameter('ldap_enabled');
++
++ if ($ldap) {
++ $container->prependExtensionConfig('security', array(
++ 'providers' => array(
++ 'chain_provider' => array(),
++ ),
++ ));
++ $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
++ $loader->load('ldap.yml');
++ } elseif ($container->hasExtension('fr3d_ldap')) {
++ $container->prependExtensionConfig('fr3_d_ldap', array(
++ 'driver' => array(
++ 'host' => 'localhost',
++ ),
++ 'user' => array(
++ 'baseDn' => 'dc=example,dc=com',
++ ),
++ ));
++ }
++ }
++
+ public function load(array $configs, ContainerBuilder $container)
+ {
+ $configuration = new Configuration();
+@@ -16,6 +41,9 @@ class WallabagUserExtension extends Extension
+
+ $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
+ $loader->load('services.yml');
++ if ($container->getParameter('ldap_enabled')) {
++ $loader->load('ldap_services.yml');
++ }
+ $container->setParameter('wallabag_user.registration_enabled', $config['registration_enabled']);
+ }
+
+diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php
+index 48446e3c..f93c59c7 100644
+--- a/src/Wallabag/UserBundle/Entity/User.php
++++ b/src/Wallabag/UserBundle/Entity/User.php
+@@ -1,5 +1,15 @@
+ <?php
+
++// This permits to have the LdapUserInterface even when fr3d/ldap-bundle is not
++// in the packages
++namespace FR3D\LdapBundle\Model;
++
++interface LdapUserInterface
++{
++ public function setDn($dn);
++ public function getDn();
++}
++
+ namespace Wallabag\UserBundle\Entity;
+
+ use Doctrine\Common\Collections\ArrayCollection;
+@@ -16,6 +26,7 @@ use Wallabag\ApiBundle\Entity\Client;
+ use Wallabag\CoreBundle\Entity\Config;
+ use Wallabag\CoreBundle\Entity\Entry;
+ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait;
++use FR3D\LdapBundle\Model\LdapUserInterface;
+
+ /**
+ * User.
+@@ -28,7 +39,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait;
+ * @UniqueEntity("email")
+ * @UniqueEntity("username")
+ */
+-class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface
++class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface, LdapUserInterface
+ {
+ use EntityTimestampsTrait;
+
+@@ -67,6 +78,13 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
+ */
+ protected $email;
+
++ /**
++ * @var string
++ *
++ * @ORM\Column(name="dn", type="text", nullable=true)
++ */
++ protected $dn;
++
+ /**
+ * @var \DateTime
+ *
+@@ -309,4 +327,33 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
+ return $this->clients->first();
+ }
+ }
++
++ /**
++ * Set dn.
++ *
++ * @param string $dn
++ *
++ * @return User
++ */
++ public function setDn($dn)
++ {
++ $this->dn = $dn;
++
++ return $this;
++ }
++
++ /**
++ * Get dn.
++ *
++ * @return string
++ */
++ public function getDn()
++ {
++ return $this->dn;
++ }
++
++ public function isLdapUser()
++ {
++ return $this->dn !== null;
++ }
+ }
+diff --git a/src/Wallabag/UserBundle/LdapHydrator.php b/src/Wallabag/UserBundle/LdapHydrator.php
+new file mode 100644
+index 00000000..cea2450f
+--- /dev/null
++++ b/src/Wallabag/UserBundle/LdapHydrator.php
+@@ -0,0 +1,103 @@
++<?php
++
++namespace Wallabag\UserBundle;
++
++use FR3D\LdapBundle\Hydrator\HydratorInterface;
++use FOS\UserBundle\FOSUserEvents;
++use FOS\UserBundle\Event\UserEvent;
++
++class LdapHydrator implements HydratorInterface
++{
++ private $userManager;
++ private $eventDispatcher;
++ private $attributesMap;
++ private $enabledAttribute;
++ private $ldapBaseDn;
++ private $ldapAdminFilter;
++ private $ldapDriver;
++
++ public function __construct(
++ $user_manager,
++ $event_dispatcher,
++ array $attributes_map,
++ $ldap_base_dn,
++ $ldap_admin_filter,
++ $ldap_driver
++ ) {
++ $this->userManager = $user_manager;
++ $this->eventDispatcher = $event_dispatcher;
++
++ $this->attributesMap = array(
++ 'setUsername' => $attributes_map[0],
++ 'setEmail' => $attributes_map[1],
++ 'setName' => $attributes_map[2],
++ );
++ $this->enabledAttribute = $attributes_map[3];
++
++ $this->ldapBaseDn = $ldap_base_dn;
++ $this->ldapAdminFilter = $ldap_admin_filter;
++ $this->ldapDriver = $ldap_driver;
++ }
++
++ public function hydrate(array $ldapEntry)
++ {
++ $user = $this->userManager->findUserBy(array('dn' => $ldapEntry['dn']));
++
++ if (!$user) {
++ $user = $this->userManager->createUser();
++ $user->setDn($ldapEntry['dn']);
++ $user->setPassword('');
++ $user->setSalt('');
++ $this->updateUserFields($user, $ldapEntry);
++
++ $event = new UserEvent($user);
++ $this->eventDispatcher->dispatch(FOSUserEvents::USER_CREATED, $event);
++
++ $this->userManager->reloadUser($user);
++ } else {
++ $this->updateUserFields($user, $ldapEntry);
++ }
++
++ return $user;
++ }
++
++ private function updateUserFields($user, $ldapEntry)
++ {
++ foreach ($this->attributesMap as $key => $value) {
++ if (is_array($ldapEntry[$value])) {
++ $ldap_value = $ldapEntry[$value][0];
++ } else {
++ $ldap_value = $ldapEntry[$value];
++ }
++
++ call_user_func([$user, $key], $ldap_value);
++ }
++
++ if ($this->enabledAttribute !== null) {
++ $user->setEnabled($ldapEntry[$this->enabledAttribute]);
++ } else {
++ $user->setEnabled(true);
++ }
++
++ if ($this->isAdmin($user)) {
++ $user->addRole('ROLE_SUPER_ADMIN');
++ } else {
++ $user->removeRole('ROLE_SUPER_ADMIN');
++ }
++
++ $this->userManager->updateUser($user, true);
++ }
++
++ private function isAdmin($user)
++ {
++ if ($this->ldapAdminFilter === null) {
++ return false;
++ }
++
++ $escaped_username = ldap_escape($user->getUsername(), '', LDAP_ESCAPE_FILTER);
++ $filter = sprintf($this->ldapAdminFilter, $escaped_username);
++ $entries = $this->ldapDriver->search($this->ldapBaseDn, $filter);
++
++ return $entries['count'] == 1;
++ }
++}
+diff --git a/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php
+new file mode 100644
+index 00000000..8a851f12
+--- /dev/null
++++ b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php
+@@ -0,0 +1,43 @@
++<?php
++
++namespace Wallabag\UserBundle;
++
++use FOS\OAuthServerBundle\Storage\OAuthStorage;
++use OAuth2\Model\IOAuth2Client;
++use Symfony\Component\Security\Core\Exception\AuthenticationException;
++
++class OAuthStorageLdapWrapper extends OAuthStorage
++{
++ private $ldapManager;
++
++ public function setLdapManager($ldap_manager)
++ {
++ $this->ldapManager = $ldap_manager;
++ }
++
++ public function checkUserCredentials(IOAuth2Client $client, $username, $password)
++ {
++ try {
++ $user = $this->userProvider->loadUserByUsername($username);
++ } catch (AuthenticationException $e) {
++ return false;
++ }
++
++ if ($user->isLdapUser()) {
++ return $this->checkLdapUserCredentials($user, $password);
++ } else {
++ return parent::checkUserCredentials($client, $username, $password);
++ }
++ }
++
++ private function checkLdapUserCredentials($user, $password)
++ {
++ if ($this->ldapManager->bind($user, $password)) {
++ return array(
++ 'data' => $user,
++ );
++ } else {
++ return false;
++ }
++ }
++}
+diff --git a/src/Wallabag/UserBundle/Resources/config/ldap.yml b/src/Wallabag/UserBundle/Resources/config/ldap.yml
+new file mode 100644
+index 00000000..5ec16088
+--- /dev/null
++++ b/src/Wallabag/UserBundle/Resources/config/ldap.yml
+@@ -0,0 +1,28 @@
++fr3d_ldap:
++ service:
++ user_hydrator: ldap_user_hydrator
++ driver:
++ host: "%ldap_host%"
++ port: "%ldap_port%"
++ useSsl: "%ldap_ssl%"
++ useStartTls: "%ldap_tls%"
++ bindRequiresDn: "%ldap_bind_requires_dn%"
++ username: "%ldap_manager_dn%"
++ password: "%ldap_manager_pw%"
++ user:
++ baseDn: "%ldap_base%"
++ filter: "%ldap_filter%"
++ usernameAttribute: "%ldap_username_attribute%"
++security:
++ providers:
++ chain_provider:
++ chain:
++ providers: [ fr3d_ldapbundle, fos_userbundle ]
++ fr3d_ldapbundle:
++ id: fr3d_ldap.security.user.provider
++ firewalls:
++ secured_area:
++ fr3d_ldap: ~
++ form_login:
++ provider: chain_provider
++
+diff --git a/src/Wallabag/UserBundle/Resources/config/ldap_services.yml b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml
+new file mode 100644
+index 00000000..b3e3fd8a
+--- /dev/null
++++ b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml
+@@ -0,0 +1,22 @@
++services:
++ fos_oauth_server.server:
++ class: OAuth2\OAuth2
++ arguments:
++ - "@oauth_storage_ldap_wrapper"
++ - "%fos_oauth_server.server.options%"
++ oauth_storage_ldap_wrapper:
++ class: Wallabag\UserBundle\OAuthStorageLdapWrapper
++ parent: fos_oauth_server.storage
++ calls:
++ - [setLdapManager, ["@fr3d_ldap.ldap_manager"]]
++
++ ldap_user_hydrator:
++ class: Wallabag\UserBundle\LdapHydrator
++ arguments:
++ - "@fos_user.user_manager"
++ - "@event_dispatcher"
++ - [ "%ldap_username_attribute%", "%ldap_email_attribute%", "%ldap_name_attribute%", "%ldap_enabled_attribute%" ]
++ - "%ldap_base%"
++ - "%ldap_admin_filter%"
++ - "@fr3d_ldap.ldap_driver"
++