added local filtering
This commit is contained in:
parent
dfc3dcb4c6
commit
e2e75ece20
|
@ -2,6 +2,7 @@ June 2018 6.4
|
||||||
- Imagick PHP extension required
|
- Imagick PHP extension required
|
||||||
- Passwords can be checked against external service (e.g. https://api.pwnedpasswords.com/range)
|
- Passwords can be checked against external service (e.g. https://api.pwnedpasswords.com/range)
|
||||||
- Personal/Windows: image cropping support
|
- Personal/Windows: image cropping support
|
||||||
|
- Better filtering of account lists
|
||||||
- Unix: Unix and group of names memberships can be synced in group selection
|
- Unix: Unix and group of names memberships can be synced in group selection
|
||||||
- IMAP: create mailbox via file upload
|
- IMAP: create mailbox via file upload
|
||||||
- PHP 7.2 support
|
- PHP 7.2 support
|
||||||
|
|
|
@ -174,7 +174,7 @@ $helpArray = array (
|
||||||
"249" => array ("Headline" => _('External password check'),
|
"249" => array ("Headline" => _('External password check'),
|
||||||
"Text" => _('Please specify the URL (e.g. "https://api.pwnedpasswords.com/range/{SHA1PREFIX}") of your 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"),
|
"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"),
|
"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.')
|
"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.')
|
. ' ' . _('You can use the wildcard @@LOGIN_DN@@ which will be substituted with the DN of the user who is currently logged in to LAM.')
|
||||||
|
|
|
@ -108,8 +108,8 @@ class lamList {
|
||||||
const VIRTUAL_ATTRIBUTE_PREFIX = 'lam_virtual_';
|
const VIRTUAL_ATTRIBUTE_PREFIX = 'lam_virtual_';
|
||||||
|
|
||||||
const SERVER_SIDE_FILTER_ATTRIBUTES = array(
|
const SERVER_SIDE_FILTER_ATTRIBUTES = array(
|
||||||
'cn', 'uid', 'memberuid', 'description',
|
'cn', 'commonname', 'uid', 'memberuid', 'description',
|
||||||
'sn', 'surname', 'gn', 'givenname'
|
'sn', 'surname', 'gn', 'givenname', 'company', 'mail'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,6 +174,8 @@ class lamList {
|
||||||
if ($this->refresh) {
|
if ($this->refresh) {
|
||||||
$this->listRefreshData();
|
$this->listRefreshData();
|
||||||
}
|
}
|
||||||
|
// local filtering
|
||||||
|
$this->applyLocalFilters();
|
||||||
// sort rows by sort column
|
// sort rows by sort column
|
||||||
if (isset($this->entries)) {
|
if (isset($this->entries)) {
|
||||||
$this->listCreateSortMapping($this->entries);
|
$this->listCreateSortMapping($this->entries);
|
||||||
|
@ -1033,6 +1035,55 @@ class lamList {
|
||||||
return in_array(strtolower($attrName), lamList::SERVER_SIDE_FILTER_ATTRIBUTES);
|
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.
|
* 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).
|
* Function must be called before $this->refresh option is checked to load new LDAP data (e.g. in listGetParams).
|
||||||
|
|
|
@ -694,7 +694,7 @@ class lamUserList extends lamList {
|
||||||
}
|
}
|
||||||
// show account status
|
// show account status
|
||||||
if ($this->showAccountStatus) {
|
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.
|
* Injects values for the virtual account status attribute to make it sortable.
|
||||||
*/
|
*/
|
||||||
private function injectAccountStatusAttributeAndFilterByStatus() {
|
private function injectAccountStatusAttribute() {
|
||||||
$entryCount = sizeof($this->ldapEntries);
|
$entryCount = sizeof($this->ldapEntries);
|
||||||
for ($i = 0; $i < $entryCount; $i++) {
|
for ($i = 0; $i < $entryCount; $i++) {
|
||||||
$unixAvailable = self::isUnixAvailable($this->ldapEntries[$i]);
|
$unixAvailable = self::isUnixAvailable($this->ldapEntries[$i]);
|
||||||
|
@ -1007,17 +1007,29 @@ class lamUserList extends lamList {
|
||||||
elseif (!$hasUnlocked && $hasLocked) {
|
elseif (!$hasUnlocked && $hasLocked) {
|
||||||
$status = self::FILTER_LOCKED;
|
$status = self::FILTER_LOCKED;
|
||||||
}
|
}
|
||||||
// filter accounts
|
|
||||||
if (!empty($this->accountStatusFilter)) {
|
|
||||||
if ($status != $this->accountStatusFilter) {
|
|
||||||
unset($this->ldapEntries[$i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add virtual attribute
|
// add virtual attribute
|
||||||
$this->ldapEntries[$i][self::ATTR_ACCOUNT_STATUS][0] = $status;
|
$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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue