diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index bfe54a7..24d16a9 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -14,14 +14,15 @@ public function getConfigTreeBuilder() $rootNode ->children() ->append($this->addClientNode()) - ->append($this->addUserNode()) - ->append($this->addRoleNode()) ->scalarNode('user_class') ->defaultValue("IMAG\LdapBundle\User\LdapUser") ->end() ->end() ; - + + $this->addUserNode($rootNode); + $this->addRoleNode($rootNode); + return $treeBuilder; } @@ -48,45 +49,48 @@ private function addClientNode() return $node; } - private function addUserNode() + private function addUserNode(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $rootNode) { - $treeBuilder = new TreeBuilder(); - $node = $treeBuilder->root('user'); - - $node - ->isRequired() + $rootNode + ->fixXmlConfig('user', 'users') ->children() - ->scalarNode('base_dn')->isRequired()->cannotBeEmpty()->end() - ->scalarNode('filter')->end() - ->scalarNode('name_attribute')->defaultValue('uid')->end() - ->variableNode('attributes')->defaultValue(array())->end() + ->arrayNode('users') + ->isRequired() + ->prototype('array') + ->children() + ->scalarNode('base_dn')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('filter')->end() + ->scalarNode('name_attribute')->defaultValue('uid')->end() + ->variableNode('attributes')->defaultValue(array())->end() + ->end() + ->end() ->end() ; - - return $node; } - private function addRoleNode() + private function addRoleNode(\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $rootNode) { - $treeBuilder = new TreeBuilder(); - $node = $treeBuilder->root('role'); - - $node + $rootNode + ->fixXmlConfig('role', 'roles') ->children() - ->scalarNode('base_dn')->isRequired()->cannotBeEmpty()->end() - ->scalarNode('filter')->end() - ->scalarNode('name_attribute')->defaultValue('cn')->end() - ->scalarNode('user_attribute')->defaultValue('member')->end() - ->scalarNode('user_id')->defaultValue('dn') - ->validate() - ->ifNotInArray(array('dn', 'username')) - ->thenInvalid('Only dn or username') + ->arrayNode('roles') + ->isRequired() + ->prototype('array') + ->children() + ->scalarNode('base_dn')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('filter')->end() + ->scalarNode('name_attribute')->defaultValue('cn')->end() + ->scalarNode('user_attribute')->defaultValue('member')->end() + ->scalarNode('user_id')->defaultValue('dn') + ->validate() + ->ifNotInArray(array('dn', 'username')) + ->thenInvalid('Only dn or username') + ->end() + ->end() + ->end() ->end() - ->end() ->end() ; - - return $node; } } diff --git a/Manager/LdapManagerUser.php b/Manager/LdapManagerUser.php index 9cfef37..78c74a8 100644 --- a/Manager/LdapManagerUser.php +++ b/Manager/LdapManagerUser.php @@ -82,11 +82,13 @@ public function getEmail() public function getAttributes() { $attributes = array(); - foreach ($this->params['user']['attributes'] as $attrName) { - if (isset($this->ldapUser[$attrName][0])) { - $attributes[$attrName] = $this->ldapUser[$attrName][0]; + foreach($this->params['users'] as $param) { + foreach ($param['attributes'] as $attrName) { + if (isset($this->ldapUser[$attrName][0])) { + $attributes[$attrName] = $this->ldapUser[$attrName][0]; + } } - } + } return $attributes; } @@ -162,30 +164,40 @@ private function addLdapUser() if (!$this->username) { throw new \InvalidArgumentException('User is not defined, please use setUsername'); } + + $user = null; + $count = 0; + foreach($this->params['users'] as $param) + { + $filter = isset($param['filter']) + ? $param['filter'] + : ''; + + $entries = $this->ldapConnection + ->search(array( + 'base_dn' => $param['base_dn'], + 'filter' => sprintf('(&%s(%s=%s))', + $filter, + $param['name_attribute'], + $this->ldapConnection->escape($this->username) + ) + )); + + $count += $entries['count']; + + if($entries['count'] === 1) + $user = $entries[0]; + } - $filter = isset($this->params['user']['filter']) - ? $this->params['user']['filter'] - : ''; - - $entries = $this->ldapConnection - ->search(array( - 'base_dn' => $this->params['user']['base_dn'], - 'filter' => sprintf('(&%s(%s=%s))', - $filter, - $this->params['user']['name_attribute'], - $this->ldapConnection->escape($this->username) - ) - )); - - if ($entries['count'] > 1) { + if ($count > 1) { throw new \RuntimeException("This search can only return a single user"); } - if ($entries['count'] == 0) { + if ($count === 0) { throw new UsernameNotFoundException(sprintf('Username "%s" doesn\'t exists', $this->username)); } - $this->ldapUser = $entries[0]; + $this->ldapUser = $user; return $this; } @@ -201,7 +213,7 @@ private function addLdapRoles() if (null === $this->ldapUser) { throw new \RuntimeException('Cannot assign LDAP roles before authenticating user against LDAP'); } - + $this->ldapUser['roles'] = array(); if (true === $this->params['client']['skip_roles']) { @@ -210,33 +222,36 @@ private function addLdapRoles() return; } - if (!isset($this->params['role']) && false === $this->params['client']['skip_roles']) { + if (!isset($this->params['roles']) && false === $this->params['client']['skip_roles']) { throw new \InvalidArgumentException("If you want to skip getting the roles, set config option imag_ldap:client:skip_roles to true"); } $tab = array(); - - $filter = isset($this->params['role']['filter']) - ? $this->params['role']['filter'] - : ''; - - $entries = $this->ldapConnection - ->search(array( - 'base_dn' => $this->params['role']['base_dn'], - 'filter' => sprintf('(&%s(%s=%s))', - $filter, - $this->params['role']['user_attribute'], - $this->ldapConnection->escape($this->getUserId()) - ), - 'attrs' => array( - $this->params['role']['name_attribute'] - ) - )); - - for ($i = 0; $i < $entries['count']; $i++) { - array_push($tab, sprintf('ROLE_%s', - self::slugify($entries[$i][$this->params['role']['name_attribute']][0]) - )); + foreach($this->params['roles'] as $param) + { + + $filter = isset($param['filter']) + ? $param['filter'] + : ''; + + $entries = $this->ldapConnection + ->search(array( + 'base_dn' => $param['base_dn'], + 'filter' => sprintf('(&%s(%s=%s))', + $filter, + $param['user_attribute'], + $this->ldapConnection->escape($this->getUserId($param)) + ), + 'attrs' => array( + $param['name_attribute'] + ) + )); + + for ($i = 0; $i < $entries['count']; $i++) { + array_push($tab, sprintf('ROLE_%s', + self::slugify($entries[$i][$param['name_attribute']][0]) + )); + } } $this->ldapUser['roles'] = $tab; @@ -265,9 +280,9 @@ private static function slugify($role) return $role; } - private function getUserId() + private function getUserId(array $param) { - switch ($this->params['role']['user_id']) { + switch ($param['user_id']) { case 'dn': return $this->ldapUser['dn']; break; @@ -277,7 +292,7 @@ private function getUserId() break; default: - throw new \Exception(sprintf("The value can't be retrieved for this user_id : %s",$this->params['role']['user_id'])); + throw new \Exception(sprintf("The value can't be retrieved for this user_id : %s", $param['user_id'])); } } } diff --git a/README.md b/README.md index f71852c..1a5aefe 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,14 @@ imag_ldap: name_attribute: cn user_attribute: member user_id: [ dn or username ] - +# Search on several OU for users +# users: +# - { base_dn: 'ou=people,dc=host,dc=foo', filter: (objectClass=Person), name_attribute: uid } +# - { base_dn: 'ou=external people,dc=host,dc=foo', filter: (objectClass=Person), name_attribute: uid } +# Search on several OU for roles +# roles: +# - { base_dn: 'ou=group, dc=host, dc=foo', filter: (objectClass=group), name_attribute: cn, user_attribute: member, user_id: dn } +# - { base_dn: 'ou=other group, dc=host, dc=foo', filter: (objectClass=group), name_attribute: cn, user_attribute: member, user_id: dn } # user_class: IMAG\LdapBundle\User\LdapUser # Optional ```