# DbpRelayBasePersonConnectorLdapBundle [GitLab](https://gitlab.tugraz.at/dbp/relay/dbp-relay-base-person-connector-ldap-bundle) | [Packagist](https://packagist.org/packages/dbp/relay-base-person-connector-ldap-bundle) This Symfony bundle contains LDAPPersonProvider services for the DBP Relay project. ## Integration into the API Server * Add the bundle package as a dependency: ```bash # You may want to first add the DBP Symfony recipe repository to your application to get the configuration file installed automatically # See: https://github.com/digital-blueprint/symfony-recipes # You can also use https://gitlab.tugraz.at/dbp/relay/dbp-relay-server-template as a template application, it has the repository included composer require dbp/relay-base-person-connector-ldap-bundle ``` * Add the bundle to your `config/bundles.php`: ```php ... Dbp\Relay\BasePersonConnectorLdapBundle\DbpRelayBasePersonConnectorLdapBundle::class => ['all' => true], DBP\API\CoreBundle\DbpCoreBundle::class => ['all' => true], ]; ``` * Run `composer install` to clear caches ## Configuration The bundle has some configuration values that you can specify in your app, either by hard-coding it, or by referencing an environment variable. For this create `config/packages/dbp_relay_base_person_connector_ldap.yaml` in the app with the following content: ```yaml dbp_relay_base_person_connector_ldap: ldap: host: '%env(LDAP_PERSON_PROVIDER_LDAP_HOST)%' base_dn: '%env(LDAP_PERSON_PROVIDER_LDAP_BASE_DN)%' username: '%env(LDAP_PERSON_PROVIDER_LDAP_USERNAME)%' password: '%env(LDAP_PERSON_PROVIDER_LDAP_PASSWORD)%' attributes: identifier: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_IDENTIFIER)%' given_name: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_GIVEN_NAME)%' family_name: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_FAMILY_NAME)%' email: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_EMAIL)%' birthday: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_BIRTHDAY)%' ``` For more info on bundle configuration see https://symfony.com/doc/current/bundles/configuration.html ## Events To modify the behavior of the connector bundle the following events are registered: ### PersonUserItemPreEvent This event allows to modify the identifier before a user is loaded from LDAP. An event subscriber receives a `\Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonUserItemPreEvent` instance in a service for example in `src/EventSubscriber/PersonUserItemSubscriber.php`: ```php <?php namespace App\EventSubscriber; use Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonUserItemPreEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class PersonUserItemSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ PersonUserItemPreEvent::NAME => 'onPre', ]; } public function onPre(PersonUserItemPreEvent $event) { $identifier = $event->getIdentifier(); // Example: // Replace once or double encoded $ character at the start like "%2524F1234" or "%24F1234" $identifier = preg_replace('/^%(25)?24/', '$', $identifier); $event->setIdentifier($identifier); } } ``` ### PersonFromUserItemPostEvent This event allows to modify a `Person` entity after it is created based on the data from the corresponding LDAP user. You can use it to populate the `Person` entity with additional data. For example, you can add additional "local data" attributes, which you want to include in responses to `Person` GET requests. Event subscribers receive a `\Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonFromUserItemPostEvent` instance containing the `Person` entity and all user attributes returned by the LDAP server. For example, create an event subscriber `src/EventSubscriber/PersonFromUserItemSubscriber.php`: ```php <?php namespace App\EventSubscriber; use Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonFromUserItemPostEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class PersonFromUserItemSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ PersonFromUserItemPostEvent::NAME => 'onPost', ]; } public function onPost(PersonFromUserItemPostEvent $event) { $attributes = $event->getAttributes(); $person = $event->getPerson(); $birthDateString = trim($attributes['dateofbirth'][0] ?? ''); if ($birthDateString !== '') { $matches = []; if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $birthDateString, $matches)) { $person->setBirthDate("{$matches[1]}-{$matches[2]}-{$matches[3]}"); // get birthday from LDAP DateOfBirth (e.g. 19810718) } elseif (preg_match('/^(\d{4})(\d{2})(\d{2})$/', $birthDateString, $matches)) { $person->setBirthDate("{$matches[1]}-{$matches[2]}-{$matches[3]}"); // sometimes also "1994-06-14 00:00:00" } elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2}) .*$/', $birthDateString, $matches)) { $person->setBirthDate("{$matches[1]}-{$matches[2]}-{$matches[3]}"); } } $person->setExtraData('special_data', $attributes['some_special_attribute'] ?? ''); $person->trySetLocalDataAttribute('foo', $attributes['foo']); } } ``` And add it to your `src/Resources/config/services.yaml`: ```yaml App\EventSubscriber\PersonFromUserItemSubscriber: autowire: true autoconfigure: true ``` ## Development & Testing * Install dependencies: `composer install` * Run tests: `composer test` * Run linters: `composer run lint` * Run cs-fixer: `composer run cs-fix` ## Bundle dependencies Don't forget you need to pull down your dependencies in your main application if you are installing packages in a bundle. ```bash # updates and installs dependencies from dbp/relay-base-person-connector-ldap-bundle composer update dbp/relay-base-person-connector-ldap-bundle ```