added local filtering

This commit is contained in:
Roland Gruber 2018-05-31 08:58:30 +02:00
parent dfc3dcb4c6
commit e2e75ece20
4 changed files with 77 additions and 13 deletions

View File

@ -2,6 +2,7 @@ June 2018 6.4
- Imagick PHP extension required
- Passwords can be checked against external service (e.g. https://api.pwnedpasswords.com/range)
- Personal/Windows: image cropping support
- Better filtering of account lists
- Unix: Unix and group of names memberships can be synced in group selection
- IMAP: create mailbox via file upload
- PHP 7.2 support

View File

@ -174,7 +174,7 @@ $helpArray = array (
"249" => array ("Headline" => _('External password check'),
"Text" => _('Please specify the URL (e.g. "https://api.pwnedpasswords.com/range/{SHA1PREFIX}") of your external password check.')),
"250" => array ("Headline" => _("Filter"),
"Text" => _("Here you can input simple filter expressions (e.g. 'value' or 'v*'). The filter is case-sensitive.")),
"Text" => _("Here you can input simple filter expressions (e.g. 'value' or 'v*'). The filter is case-insensitive.")),
"260" => array ("Headline" => _("Additional LDAP filter"),
"Text" => _('Use this to enter an additional LDAP filter (e.g. "(cn!=admin)") to reduce the number of visible elements for this account type.')
. ' ' . _('You can use the wildcard @@LOGIN_DN@@ which will be substituted with the DN of the user who is currently logged in to LAM.')

View File

@ -108,8 +108,8 @@ class lamList {
const VIRTUAL_ATTRIBUTE_PREFIX = 'lam_virtual_';
const SERVER_SIDE_FILTER_ATTRIBUTES = array(
'cn', 'uid', 'memberuid', 'description',
'sn', 'surname', 'gn', 'givenname'
'cn', 'commonname', 'uid', 'memberuid', 'description',
'sn', 'surname', 'gn', 'givenname', 'company', 'mail'
);
/**
@ -174,6 +174,8 @@ class lamList {
if ($this->refresh) {
$this->listRefreshData();
}
// local filtering
$this->applyLocalFilters();
// sort rows by sort column
if (isset($this->entries)) {
$this->listCreateSortMapping($this->entries);
@ -1033,6 +1035,55 @@ class lamList {
return in_array(strtolower($attrName), lamList::SERVER_SIDE_FILTER_ATTRIBUTES);
}
/**
* Applies any local filters for attributes that cannot be filtered server side.
*/
protected function applyLocalFilters() {
$this->entries = array();
foreach ($this->ldapEntries as $index => &$data) {
$this->entries[$index] = &$data;
}
$toFilter = array();
foreach ($this->filters as $filterAttribute => $filterValue) {
if ($this->isAttributeFilteredByServer($filterAttribute) || ($filterValue === '')) {
continue;
}
foreach ($this->entries as $index => &$data) {
if (in_array($index, $toFilter)) {
continue;
}
$regex = str_replace(array('*'), array('.*'), $filterValue);
$regex = '/^' . $regex . '$/i';
if (!$this->isFilterMatching($data, $filterAttribute, $regex)) {
$toFilter[] = $index;
}
}
}
foreach ($toFilter as $index) {
unset($this->entries[$index]);
}
$this->entries = array_values($this->entries);
}
/**
* Checks if the given LDAP data matches the filter.
*
* @param array $data LDAP attributes
* @param string $filterAttribute filter attribute name
* @param string $regex filter attribute regex
*/
protected function isFilterMatching(&$data, $filterAttribute, $regex) {
if (!isset($data[$filterAttribute])) {
return false;
}
foreach ($data[$filterAttribute] as $value) {
if (preg_match($regex, $value)) {
return true;
}
}
return false;
}
/**
* Forces a refresh of the LDAP data.
* Function must be called before $this->refresh option is checked to load new LDAP data (e.g. in listGetParams).

View File

@ -694,7 +694,7 @@ class lamUserList extends lamList {
}
// show account status
if ($this->showAccountStatus) {
$this->injectAccountStatusAttributeAndFilterByStatus();
$this->injectAccountStatusAttribute();
}
}
@ -968,7 +968,7 @@ class lamUserList extends lamList {
/**
* Injects values for the virtual account status attribute to make it sortable.
*/
private function injectAccountStatusAttributeAndFilterByStatus() {
private function injectAccountStatusAttribute() {
$entryCount = sizeof($this->ldapEntries);
for ($i = 0; $i < $entryCount; $i++) {
$unixAvailable = self::isUnixAvailable($this->ldapEntries[$i]);
@ -1007,17 +1007,29 @@ class lamUserList extends lamList {
elseif (!$hasUnlocked && $hasLocked) {
$status = self::FILTER_LOCKED;
}
// filter accounts
if (!empty($this->accountStatusFilter)) {
if ($status != $this->accountStatusFilter) {
unset($this->ldapEntries[$i]);
continue;
}
}
// add virtual attribute
$this->ldapEntries[$i][self::ATTR_ACCOUNT_STATUS][0] = $status;
}
$this->ldapEntries = array_values($this->ldapEntries);
}
/**
* {@inheritDoc}
* @see lamList::isFilterMatching()
*/
protected function isFilterMatching(&$data, $filterAttribute, $regex) {
if ($filterAttribute == self::ATTR_ACCOUNT_STATUS) {
return preg_match($regex, $data[self::ATTR_ACCOUNT_STATUS][0]);
}
if (($filterAttribute == 'gidnumber') && ($this->trans_primary == "on")) {
if (!isset($data[$filterAttribute])) {
return false;
}
if (!isset($this->trans_primary_hash[$data[$filterAttribute][0]])) {
return false;
}
return preg_match($regex, $this->trans_primary_hash[$data[$filterAttribute][0]]);
}
return parent::isFilterMatching($data, $filterAttribute, $regex);
}
/**