diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-12-13 21:25:24 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2019-05-24 01:40:13 +0200 |
commit | 24fd1fe6c62b7a9fc347794fde043285da272f5c (patch) | |
tree | 65557bf1d241ca389b619dbd24d18d51932ee030 /pkgs/webapps/wallabag/ldap.patch | |
download | NUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.tar.gz NUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.tar.zst NUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.zip |
Initial commit published for NUR
Diffstat (limited to 'pkgs/webapps/wallabag/ldap.patch')
-rw-r--r-- | pkgs/webapps/wallabag/ldap.patch | 698 |
1 files changed, 698 insertions, 0 deletions
diff --git a/pkgs/webapps/wallabag/ldap.patch b/pkgs/webapps/wallabag/ldap.patch new file mode 100644 index 00000000..9caf7dac --- /dev/null +++ b/pkgs/webapps/wallabag/ldap.patch | |||
@@ -0,0 +1,698 @@ | |||
1 | diff --git a/.travis.yml b/.travis.yml | ||
2 | index 04cea258..56b1f576 100644 | ||
3 | --- a/.travis.yml | ||
4 | +++ b/.travis.yml | ||
5 | @@ -58,6 +58,7 @@ install: | ||
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 | ||
13 | diff --git a/app/AppKernel.php b/app/AppKernel.php | ||
14 | index 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(); | ||
28 | diff --git a/app/DoctrineMigrations/Version20170710113900.php b/app/DoctrineMigrations/Version20170710113900.php | ||
29 | new file mode 100644 | ||
30 | index 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 | + | ||
88 | diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist | ||
89 | index 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: ~ | ||
116 | diff --git a/app/config/security.yml b/app/config/security.yml | ||
117 | index 02afc9ea..48fbb553 100644 | ||
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: | ||
136 | diff --git a/composer.json b/composer.json | ||
137 | index 68cfad05..32a3d1a4 100644 | ||
138 | --- a/composer.json | ||
139 | +++ b/composer.json | ||
140 | @@ -85,7 +85,11 @@ | ||
141 | "friendsofsymfony/jsrouting-bundle": "^1.6.3", | ||
142 | "bdunogier/guzzle-site-authenticator": "^1.0.0", | ||
143 | "defuse/php-encryption": "^2.1", | ||
144 | - "html2text/html2text": "^4.1" | ||
145 | + "html2text/html2text": "^4.1", | ||
146 | + "fr3d/ldap-bundle": "^3.0" | ||
147 | + }, | ||
148 | + "suggest": { | ||
149 | + "fr3d/ldap-bundle": "If you want to authenticate via LDAP" | ||
150 | }, | ||
151 | "require-dev": { | ||
152 | "doctrine/doctrine-fixtures-bundle": "~2.2", | ||
153 | diff --git a/composer.lock b/composer.lock | ||
154 | index 251ee081..37795e0b 100644 | ||
155 | --- a/composer.lock | ||
156 | +++ b/composer.lock | ||
157 | @@ -4,7 +4,7 @@ | ||
158 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||
159 | "This file is @generated automatically" | ||
160 | ], | ||
161 | - "content-hash": "d2a0bd8408dccdeb7a7455996519829b", | ||
162 | + "content-hash": "4699d166d03a8e5f70d802d0bc3e6a20", | ||
163 | "packages": [ | ||
164 | { | ||
165 | "name": "bdunogier/guzzle-site-authenticator", | ||
166 | @@ -1346,6 +1346,65 @@ | ||
167 | ], | ||
168 | "time": "2018-12-14T19:44:53+00:00" | ||
169 | }, | ||
170 | + { | ||
171 | + "name": "fr3d/ldap-bundle", | ||
172 | + "version": "v3.0.0", | ||
173 | + "source": { | ||
174 | + "type": "git", | ||
175 | + "url": "https://github.com/Maks3w/FR3DLdapBundle.git", | ||
176 | + "reference": "5a8927c11af45fa06331b97221c6da1a4a237475" | ||
177 | + }, | ||
178 | + "dist": { | ||
179 | + "type": "zip", | ||
180 | + "url": "https://api.github.com/repos/Maks3w/FR3DLdapBundle/zipball/5a8927c11af45fa06331b97221c6da1a4a237475", | ||
181 | + "reference": "5a8927c11af45fa06331b97221c6da1a4a237475", | ||
182 | + "shasum": "" | ||
183 | + }, | ||
184 | + "require": { | ||
185 | + "php": ">=5.5", | ||
186 | + "psr/log": "~1.0", | ||
187 | + "symfony/config": "2.3 - 3", | ||
188 | + "symfony/dependency-injection": "2.3 - 3", | ||
189 | + "symfony/polyfill-php56": "^1.1", | ||
190 | + "symfony/security": "2.3 - 3", | ||
191 | + "symfony/security-bundle": "2.3 - 3", | ||
192 | + "zendframework/zend-ldap": "2.5 - 3" | ||
193 | + }, | ||
194 | + "require-dev": { | ||
195 | + "fabpot/php-cs-fixer": "1.11.*", | ||
196 | + "fr3d/psr3-message-assertions": "0.1.*", | ||
197 | + "friendsofsymfony/user-bundle": "~1.3", | ||
198 | + "maks3w/phpunit-methods-trait": "^4.6", | ||
199 | + "phpunit/phpunit": "^4.6", | ||
200 | + "symfony/validator": "2.3 - 3" | ||
201 | + }, | ||
202 | + "suggest": { | ||
203 | + "friendsofsymfony/user-bundle": "Integrate authentication and management for DB users, useful for unmanned LDAP servers", | ||
204 | + "symfony/validator": "Allow pre-validate for existing users before register new ones" | ||
205 | + }, | ||
206 | + "type": "symfony-bundle", | ||
207 | + "autoload": { | ||
208 | + "psr-4": { | ||
209 | + "FR3D\\LdapBundle\\": "" | ||
210 | + } | ||
211 | + }, | ||
212 | + "notification-url": "https://packagist.org/downloads/", | ||
213 | + "license": [ | ||
214 | + "MIT" | ||
215 | + ], | ||
216 | + "authors": [ | ||
217 | + { | ||
218 | + "name": "Maks3w" | ||
219 | + } | ||
220 | + ], | ||
221 | + "description": "This package provide users and authentication services based on LDAP directories for Symfony2 framework", | ||
222 | + "homepage": "https://github.com/Maks3w/FR3DLdapBundle", | ||
223 | + "keywords": [ | ||
224 | + "Authentication", | ||
225 | + "ldap" | ||
226 | + ], | ||
227 | + "time": "2016-02-12T17:45:14+00:00" | ||
228 | + }, | ||
229 | { | ||
230 | "name": "friendsofsymfony/jsrouting-bundle", | ||
231 | "version": "1.6.3", | ||
232 | @@ -7027,6 +7086,59 @@ | ||
233 | "zf2" | ||
234 | ], | ||
235 | "time": "2018-04-25T15:33:34+00:00" | ||
236 | + }, | ||
237 | + { | ||
238 | + "name": "zendframework/zend-ldap", | ||
239 | + "version": "2.10.0", | ||
240 | + "source": { | ||
241 | + "type": "git", | ||
242 | + "url": "https://github.com/zendframework/zend-ldap.git", | ||
243 | + "reference": "b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49" | ||
244 | + }, | ||
245 | + "dist": { | ||
246 | + "type": "zip", | ||
247 | + "url": "https://api.github.com/repos/zendframework/zend-ldap/zipball/b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49", | ||
248 | + "reference": "b63c7884a08d3a6bda60ebcf7d6238cf8ad89f49", | ||
249 | + "shasum": "" | ||
250 | + }, | ||
251 | + "require": { | ||
252 | + "ext-ldap": "*", | ||
253 | + "php": "^5.6 || ^7.0" | ||
254 | + }, | ||
255 | + "require-dev": { | ||
256 | + "php-mock/php-mock-phpunit": "^1.1.2 || ^2.1.1", | ||
257 | + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", | ||
258 | + "zendframework/zend-coding-standard": "~1.0.0", | ||
259 | + "zendframework/zend-config": "^2.5", | ||
260 | + "zendframework/zend-eventmanager": "^2.6.3 || ^3.0.1", | ||
261 | + "zendframework/zend-stdlib": "^2.7 || ^3.0" | ||
262 | + }, | ||
263 | + "suggest": { | ||
264 | + "zendframework/zend-eventmanager": "Zend\\EventManager component" | ||
265 | + }, | ||
266 | + "type": "library", | ||
267 | + "extra": { | ||
268 | + "branch-alias": { | ||
269 | + "dev-master": "2.10.x-dev", | ||
270 | + "dev-develop": "2.11.x-dev" | ||
271 | + } | ||
272 | + }, | ||
273 | + "autoload": { | ||
274 | + "psr-4": { | ||
275 | + "Zend\\Ldap\\": "src/" | ||
276 | + } | ||
277 | + }, | ||
278 | + "notification-url": "https://packagist.org/downloads/", | ||
279 | + "license": [ | ||
280 | + "BSD-3-Clause" | ||
281 | + ], | ||
282 | + "description": "Provides support for LDAP operations including but not limited to binding, searching and modifying entries in an LDAP directory", | ||
283 | + "keywords": [ | ||
284 | + "ZendFramework", | ||
285 | + "ldap", | ||
286 | + "zf" | ||
287 | + ], | ||
288 | + "time": "2018-07-05T05:05:12+00:00" | ||
289 | } | ||
290 | ], | ||
291 | "packages-dev": [ | ||
292 | @@ -7561,12 +7673,12 @@ | ||
293 | "source": { | ||
294 | "type": "git", | ||
295 | "url": "https://github.com/symfony/phpunit-bridge.git", | ||
296 | - "reference": "5dab0d4b2ac99ab22b447b615fdfdc10ec4af3d5" | ||
297 | + "reference": "d61ec438634e0f234c6bda1c6ee97016bbb0e7a1" | ||
298 | }, | ||
299 | "dist": { | ||
300 | "type": "zip", | ||
301 | - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/5dab0d4b2ac99ab22b447b615fdfdc10ec4af3d5", | ||
302 | - "reference": "5dab0d4b2ac99ab22b447b615fdfdc10ec4af3d5", | ||
303 | + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d61ec438634e0f234c6bda1c6ee97016bbb0e7a1", | ||
304 | + "reference": "d61ec438634e0f234c6bda1c6ee97016bbb0e7a1", | ||
305 | "shasum": "" | ||
306 | }, | ||
307 | "require": { | ||
308 | @@ -7619,7 +7731,7 @@ | ||
309 | ], | ||
310 | "description": "Symfony PHPUnit Bridge", | ||
311 | "homepage": "https://symfony.com", | ||
312 | - "time": "2019-01-01T13:45:19+00:00" | ||
313 | + "time": "2019-01-16T13:27:11+00:00" | ||
314 | }, | ||
315 | { | ||
316 | "name": "symfony/polyfill-php72", | ||
317 | diff --git a/scripts/install.sh b/scripts/install.sh | ||
318 | index 8b7ea03f..3a4a33ab 100755 | ||
319 | --- a/scripts/install.sh | ||
320 | +++ b/scripts/install.sh | ||
321 | @@ -26,5 +26,8 @@ ENV=$1 | ||
322 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) | ||
323 | |||
324 | git checkout $TAG | ||
325 | +if [ -n "$LDAP_ENABLED" ]; then | ||
326 | + SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle | ||
327 | +fi | ||
328 | SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist | ||
329 | php bin/console wallabag:install --env=$ENV | ||
330 | diff --git a/scripts/update.sh b/scripts/update.sh | ||
331 | index c62d104a..6259a431 100755 | ||
332 | --- a/scripts/update.sh | ||
333 | +++ b/scripts/update.sh | ||
334 | @@ -32,6 +32,9 @@ git fetch origin | ||
335 | git fetch --tags | ||
336 | TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) | ||
337 | git checkout $TAG --force | ||
338 | +if [ -n "$LDAP_ENABLED" ]; then | ||
339 | + SYMFONY_ENV=$ENV $COMPOSER_COMMAND require --no-update fr3d/ldap-bundle | ||
340 | +fi | ||
341 | SYMFONY_ENV=$ENV $COMPOSER_COMMAND install --no-dev -o --prefer-dist | ||
342 | php bin/console doctrine:migrations:migrate --no-interaction --env=$ENV | ||
343 | php bin/console cache:clear --env=$ENV | ||
344 | diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | ||
345 | index 5ca3482e..904a6af1 100644 | ||
346 | --- a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | ||
347 | +++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php | ||
348 | @@ -6,9 +6,34 @@ use Symfony\Component\Config\FileLocator; | ||
349 | use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
350 | use Symfony\Component\DependencyInjection\Loader; | ||
351 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; | ||
352 | +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; | ||
353 | |||
354 | -class WallabagUserExtension extends Extension | ||
355 | +class WallabagUserExtension extends Extension implements PrependExtensionInterface | ||
356 | { | ||
357 | + public function prepend(ContainerBuilder $container) | ||
358 | + { | ||
359 | + $ldap = $container->getParameter('ldap_enabled'); | ||
360 | + | ||
361 | + if ($ldap) { | ||
362 | + $container->prependExtensionConfig('security', array( | ||
363 | + 'providers' => array( | ||
364 | + 'chain_provider' => array(), | ||
365 | + ), | ||
366 | + )); | ||
367 | + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | ||
368 | + $loader->load('ldap.yml'); | ||
369 | + } elseif ($container->hasExtension('fr3d_ldap')) { | ||
370 | + $container->prependExtensionConfig('fr3_d_ldap', array( | ||
371 | + 'driver' => array( | ||
372 | + 'host' => 'localhost', | ||
373 | + ), | ||
374 | + 'user' => array( | ||
375 | + 'baseDn' => 'dc=example,dc=com', | ||
376 | + ), | ||
377 | + )); | ||
378 | + } | ||
379 | + } | ||
380 | + | ||
381 | public function load(array $configs, ContainerBuilder $container) | ||
382 | { | ||
383 | $configuration = new Configuration(); | ||
384 | @@ -16,6 +41,9 @@ class WallabagUserExtension extends Extension | ||
385 | |||
386 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); | ||
387 | $loader->load('services.yml'); | ||
388 | + if ($container->getParameter('ldap_enabled')) { | ||
389 | + $loader->load('ldap_services.yml'); | ||
390 | + } | ||
391 | $container->setParameter('wallabag_user.registration_enabled', $config['registration_enabled']); | ||
392 | } | ||
393 | |||
394 | diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php | ||
395 | index 48446e3c..f93c59c7 100644 | ||
396 | --- a/src/Wallabag/UserBundle/Entity/User.php | ||
397 | +++ b/src/Wallabag/UserBundle/Entity/User.php | ||
398 | @@ -1,5 +1,15 @@ | ||
399 | <?php | ||
400 | |||
401 | +// This permits to have the LdapUserInterface even when fr3d/ldap-bundle is not | ||
402 | +// in the packages | ||
403 | +namespace FR3D\LdapBundle\Model; | ||
404 | + | ||
405 | +interface LdapUserInterface | ||
406 | +{ | ||
407 | + public function setDn($dn); | ||
408 | + public function getDn(); | ||
409 | +} | ||
410 | + | ||
411 | namespace Wallabag\UserBundle\Entity; | ||
412 | |||
413 | use Doctrine\Common\Collections\ArrayCollection; | ||
414 | @@ -16,6 +26,7 @@ use Wallabag\ApiBundle\Entity\Client; | ||
415 | use Wallabag\CoreBundle\Entity\Config; | ||
416 | use Wallabag\CoreBundle\Entity\Entry; | ||
417 | use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; | ||
418 | +use FR3D\LdapBundle\Model\LdapUserInterface; | ||
419 | |||
420 | /** | ||
421 | * User. | ||
422 | @@ -28,7 +39,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; | ||
423 | * @UniqueEntity("email") | ||
424 | * @UniqueEntity("username") | ||
425 | */ | ||
426 | -class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface | ||
427 | +class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface, LdapUserInterface | ||
428 | { | ||
429 | use EntityTimestampsTrait; | ||
430 | |||
431 | @@ -67,6 +78,13 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | ||
432 | */ | ||
433 | protected $email; | ||
434 | |||
435 | + /** | ||
436 | + * @var string | ||
437 | + * | ||
438 | + * @ORM\Column(name="dn", type="text", nullable=true) | ||
439 | + */ | ||
440 | + protected $dn; | ||
441 | + | ||
442 | /** | ||
443 | * @var \DateTime | ||
444 | * | ||
445 | @@ -309,4 +327,33 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | ||
446 | return $this->clients->first(); | ||
447 | } | ||
448 | } | ||
449 | + | ||
450 | + /** | ||
451 | + * Set dn. | ||
452 | + * | ||
453 | + * @param string $dn | ||
454 | + * | ||
455 | + * @return User | ||
456 | + */ | ||
457 | + public function setDn($dn) | ||
458 | + { | ||
459 | + $this->dn = $dn; | ||
460 | + | ||
461 | + return $this; | ||
462 | + } | ||
463 | + | ||
464 | + /** | ||
465 | + * Get dn. | ||
466 | + * | ||
467 | + * @return string | ||
468 | + */ | ||
469 | + public function getDn() | ||
470 | + { | ||
471 | + return $this->dn; | ||
472 | + } | ||
473 | + | ||
474 | + public function isLdapUser() | ||
475 | + { | ||
476 | + return $this->dn !== null; | ||
477 | + } | ||
478 | } | ||
479 | diff --git a/src/Wallabag/UserBundle/LdapHydrator.php b/src/Wallabag/UserBundle/LdapHydrator.php | ||
480 | new file mode 100644 | ||
481 | index 00000000..cea2450f | ||
482 | --- /dev/null | ||
483 | +++ b/src/Wallabag/UserBundle/LdapHydrator.php | ||
484 | @@ -0,0 +1,103 @@ | ||
485 | +<?php | ||
486 | + | ||
487 | +namespace Wallabag\UserBundle; | ||
488 | + | ||
489 | +use FR3D\LdapBundle\Hydrator\HydratorInterface; | ||
490 | +use FOS\UserBundle\FOSUserEvents; | ||
491 | +use FOS\UserBundle\Event\UserEvent; | ||
492 | + | ||
493 | +class LdapHydrator implements HydratorInterface | ||
494 | +{ | ||
495 | + private $userManager; | ||
496 | + private $eventDispatcher; | ||
497 | + private $attributesMap; | ||
498 | + private $enabledAttribute; | ||
499 | + private $ldapBaseDn; | ||
500 | + private $ldapAdminFilter; | ||
501 | + private $ldapDriver; | ||
502 | + | ||
503 | + public function __construct( | ||
504 | + $user_manager, | ||
505 | + $event_dispatcher, | ||
506 | + array $attributes_map, | ||
507 | + $ldap_base_dn, | ||
508 | + $ldap_admin_filter, | ||
509 | + $ldap_driver | ||
510 | + ) { | ||
511 | + $this->userManager = $user_manager; | ||
512 | + $this->eventDispatcher = $event_dispatcher; | ||
513 | + | ||
514 | + $this->attributesMap = array( | ||
515 | + 'setUsername' => $attributes_map[0], | ||
516 | + 'setEmail' => $attributes_map[1], | ||
517 | + 'setName' => $attributes_map[2], | ||
518 | + ); | ||
519 | + $this->enabledAttribute = $attributes_map[3]; | ||
520 | + | ||
521 | + $this->ldapBaseDn = $ldap_base_dn; | ||
522 | + $this->ldapAdminFilter = $ldap_admin_filter; | ||
523 | + $this->ldapDriver = $ldap_driver; | ||
524 | + } | ||
525 | + | ||
526 | + public function hydrate(array $ldapEntry) | ||
527 | + { | ||
528 | + $user = $this->userManager->findUserBy(array('dn' => $ldapEntry['dn'])); | ||
529 | + | ||
530 | + if (!$user) { | ||
531 | + $user = $this->userManager->createUser(); | ||
532 | + $user->setDn($ldapEntry['dn']); | ||
533 | + $user->setPassword(''); | ||
534 | + $user->setSalt(''); | ||
535 | + $this->updateUserFields($user, $ldapEntry); | ||
536 | + | ||
537 | + $event = new UserEvent($user); | ||
538 | + $this->eventDispatcher->dispatch(FOSUserEvents::USER_CREATED, $event); | ||
539 | + | ||
540 | + $this->userManager->reloadUser($user); | ||
541 | + } else { | ||
542 | + $this->updateUserFields($user, $ldapEntry); | ||
543 | + } | ||
544 | + | ||
545 | + return $user; | ||
546 | + } | ||
547 | + | ||
548 | + private function updateUserFields($user, $ldapEntry) | ||
549 | + { | ||
550 | + foreach ($this->attributesMap as $key => $value) { | ||
551 | + if (is_array($ldapEntry[$value])) { | ||
552 | + $ldap_value = $ldapEntry[$value][0]; | ||
553 | + } else { | ||
554 | + $ldap_value = $ldapEntry[$value]; | ||
555 | + } | ||
556 | + | ||
557 | + call_user_func([$user, $key], $ldap_value); | ||
558 | + } | ||
559 | + | ||
560 | + if ($this->enabledAttribute !== null) { | ||
561 | + $user->setEnabled($ldapEntry[$this->enabledAttribute]); | ||
562 | + } else { | ||
563 | + $user->setEnabled(true); | ||
564 | + } | ||
565 | + | ||
566 | + if ($this->isAdmin($user)) { | ||
567 | + $user->addRole('ROLE_SUPER_ADMIN'); | ||
568 | + } else { | ||
569 | + $user->removeRole('ROLE_SUPER_ADMIN'); | ||
570 | + } | ||
571 | + | ||
572 | + $this->userManager->updateUser($user, true); | ||
573 | + } | ||
574 | + | ||
575 | + private function isAdmin($user) | ||
576 | + { | ||
577 | + if ($this->ldapAdminFilter === null) { | ||
578 | + return false; | ||
579 | + } | ||
580 | + | ||
581 | + $escaped_username = ldap_escape($user->getUsername(), '', LDAP_ESCAPE_FILTER); | ||
582 | + $filter = sprintf($this->ldapAdminFilter, $escaped_username); | ||
583 | + $entries = $this->ldapDriver->search($this->ldapBaseDn, $filter); | ||
584 | + | ||
585 | + return $entries['count'] == 1; | ||
586 | + } | ||
587 | +} | ||
588 | diff --git a/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php | ||
589 | new file mode 100644 | ||
590 | index 00000000..8a851f12 | ||
591 | --- /dev/null | ||
592 | +++ b/src/Wallabag/UserBundle/OAuthStorageLdapWrapper.php | ||
593 | @@ -0,0 +1,43 @@ | ||
594 | +<?php | ||
595 | + | ||
596 | +namespace Wallabag\UserBundle; | ||
597 | + | ||
598 | +use FOS\OAuthServerBundle\Storage\OAuthStorage; | ||
599 | +use OAuth2\Model\IOAuth2Client; | ||
600 | +use Symfony\Component\Security\Core\Exception\AuthenticationException; | ||
601 | + | ||
602 | +class OAuthStorageLdapWrapper extends OAuthStorage | ||
603 | +{ | ||
604 | + private $ldapManager; | ||
605 | + | ||
606 | + public function setLdapManager($ldap_manager) | ||
607 | + { | ||
608 | + $this->ldapManager = $ldap_manager; | ||
609 | + } | ||
610 | + | ||
611 | + public function checkUserCredentials(IOAuth2Client $client, $username, $password) | ||
612 | + { | ||
613 | + try { | ||
614 | + $user = $this->userProvider->loadUserByUsername($username); | ||
615 | + } catch (AuthenticationException $e) { | ||
616 | + return false; | ||
617 | + } | ||
618 | + | ||
619 | + if ($user->isLdapUser()) { | ||
620 | + return $this->checkLdapUserCredentials($user, $password); | ||
621 | + } else { | ||
622 | + return parent::checkUserCredentials($client, $username, $password); | ||
623 | + } | ||
624 | + } | ||
625 | + | ||
626 | + private function checkLdapUserCredentials($user, $password) | ||
627 | + { | ||
628 | + if ($this->ldapManager->bind($user, $password)) { | ||
629 | + return array( | ||
630 | + 'data' => $user, | ||
631 | + ); | ||
632 | + } else { | ||
633 | + return false; | ||
634 | + } | ||
635 | + } | ||
636 | +} | ||
637 | diff --git a/src/Wallabag/UserBundle/Resources/config/ldap.yml b/src/Wallabag/UserBundle/Resources/config/ldap.yml | ||
638 | new file mode 100644 | ||
639 | index 00000000..5ec16088 | ||
640 | --- /dev/null | ||
641 | +++ b/src/Wallabag/UserBundle/Resources/config/ldap.yml | ||
642 | @@ -0,0 +1,28 @@ | ||
643 | +fr3d_ldap: | ||
644 | + service: | ||
645 | + user_hydrator: ldap_user_hydrator | ||
646 | + driver: | ||
647 | + host: "%ldap_host%" | ||
648 | + port: "%ldap_port%" | ||
649 | + useSsl: "%ldap_ssl%" | ||
650 | + useStartTls: "%ldap_tls%" | ||
651 | + bindRequiresDn: "%ldap_bind_requires_dn%" | ||
652 | + username: "%ldap_manager_dn%" | ||
653 | + password: "%ldap_manager_pw%" | ||
654 | + user: | ||
655 | + baseDn: "%ldap_base%" | ||
656 | + filter: "%ldap_filter%" | ||
657 | + usernameAttribute: "%ldap_username_attribute%" | ||
658 | +security: | ||
659 | + providers: | ||
660 | + chain_provider: | ||
661 | + chain: | ||
662 | + providers: [ fr3d_ldapbundle, fos_userbundle ] | ||
663 | + fr3d_ldapbundle: | ||
664 | + id: fr3d_ldap.security.user.provider | ||
665 | + firewalls: | ||
666 | + secured_area: | ||
667 | + fr3d_ldap: ~ | ||
668 | + form_login: | ||
669 | + provider: chain_provider | ||
670 | + | ||
671 | diff --git a/src/Wallabag/UserBundle/Resources/config/ldap_services.yml b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml | ||
672 | new file mode 100644 | ||
673 | index 00000000..b3e3fd8a | ||
674 | --- /dev/null | ||
675 | +++ b/src/Wallabag/UserBundle/Resources/config/ldap_services.yml | ||
676 | @@ -0,0 +1,22 @@ | ||
677 | +services: | ||
678 | + fos_oauth_server.server: | ||
679 | + class: OAuth2\OAuth2 | ||
680 | + arguments: | ||
681 | + - "@oauth_storage_ldap_wrapper" | ||
682 | + - "%fos_oauth_server.server.options%" | ||
683 | + oauth_storage_ldap_wrapper: | ||
684 | + class: Wallabag\UserBundle\OAuthStorageLdapWrapper | ||
685 | + parent: fos_oauth_server.storage | ||
686 | + calls: | ||
687 | + - [setLdapManager, ["@fr3d_ldap.ldap_manager"]] | ||
688 | + | ||
689 | + ldap_user_hydrator: | ||
690 | + class: Wallabag\UserBundle\LdapHydrator | ||
691 | + arguments: | ||
692 | + - "@fos_user.user_manager" | ||
693 | + - "@event_dispatcher" | ||
694 | + - [ "%ldap_username_attribute%", "%ldap_email_attribute%", "%ldap_name_attribute%", "%ldap_enabled_attribute%" ] | ||
695 | + - "%ldap_base%" | ||
696 | + - "%ldap_admin_filter%" | ||
697 | + - "@fr3d_ldap.ldap_driver" | ||
698 | + | ||