diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index b9f4bdf199..aff25593ef 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -26,11 +26,6 @@ namespace OCA\user_ldap; class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { protected $enabled = false; - protected $_group_user = array(); - protected $_user_groups = array(); - protected $_group_users = array(); - protected $_groups = array(); - public function setConnector(lib\Connection &$connection) { parent::setConnector($connection); if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) { @@ -51,18 +46,20 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$this->enabled) { return false; } - if(isset($this->_group_user[$gid][$uid])) { - return $this->_group_user[$gid][$uid]; + if($this->connection->isCached('inGroup'.$uid.':'.$gid)) { + return $this->connection->getFromCache('inGroup'.$uid.':'.$gid); } $dn_user = $this->username2dn($uid); $dn_group = $this->groupname2dn($gid); // just in case if(!$dn_group || !$dn_user) { + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, false); return false; } @@ -81,8 +78,10 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { $members = $dns; } - $this->_group_user[$gid][$uid] = in_array($dn_user, $members); - return $this->_group_user[$gid][$uid]; + $isInGroup = in_array($dn_user, $members); + $this->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup); + + return $isInGroup; } /** @@ -97,12 +96,12 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$this->enabled) { return array(); } - if(isset($this->_user_groups[$uid])) { - return $this->_user_groups[$uid]; + if($this->connection->isCached('getUserGroups'.$uid)) { + return $this->connection->getFromCache('getUserGroups'.$uid); } $userDN = $this->username2dn($uid); if(!$userDN) { - $this->_user_groups[$uid] = array(); + $this->connection->writeToCache('getUserGroups'.$uid, array()); return array(); } @@ -124,9 +123,10 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { $this->connection->ldapGroupMemberAssocAttr.'='.$uid )); $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn')); - $this->_user_groups[$uid] = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $groups = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING); + $this->connection->writeToCache('getUserGroups'.$uid, $groups); - return $this->_user_groups[$uid]; + return $groups; } /** @@ -137,19 +137,19 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$this->enabled) { return array(); } - if(isset($this->_group_users[$gid])) { - return $this->_group_users[$gid]; + if($this->connection->isCached('usersInGroup'.$gid)) { + return $this->connection->getFromCache('usersInGroup'.$gid); } $groupDN = $this->groupname2dn($gid); if(!$groupDN) { - $this->_group_users[$gid] = array(); + $this->connection->writeToCache('usersInGroup'.$gid, array()); return array(); } $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr); if(!$members) { - $this->_group_users[$gid] = array(); + $this->connection->writeToCache('usersInGroup'.$gid, array()); return array(); } @@ -173,8 +173,10 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$isMemberUid) { $result = array_intersect($result, \OCP\User::getUsers()); } - $this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING); - return $this->_group_users[$gid]; + $groupUsers = array_unique($result, SORT_LOCALE_STRING); + $this->connection->writeToCache('usersInGroup'.$gid, $groupUsers); + + return $groupUsers; } /** @@ -187,11 +189,14 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface { if(!$this->enabled) { return array(); } - if(empty($this->_groups)) { - $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn')); - $this->_groups = $this->ownCloudGroupNames($ldap_groups); + if($this->connection->isCached('getGroups')) { + return $this->connection->getFromCache('getGroups'); } - return $this->_groups; + $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn')); + $ldap_groups = $this->ownCloudGroupNames($ldap_groups); + $this->connection->writeToCache('getGroups', $ldap_groups); + + return $ldap_groups; } /** diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 96ffea4b64..cd9c83ff33 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -28,7 +28,10 @@ class Connection { private $configID; private $configured = false; - //cached settings + //cache handler + protected $cache; + + //settings protected $config = array( 'ldapHost' => null, 'ldapPort' => null, @@ -48,10 +51,12 @@ class Connection { 'ldapQuotaAttribute' => null, 'ldapQuotaDefault' => null, 'ldapEmailAttribute' => null, + 'ldapCacheTTL' => null, ); public function __construct($configID = 'user_ldap') { $this->configID = $configID; + $this->cache = \OC_Cache::getGlobalCache(); } public function __destruct() { @@ -92,6 +97,57 @@ class Connection { return $this->ldapConnectionRes; } + private function getCacheKey($key) { + $prefix = 'LDAP-'.$this->configID.'-'; + if(is_null($key)) { + return $prefix; + } + return $prefix.md5($key); + } + + public function getFromCache($key) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return null; + } + if(!$this->isCached($key)) { + return null; + + } + $key = $this->getCacheKey($key); + + return unserialize(base64_decode($this->cache->get($key))); + } + + public function isCached($key) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return false; + } + $key = $this->getCacheKey($key); + return $this->cache->hasKey($key); + } + + public function writeToCache($key, $value) { + if(!$this->configured) { + $this->readConfiguration(); + } + if(!$this->config['ldapCacheTTL']) { + return null; + } + $key = $this->getCacheKey($key); + $value = base64_encode(serialize($value)); + $this->cache->set($key, $value, $this->config['ldapCacheTTL']); + } + + public function clearCache() { + $this->cache->clear($this->getCacheKey(null)); + } + /** * Caches the general LDAP configuration. */ @@ -118,6 +174,7 @@ class Connection { $this->config['ldapEmailAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', ''); $this->config['ldapGroupMemberAssocAttr'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember'); $this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); + $this->config['ldapCacheTTL'] = \OCP\Config::getAppValue($this->configID, 'ldap_cache_ttl', 10*60); $this->configured = $this->validateConfiguration(); } diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index 42084855e8..135c735e70 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -20,7 +20,7 @@ * License along with this library. If not, see . * */ -$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_group_filter', 'ldap_display_name', 'ldap_group_display_name', 'ldap_tls', 'ldap_nocase', 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr', 'ldap_group_member_assoc_attribute'); +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_agent_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_group_filter', 'ldap_display_name', 'ldap_group_display_name', 'ldap_tls', 'ldap_nocase', 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr', 'ldap_group_member_assoc_attribute', 'ldap_cache_ttl'); OCP\Util::addscript('user_ldap', 'settings'); @@ -29,18 +29,23 @@ if ($_POST) { if(isset($_POST[$param])){ if('ldap_agent_password' == $param) { OCP\Config::setAppValue('user_ldap', $param, base64_encode($_POST[$param])); + } elseif('ldap_cache_ttl' == $param) { + if(OCP\Config::getAppValue('user_ldap', $param,'') != $_POST[$param]) { + $ldap = new \OCA\user_ldap\lib\Connection('user_ldap'); + $ldap->clearCache(); + OCP\Config::setAppValue('user_ldap', $param, $_POST[$param]); + } } else { OCP\Config::setAppValue('user_ldap', $param, $_POST[$param]); } } elseif('ldap_tls' == $param) { // unchecked checkboxes are not included in the post paramters - OCP\Config::setAppValue('user_ldap', $param, 0); + OCP\Config::setAppValue('user_ldap', $param, 0); } elseif('ldap_nocase' == $param) { OCP\Config::setAppValue('user_ldap', $param, 0); } - } } @@ -57,5 +62,6 @@ $tmpl->assign( 'ldap_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_d $tmpl->assign( 'ldap_group_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', 'cn')); $tmpl->assign( 'ldap_group_member_assoc_attribute', OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember')); $tmpl->assign( 'ldap_agent_password', base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password'))); +$tmpl->assign( 'ldap_cache_ttl', OCP\Config::getAppValue('user_ldap', 'ldap_cache_ttl', '600')); return $tmpl->fetchPage(); diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 31f453b5a5..cc61598a26 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -26,6 +26,7 @@

bytes

+

t('in seconds');?>

t('Help');?> diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 61f84047f1..57b2ef489b 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -27,9 +27,6 @@ namespace OCA\user_ldap; class USER_LDAP extends lib\Access implements \OCP\UserInterface { - // cache getUsers() - protected $_users = null; - private function updateQuota($dn) { $quota = null; if(!empty($this->connection->ldapQuotaDefault)) { @@ -97,11 +94,13 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { * Get a list of all users. */ public function getUsers(){ - if(is_null($this->_users)) { + $ldap_users = $this->connection->getFromCache('getUsers'); + if(is_null($ldap_users)) { $ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn')); - $this->_users = $this->ownCloudUserNames($ldap_users); + $ldap_users = $this->ownCloudUserNames($ldap_users); + $this->connection->writeToCache('getUsers', $ldap_users); } - return $this->_users; + return $ldap_users; } /** @@ -110,18 +109,25 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { * @return boolean */ public function userExists($uid){ + if($this->connection->isCached('userExists'.$uid)) { + return $this->connection->getFromCache('userExists'.$uid); + } + //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking. $dn = $this->username2dn($uid); if(!$dn) { + $this->connection->writeToCache('userExists'.$uid, false); return false; } //if user really still exists, we will be able to read his cn $cn = $this->readAttribute($dn, 'cn'); if(!$cn || empty($cn)) { + $this->connection->writeToCache('userExists'.$uid, false); return false; } + $this->connection->writeToCache('userExists'.$uid, true); return true; }