Skip to content

Commit

Permalink
More flexible exclude option
Browse files Browse the repository at this point in the history
  • Loading branch information
Alessandro Pozzi committed Mar 21, 2018
1 parent fdaa0f2 commit b35aaba
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 8 deletions.
18 changes: 17 additions & 1 deletion src/DependencyInjection/AlepLdapExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ public function load(array $configs, ContainerBuilder $container)
if(!$config['enabled']) {
$container->removeDefinition('Alep\LdapBundle\EventListener\LoginListener');
} else {

//Support for deprecated exclude configuration
if(isset($config['exclude']) && is_array($config['exclude']) && !empty($config['exclude'])) {
if(isset($config['exclude_rules']) && is_array($config['exclude_rules'])) {
if(isset($config['exclude_rules']['users']) && is_array($config['exclude_rules']['users'])) {
$config['exclude_rules']['users'] = array_merge($config['exclude_rules']['users'], $config['exclude']);
} else {
$config['exclude_rules']['users'] = $config['exclude'];
}
} else {
$config['exclude_rules'] = array(
'users' => $config['exclude']
);
}
}

$loginListenerDefinition = $container->getDefinition('Alep\LdapBundle\EventListener\LoginListener');
$loginListenerDefinition->setArguments(array(
new Reference($config['service']),
Expand All @@ -50,7 +66,7 @@ public function load(array $configs, ContainerBuilder $container)
$config['default_roles'],
$config['uid_key'],
$config['filter'],
$config['exclude'],
$config['exclude_rules'],
new Reference($config['mapper'])
));
}
Expand Down
10 changes: 9 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,18 @@ public function getConfigTreeBuilder()
->cannotBeEmpty()
->defaultValue('({uid_key}={username})')
->end()
->arrayNode('exclude')
->arrayNode('exclude')
->info('This is a list of usernames to exclude from LDAP authentication.')
->setDeprecated('The "%node%" option is deprecated. Use "exclude_rules" instead.')
->scalarPrototype()->end()
->end()
->arrayNode('exclude_rules')
->info('This is a list of usernames/roles to exclude from LDAP authentication (supports regular expressions).')
->children()
->arrayNode('users')->scalarPrototype()->end()->end()
->arrayNode('roles')->scalarPrototype()->end()->end()
->end()
->end()
->scalarNode('mapper')
->info('This is the data mapper service used to map ldap user data to Pimcore user.')
->cannotBeEmpty()
Expand Down
74 changes: 69 additions & 5 deletions src/EventListener/LoginListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ class LoginListener
* @param string[] $default_roles
* @param string $uid_key
* @param string $filter
* @param string[] $exclude
* @param array $exclude_rules
* @param LdapUserMapperInterface $mapper
*/
public function __construct(Ldap $ldap, $base_dn, $search_dn, $search_password, $default_roles, $uid_key, $filter, $exclude, LdapUserMapperInterface $mapper)
public function __construct(Ldap $ldap, $base_dn, $search_dn, $search_password, $default_roles, $uid_key, $filter, $exclude_rules, LdapUserMapperInterface $mapper)
{
$this->ldap = $ldap;
$this->base_dn = $base_dn;
Expand All @@ -91,7 +91,7 @@ public function __construct(Ldap $ldap, $base_dn, $search_dn, $search_password,
$this->default_roles = (is_array($default_roles)) ? $default_roles : array();
$this->uid_key = $uid_key;
$this->filter = str_replace('{uid_key}', $uid_key, $filter);
$this->exclude = (is_array($exclude)) ? $exclude : array();
$this->exclude_rules = (is_array($exclude_rules)) ? $exclude_rules : array();
$this->mapper = $mapper;

$this->ldap->bind($search_dn, $search_password);
Expand All @@ -108,7 +108,7 @@ public function onAdminLoginCredentials(LoginCredentialsEvent $event)
$password = $credentials['password'];

//Check if this user has to be excluded
if(in_array($username, $this->exclude)) return;
if($this->isExcluded($username)) return;

//Authenticate via ldap
$ldap_user = $this->authenticate($username, $password);
Expand All @@ -127,7 +127,7 @@ public function onAdminLoginFailed(LoginFailedEvent $event)
$password = $event->getCredential('password');

//Check if this user has to be excluded
if(in_array($username, $this->exclude)) return;
if($this->isExcluded($username)) return;

//authenticate via ldap
$ldap_user = $this->authenticate($username, $password);
Expand All @@ -139,6 +139,67 @@ public function onAdminLoginFailed(LoginFailedEvent $event)
$event->setUser($pimcore_user);
}

/**
* @param string $username
* @return bool
*/
private function isExcluded($username) {

//Check users excluding rules
if(isset($this->exclude_rules['users'])) {
foreach ($this->exclude_rules['users'] as $userExcludeRule) {
if (@preg_match($userExcludeRule, null) !== false) { //Check as regex (@ sign in front of the regex function is to prevent warnings on the valid regex test)
if (preg_match($userExcludeRule, $username)) {
return true;
}
} elseif ($username == $userExcludeRule) { //Check as string
return true;
}
}
}

//Check roles excluding rules
if(isset($this->exclude_rules['roles'])) {
$roles = $this->getUserRoleNames($username);
if(!empty($roles)) {
foreach ($this->exclude_rules['roles'] as $roleExcludeRule) {
if (@preg_match($roleExcludeRule, null) !== false) { //Check as regex (@ sign in front of the regex function is to prevent warnings on the valid regex test)
if (preg_grep($roleExcludeRule, $roles)) {
return true;
}
} elseif (in_array($roleExcludeRule, $roles)) { //Check as string
return true;
}
}
}
}

return false;
}

/**
* @param string $username
* @return string[]
*/
private function getUserRoleNames($username) {
$roles = array();

//Get user
$user = User::getByName($username);
if($user instanceof User) {
//If the user is an admin add the role ROLE_PIMCORE_ADMIN automatically
if($user->isAdmin()) $roles[] = 'ROLE_PIMCORE_ADMIN';

//Get user's roles
foreach($user->getRoles() as $roleId) {
$role = User\Role::getById($roleId);
$roles[] = $role->getName();
}
}

return $roles;
}

/**
* @param string $username
* @param string $password
Expand Down Expand Up @@ -231,6 +292,9 @@ private function updatePimcoreUser($username, $password, $ldap_user)
}
}

/**
* @return interger[]
*/
private function getDefaultRolesIds() {
$default_roles_ids = array();

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/config/pimcore/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ alep_ldap:
default_roles: ~
uid_key: 'sAMAccountName'
filter: '({uid_key}={username})'
exclude: ~
exclude_rules: ~
mapper: 'Alep\LdapBundle\DataMapper\DefaultLdapUserMapper'

0 comments on commit b35aaba

Please sign in to comment.