LDAP: use OC_Cache to cache results from LDAP. Default is set to 10 min. Should improve performance especially when LDAP users use the sync client, because userExists checks with the LDAP server are reduced.
This commit is contained in:
parent
e0121ea75e
commit
6c92a85d49
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
$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();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" />
|
||||
<label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php if (isset($_['ldap_quota_def'])) echo $_['ldap_quota_def']; ?>" />bytes</p>
|
||||
<p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
|
||||
<p><label for="ldap_cache_ttl">Cache Time-To-Live</label><input type="text" id="ldap_cache_ttl" name="ldap_cache_ttl" value="<?php echo $_['ldap_cache_ttl']; ?>" /><small><?php echo $l->t('in seconds');?></small></p>
|
||||
</fieldset>
|
||||
<input type="submit" value="Save" /> <a href="http://owncloud.org/support/ldap-backend/" target="_blank"><img src="<?php echo OCP\Util::imagePath('','actions/info.png'); ?>" style="height:1.75ex" /> <?php echo $l->t('Help');?></a>
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue