Skip to content

Commit

Permalink
feature #31532 [Ldap] Add users extraFields in ldap component (Simper…
Browse files Browse the repository at this point in the history
…fit)

This PR was merged into the 4.4 branch.

Discussion
----------

[Ldap] Add users extraFields in ldap component

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes <!-- please update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | yes <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #28873, #19329 <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | todo when validated, before merge <!-- required for new features -->

As I'm using ldap too in some personal project, It seems that this feature is a really good nice to have IMHO.

Adding the wanted field in the `user_metadata` array transform them as field -> value in the `metadata` field of the user.

Commits
-------

bcfff04 [Ldap] Add users extra_fields in ldap component
  • Loading branch information
fabpot committed Jun 22, 2019
2 parents 115e67b + bcfff04 commit aa4385d
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 4 deletions.
Expand Up @@ -36,6 +36,7 @@ public function create(ContainerBuilder $container, $id, $config)
->replaceArgument(5, $config['uid_key'])
->replaceArgument(6, $config['filter'])
->replaceArgument(7, $config['password_attribute'])
->replaceArgument(8, $config['extra_fields'])
;
}

Expand All @@ -52,6 +53,9 @@ public function addConfiguration(NodeDefinition $node)
->scalarNode('base_dn')->isRequired()->cannotBeEmpty()->end()
->scalarNode('search_dn')->end()
->scalarNode('search_password')->end()
->arrayNode('extra_fields')
->prototype('scalar')->end()
->end()
->arrayNode('default_roles')
->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); })->end()
->requiresAtLeastOneElement()
Expand Down
Expand Up @@ -184,6 +184,7 @@
<argument /> <!-- uid key -->
<argument /> <!-- filter -->
<argument /> <!-- password_attribute -->
<argument /> <!-- extra_fields (email etc) -->
</service>

<service id="security.user.provider.chain" class="Symfony\Component\Security\Core\User\ChainUserProvider" abstract="true" />
Expand Down
Expand Up @@ -21,6 +21,7 @@ security:
search_password: ''
default_roles: ROLE_USER
uid_key: uid
extra_fields: ['email']

firewalls:
main:
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Ldap/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========

4.4.0
-----

* Added the "extra_fields" option, an array of custom fields to pull from the LDAP server

4.3.0
-----

Expand Down
Expand Up @@ -334,6 +334,7 @@ public function testLoadUserByUsernameIsSuccessfulWithPasswordAttribute()
->willReturn(new Entry('foo', [
'sAMAccountName' => ['foo'],
'userpassword' => ['bar'],
'email' => ['elsa@symfony.com'],
]
))
;
Expand All @@ -353,7 +354,7 @@ public function testLoadUserByUsernameIsSuccessfulWithPasswordAttribute()
->willReturn($query)
;

$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword');
$provider = new LdapUserProvider($ldap, 'ou=MyBusiness,dc=symfony,dc=com', null, null, [], 'sAMAccountName', '({uid_key}={username})', 'userpassword', ['email']);
$this->assertInstanceOf(
'Symfony\Component\Security\Core\User\User',
$provider->loadUserByUsername('foo')
Expand Down
11 changes: 9 additions & 2 deletions src/Symfony/Component/Security/Core/User/LdapUserProvider.php
Expand Up @@ -34,8 +34,9 @@ class LdapUserProvider implements UserProviderInterface
private $uidKey;
private $defaultSearch;
private $passwordAttribute;
private $extraFields;

public function __construct(LdapInterface $ldap, string $baseDn, string $searchDn = null, string $searchPassword = null, array $defaultRoles = [], string $uidKey = null, string $filter = null, string $passwordAttribute = null)
public function __construct(LdapInterface $ldap, string $baseDn, string $searchDn = null, string $searchPassword = null, array $defaultRoles = [], string $uidKey = null, string $filter = null, string $passwordAttribute = null, array $extraFields = [])
{
if (null === $uidKey) {
$uidKey = 'sAMAccountName';
Expand All @@ -53,6 +54,7 @@ public function __construct(LdapInterface $ldap, string $baseDn, string $searchD
$this->uidKey = $uidKey;
$this->defaultSearch = str_replace('{uid_key}', $uidKey, $filter);
$this->passwordAttribute = $passwordAttribute;
$this->extraFields = $extraFields;
}

/**
Expand Down Expand Up @@ -123,12 +125,17 @@ public function supportsClass($class)
protected function loadUser($username, Entry $entry)
{
$password = null;
$extraFields = [];

if (null !== $this->passwordAttribute) {
$password = $this->getAttributeValue($entry, $this->passwordAttribute);
}

return new User($username, $password, $this->defaultRoles);
foreach ($this->extraFields as $field) {
$extraFields[$field] = $this->getAttributeValue($entry, $field);
}

return new User($username, $password, $this->defaultRoles, true, true, true, true, $extraFields);
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/Symfony/Component/Security/Core/User/User.php
Expand Up @@ -27,8 +27,9 @@ final class User implements UserInterface, EquatableInterface, AdvancedUserInter
private $credentialsNonExpired;
private $accountNonLocked;
private $roles;
private $extraFields;

public function __construct(?string $username, ?string $password, array $roles = [], bool $enabled = true, bool $userNonExpired = true, bool $credentialsNonExpired = true, bool $userNonLocked = true)
public function __construct(?string $username, ?string $password, array $roles = [], bool $enabled = true, bool $userNonExpired = true, bool $credentialsNonExpired = true, bool $userNonLocked = true, array $extraFields = [])
{
if ('' === $username || null === $username) {
throw new \InvalidArgumentException('The username cannot be empty.');
Expand All @@ -41,6 +42,7 @@ public function __construct(?string $username, ?string $password, array $roles =
$this->credentialsNonExpired = $credentialsNonExpired;
$this->accountNonLocked = $userNonLocked;
$this->roles = $roles;
$this->extraFields = $extraFields;
}

public function __toString()
Expand Down Expand Up @@ -118,6 +120,11 @@ public function eraseCredentials()
{
}

public function getExtraFields()
{
return $this->extraFields;
}

/**
* {@inheritdoc}
*/
Expand Down

0 comments on commit aa4385d

Please sign in to comment.