read all relevant user attributes on login and user search, in one query. saves us some.
This commit is contained in:
parent
6f5f1c4f14
commit
9d03b7c6b7
|
@ -536,6 +536,16 @@ class Access extends LDAPUtility implements user\IUserTools {
|
||||||
return $ownCloudNames;
|
return $ownCloudNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* caches the user display name
|
||||||
|
* @param string $ocName the internal ownCloud username
|
||||||
|
* @param string|false $home the home directory path
|
||||||
|
*/
|
||||||
|
public function cacheUserHome($ocName, $home) {
|
||||||
|
$cacheKey = 'getHome'.$ocName;
|
||||||
|
$this->connection->writeToCache($cacheKey, $home);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* caches a user as existing
|
* caches a user as existing
|
||||||
* @param string $ocName the internal ownCloud username
|
* @param string $ocName the internal ownCloud username
|
||||||
|
@ -656,7 +666,24 @@ class Access extends LDAPUtility implements user\IUserTools {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function fetchListOfUsers($filter, $attr, $limit = null, $offset = null) {
|
public function fetchListOfUsers($filter, $attr, $limit = null, $offset = null) {
|
||||||
return $this->fetchList($this->searchUsers($filter, $attr, $limit, $offset), (count($attr) > 1));
|
$ldapRecords = $this->searchUsers($filter, $attr, $limit, $offset);
|
||||||
|
$this->batchApplyUserAttributes($ldapRecords);
|
||||||
|
return $this->fetchList($ldapRecords, (count($attr) > 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provided with an array of LDAP user records the method will fetch the
|
||||||
|
* user object and requests it to process the freshly fetched attributes and
|
||||||
|
* and their values
|
||||||
|
* @param array $ldapRecords
|
||||||
|
*/
|
||||||
|
public function batchApplyUserAttributes(array $ldapRecords){
|
||||||
|
foreach($ldapRecords as $userRecord) {
|
||||||
|
$ocName = $this->dn2ocname($userRecord['dn'], $userRecord[$this->connection->ldapUserDisplayName]);
|
||||||
|
$this->cacheUserExists($ocName);
|
||||||
|
$user = $this->userManager->get($ocName);
|
||||||
|
$user->processAttributes($userRecord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -126,6 +126,43 @@ class Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a list of attributes that will be processed further, e.g. quota,
|
||||||
|
* email, displayname, or others.
|
||||||
|
* @param bool $minimal - optional, set to true to skip attributes with big
|
||||||
|
* payload
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getAttributes($minimal = false) {
|
||||||
|
$attributes = array('dn', 'uid', 'samaccountname', 'memberof');
|
||||||
|
$possible = array(
|
||||||
|
$this->access->getConnection()->ldapQuotaAttribute,
|
||||||
|
$this->access->getConnection()->ldapEmailAttribute,
|
||||||
|
$this->access->getConnection()->ldapUserDisplayName,
|
||||||
|
);
|
||||||
|
foreach($possible as $attr) {
|
||||||
|
if(!is_null($attr)) {
|
||||||
|
$attributes[] = $attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$homeRule = $this->access->getConnection()->homeFolderNamingRule;
|
||||||
|
if(strpos($homeRule, 'attr:') === 0) {
|
||||||
|
$attributes[] = substr($homeRule, strlen('attr:'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$minimal) {
|
||||||
|
// attributes that are not really important but may come with big
|
||||||
|
// payload.
|
||||||
|
$attributes = array_merge($attributes, array(
|
||||||
|
'jpegphoto',
|
||||||
|
'thumbnailphoto'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the specified user is marked as deleted
|
* Checks whether the specified user is marked as deleted
|
||||||
* @param string $id the ownCloud user name
|
* @param string $id the ownCloud user name
|
||||||
|
|
|
@ -138,6 +138,69 @@ class User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* processes results from LDAP for attributes as returned by getAttributesToRead()
|
||||||
|
* @param array $ldapEntry the user entry as retrieved from LDAP
|
||||||
|
*/
|
||||||
|
public function processAttributes($ldapEntry) {
|
||||||
|
$this->markRefreshTime();
|
||||||
|
//Quota
|
||||||
|
$attr = strtolower($this->connection->ldapQuotaAttribute);
|
||||||
|
if(isset($ldapEntry[$attr])) {
|
||||||
|
$this->updateQuota($ldapEntry[$attr]);
|
||||||
|
}
|
||||||
|
unset($attr);
|
||||||
|
|
||||||
|
//Email
|
||||||
|
$attr = strtolower($this->connection->ldapEmailAttribute);
|
||||||
|
if(isset($ldapEntry[$attr])) {
|
||||||
|
$this->updateEmail($ldapEntry[$attr]);
|
||||||
|
}
|
||||||
|
unset($attr);
|
||||||
|
|
||||||
|
//displayName
|
||||||
|
$attr = strtolower($this->connection->ldapUserDisplayName);
|
||||||
|
if(isset($ldapEntry[$attr])) {
|
||||||
|
$displayName = $ldapEntry[$attr];
|
||||||
|
if(!empty($displayName)) {
|
||||||
|
$this->storeDisplayName($displayName);
|
||||||
|
$this->access->cacheUserDisplayName($this->getUsername(), $displayName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($attr);
|
||||||
|
|
||||||
|
// LDAP Username, needed for s2s sharing
|
||||||
|
if(isset($ldapEntry['uid'])) {
|
||||||
|
$this->storeLDAPUserName($ldapEntry['uid']);
|
||||||
|
} else if(isset($ldapEntry['samaccountname'])) {
|
||||||
|
$this->storeLDAPUserName($ldapEntry['samaccountname']);
|
||||||
|
}
|
||||||
|
//homePath
|
||||||
|
if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
|
||||||
|
$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
|
||||||
|
if(isset($ldapEntry[$attr])) {
|
||||||
|
$this->access->cacheUserHome(
|
||||||
|
$this->getUsername(), $this->getHomePath($ldapEntry[$attr]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//memberOf groups
|
||||||
|
$cacheKey = 'getMemberOf'.$this->getUsername();
|
||||||
|
$groups = false;
|
||||||
|
if(isset($ldapEntry['memberof'])) {
|
||||||
|
$groups = $ldapEntry['memberof'];
|
||||||
|
}
|
||||||
|
$this->connection->writeToCache($cacheKey, $groups);
|
||||||
|
//Avatar
|
||||||
|
$attrs = array('jpegphoto', 'thumbnailphoto');
|
||||||
|
foreach ($attrs as $attr) {
|
||||||
|
if(isset($ldapEntry[$attr])) {
|
||||||
|
$this->avatarImage = $ldapEntry[$attr];
|
||||||
|
$this->updateAvatar();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief returns the LDAP DN of the user
|
* @brief returns the LDAP DN of the user
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -154,6 +217,65 @@ class User {
|
||||||
return $this->uid;
|
return $this->uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the home directory of the user if specified by LDAP settings
|
||||||
|
* @param string $valueFromLDAP
|
||||||
|
* @return bool|string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function getHomePath($valueFromLDAP = null) {
|
||||||
|
$path = $valueFromLDAP;
|
||||||
|
|
||||||
|
if( is_null($path)
|
||||||
|
&& strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
|
||||||
|
&& $this->access->connection->homeFolderNamingRule !== 'attr:')
|
||||||
|
{
|
||||||
|
$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
|
||||||
|
$homedir = $this->access->readAttribute(
|
||||||
|
$this->access->username2dn($this->getUsername()), $attr);
|
||||||
|
if ($homedir && isset($homedir[0])) {
|
||||||
|
$path = $homedir[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($path)) {
|
||||||
|
//if attribute's value is an absolute path take this, otherwise append it to data dir
|
||||||
|
//check for / at the beginning or pattern c:\ resp. c:/
|
||||||
|
if( '/' !== $path[0]
|
||||||
|
&& !(3 < strlen($path) && ctype_alpha($path[0])
|
||||||
|
&& $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
|
||||||
|
) {
|
||||||
|
$path = $this->config->getSystemValue('datadirectory',
|
||||||
|
\OC::$SERVERROOT.'/data' ) . '/' . $path;
|
||||||
|
}
|
||||||
|
//we need it to store it in the DB as well in case a user gets
|
||||||
|
//deleted so we can clean up afterwards
|
||||||
|
$this->config->setUserValue(
|
||||||
|
$this->getUsername(), 'user_ldap', 'homePath', $path
|
||||||
|
);
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)) {
|
||||||
|
// a naming rule attribute is defined, but it doesn't exist for that LDAP user
|
||||||
|
throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
//false will apply default behaviour as defined and done by OC_User
|
||||||
|
$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMemberOfGroups() {
|
||||||
|
$cacheKey = 'getMemberOf'.$this->getUsername();
|
||||||
|
if($this->connection->isCached($cacheKey)) {
|
||||||
|
return $this->connection->getFromCache($cacheKey);
|
||||||
|
}
|
||||||
|
$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
|
||||||
|
$this->connection->writeToCache($cacheKey, $groupDNs);
|
||||||
|
return $groupDNs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief reads the image from LDAP that shall be used as Avatar
|
* @brief reads the image from LDAP that shall be used as Avatar
|
||||||
* @return string data (provided by LDAP) | false
|
* @return string data (provided by LDAP) | false
|
||||||
|
@ -189,7 +311,7 @@ class User {
|
||||||
* @brief marks the time when user features like email have been updated
|
* @brief marks the time when user features like email have been updated
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
private function markRefreshTime() {
|
public function markRefreshTime() {
|
||||||
$this->config->setUserValue(
|
$this->config->setUserValue(
|
||||||
$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
|
$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
|
||||||
}
|
}
|
||||||
|
@ -252,50 +374,54 @@ class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief fetches the email from LDAP and stores it as ownCloud user value
|
* fetches the email from LDAP and stores it as ownCloud user value
|
||||||
|
* @param string $valueFromLDAP if known, to save an LDAP read request
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function updateEmail() {
|
public function updateEmail($valueFromLDAP = null) {
|
||||||
if($this->wasRefreshed('email')) {
|
if($this->wasRefreshed('email')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$email = $valueFromLDAP;
|
||||||
$email = null;
|
if(is_null($valueFromLDAP)) {
|
||||||
$emailAttribute = $this->connection->ldapEmailAttribute;
|
$emailAttribute = $this->connection->ldapEmailAttribute;
|
||||||
if(!empty($emailAttribute)) {
|
if(!empty($emailAttribute)) {
|
||||||
$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
|
$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
|
||||||
if($aEmail && (count($aEmail) > 0)) {
|
if(is_array($aEmail) && (count($aEmail) > 0)) {
|
||||||
$email = $aEmail[0];
|
$email = $aEmail[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!is_null($email)) {
|
if(!is_null($email)) {
|
||||||
$this->config->setUserValue(
|
$this->config->setUserValue(
|
||||||
$this->uid, 'settings', 'email', $email);
|
$this->uid, 'settings', 'email', $email);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief fetches the quota from LDAP and stores it as ownCloud user value
|
* fetches the quota from LDAP and stores it as ownCloud user value
|
||||||
|
* @param string $valueFromLDAP the quota attribute's value can be passed,
|
||||||
|
* to save the readAttribute request
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function updateQuota() {
|
public function updateQuota($valueFromLDAP = null) {
|
||||||
if($this->wasRefreshed('quota')) {
|
if($this->wasRefreshed('quota')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//can be null
|
||||||
$quota = null;
|
|
||||||
$quotaDefault = $this->connection->ldapQuotaDefault;
|
$quotaDefault = $this->connection->ldapQuotaDefault;
|
||||||
|
$quota = !is_null($valueFromLDAP)
|
||||||
|
? $valueFromLDAP
|
||||||
|
: $quotaDefault !== '' ? $quotaDefault : null;
|
||||||
|
if(is_null($valueFromLDAP)) {
|
||||||
$quotaAttribute = $this->connection->ldapQuotaAttribute;
|
$quotaAttribute = $this->connection->ldapQuotaAttribute;
|
||||||
if(!empty($quotaDefault)) {
|
|
||||||
$quota = $quotaDefault;
|
|
||||||
}
|
|
||||||
if(!empty($quotaAttribute)) {
|
if(!empty($quotaAttribute)) {
|
||||||
$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
|
$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
|
||||||
|
|
||||||
if($aQuota && (count($aQuota) > 0)) {
|
if($aQuota && (count($aQuota) > 0)) {
|
||||||
$quota = $aQuota[0];
|
$quota = $aQuota[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(!is_null($quota)) {
|
if(!is_null($quota)) {
|
||||||
$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
|
$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ use \OCA\user_ldap\lib\Connection;
|
||||||
use \OCA\user_ldap\lib\ILDAPWrapper;
|
use \OCA\user_ldap\lib\ILDAPWrapper;
|
||||||
|
|
||||||
class Test_Access extends \Test\TestCase {
|
class Test_Access extends \Test\TestCase {
|
||||||
private function getConnecterAndLdapMock() {
|
private function getConnectorAndLdapMock() {
|
||||||
static $conMethods;
|
static $conMethods;
|
||||||
static $accMethods;
|
static $accMethods;
|
||||||
static $umMethods;
|
static $umMethods;
|
||||||
|
@ -56,7 +56,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEscapeFilterPartValidChars() {
|
public function testEscapeFilterPartValidChars() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$input = 'okay';
|
$input = 'okay';
|
||||||
|
@ -64,7 +64,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEscapeFilterPartEscapeWildcard() {
|
public function testEscapeFilterPartEscapeWildcard() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$input = '*';
|
$input = '*';
|
||||||
|
@ -73,7 +73,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEscapeFilterPartEscapeWildcard2() {
|
public function testEscapeFilterPartEscapeWildcard2() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$input = 'foo*bar';
|
$input = 'foo*bar';
|
||||||
|
@ -83,7 +83,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
|
|
||||||
/** @dataProvider convertSID2StrSuccessData */
|
/** @dataProvider convertSID2StrSuccessData */
|
||||||
public function testConvertSID2StrSuccess(array $sidArray, $sidExpected) {
|
public function testConvertSID2StrSuccess(array $sidArray, $sidExpected) {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$sidBinary = implode('', $sidArray);
|
$sidBinary = implode('', $sidArray);
|
||||||
|
@ -118,7 +118,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConvertSID2StrInputError() {
|
public function testConvertSID2StrInputError() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$sidIllegal = 'foobar';
|
$sidIllegal = 'foobar';
|
||||||
|
@ -128,7 +128,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetDomainDNFromDNSuccess() {
|
public function testGetDomainDNFromDNSuccess() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$inputDN = 'uid=zaphod,cn=foobar,dc=my,dc=server,dc=com';
|
$inputDN = 'uid=zaphod,cn=foobar,dc=my,dc=server,dc=com';
|
||||||
|
@ -143,7 +143,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetDomainDNFromDNError() {
|
public function testGetDomainDNFromDNError() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$inputDN = 'foobar';
|
$inputDN = 'foobar';
|
||||||
|
@ -178,7 +178,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testStringResemblesDN() {
|
public function testStringResemblesDN() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
$cases = $this->getResemblesDNInputData();
|
$cases = $this->getResemblesDNInputData();
|
||||||
|
@ -199,7 +199,7 @@ class Test_Access extends \Test\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testStringResemblesDNLDAPmod() {
|
public function testStringResemblesDNLDAPmod() {
|
||||||
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
$lw = new \OCA\user_ldap\lib\LDAP();
|
$lw = new \OCA\user_ldap\lib\LDAP();
|
||||||
$access = new Access($con, $lw, $um);
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
|
@ -213,4 +213,51 @@ class Test_Access extends \Test\TestCase {
|
||||||
$this->assertSame($case['expectedResult'], $access->stringResemblesDN($case['input']));
|
$this->assertSame($case['expectedResult'], $access->stringResemblesDN($case['input']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCacheUserHome() {
|
||||||
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
|
$access = new Access($con, $lw, $um);
|
||||||
|
|
||||||
|
$con->expects($this->once())
|
||||||
|
->method('writeToCache');
|
||||||
|
|
||||||
|
$access->cacheUserHome('foobar', '/foobars/path');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBatchApplyUserAttributes() {
|
||||||
|
list($lw, $con, $um) = $this->getConnectorAndLdapMock();
|
||||||
|
$access = new Access($con, $lw, $um);
|
||||||
|
$mapperMock = $this->getMockBuilder('\OCA\User_LDAP\Mapping\UserMapping')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$userMock = $this->getMockBuilder('\OCA\user_ldap\lib\user\User')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$access->setUserMapper($mapperMock);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
array(
|
||||||
|
'dn' => 'foobar',
|
||||||
|
$con->ldapUserDisplayName => 'barfoo'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'dn' => 'foo',
|
||||||
|
$con->ldapUserDisplayName => 'bar'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'dn' => 'raboof',
|
||||||
|
$con->ldapUserDisplayName => 'oofrab'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$userMock->expects($this->exactly(count($data)))
|
||||||
|
->method('processAttributes');
|
||||||
|
|
||||||
|
$um->expects($this->exactly(count($data)))
|
||||||
|
->method('get')
|
||||||
|
->will($this->returnValue($userMock));
|
||||||
|
|
||||||
|
$access->batchApplyUserAttributes($data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ class Test_Group_Ldap extends \Test\TestCase {
|
||||||
$accMethods,
|
$accMethods,
|
||||||
array($connector, $lw, $um));
|
array($connector, $lw, $um));
|
||||||
|
|
||||||
|
$access->expects($this->any())
|
||||||
|
->method('getConnection')
|
||||||
|
->will($this->returnValue($connector));
|
||||||
|
|
||||||
return $access;
|
return $access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +395,7 @@ class Test_Group_Ldap extends \Test\TestCase {
|
||||||
|
|
||||||
$access->connection->hasPrimaryGroups = false;
|
$access->connection->hasPrimaryGroups = false;
|
||||||
|
|
||||||
$access->expects($this->once())
|
$access->expects($this->any())
|
||||||
->method('username2dn')
|
->method('username2dn')
|
||||||
->will($this->returnValue($dn));
|
->will($this->returnValue($dn));
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,16 @@ class Test_User_Manager extends \Test\TestCase {
|
||||||
$image = $this->getMock('\OCP\Image');
|
$image = $this->getMock('\OCP\Image');
|
||||||
$dbc = $this->getMock('\OCP\IDBConnection');
|
$dbc = $this->getMock('\OCP\IDBConnection');
|
||||||
|
|
||||||
|
$connection = new \OCA\user_ldap\lib\Connection(
|
||||||
|
$lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'),
|
||||||
|
'',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$access->expects($this->any())
|
||||||
|
->method('getConnection')
|
||||||
|
->will($this->returnValue($connection));
|
||||||
|
|
||||||
return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc);
|
return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,4 +216,36 @@ class Test_User_Manager extends \Test\TestCase {
|
||||||
$this->assertNull($user);
|
$this->assertNull($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetAttributesAll() {
|
||||||
|
list($access, $config, $filesys, $image, $log, $avaMgr, $dbc) =
|
||||||
|
$this->getTestInstances();
|
||||||
|
|
||||||
|
$manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc);
|
||||||
|
$manager->setLdapAccess($access);
|
||||||
|
|
||||||
|
$connection = $access->getConnection();
|
||||||
|
$connection->setConfiguration(array('ldapEmailAttribute' => 'mail'));
|
||||||
|
|
||||||
|
$attributes = $manager->getAttributes();
|
||||||
|
|
||||||
|
$this->assertTrue(in_array('dn', $attributes));
|
||||||
|
$this->assertTrue(in_array($access->getConnection()->ldapEmailAttribute, $attributes));
|
||||||
|
$this->assertTrue(in_array('jpegphoto', $attributes));
|
||||||
|
$this->assertTrue(in_array('thumbnailphoto', $attributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAttributesMinimal() {
|
||||||
|
list($access, $config, $filesys, $image, $log, $avaMgr, $dbc) =
|
||||||
|
$this->getTestInstances();
|
||||||
|
|
||||||
|
$manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc);
|
||||||
|
$manager->setLdapAccess($access);
|
||||||
|
|
||||||
|
$attributes = $manager->getAttributes(true);
|
||||||
|
|
||||||
|
$this->assertTrue(in_array('dn', $attributes));
|
||||||
|
$this->assertTrue(!in_array('jpegphoto', $attributes));
|
||||||
|
$this->assertTrue(!in_array('thumbnailphoto', $attributes));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ class Test_User_User extends \Test\TestCase {
|
||||||
$connection->expects($this->at(0))
|
$connection->expects($this->at(0))
|
||||||
->method('__get')
|
->method('__get')
|
||||||
->with($this->equalTo('ldapQuotaDefault'))
|
->with($this->equalTo('ldapQuotaDefault'))
|
||||||
->will($this->returnValue('23 GB'));
|
->will($this->returnValue('25 GB'));
|
||||||
|
|
||||||
$connection->expects($this->at(1))
|
$connection->expects($this->at(1))
|
||||||
->method('__get')
|
->method('__get')
|
||||||
|
@ -242,7 +242,7 @@ class Test_User_User extends \Test\TestCase {
|
||||||
->with($this->equalTo('alice'),
|
->with($this->equalTo('alice'),
|
||||||
$this->equalTo('files'),
|
$this->equalTo('files'),
|
||||||
$this->equalTo('quota'),
|
$this->equalTo('quota'),
|
||||||
$this->equalTo('23 GB'))
|
$this->equalTo('25 GB'))
|
||||||
->will($this->returnValue(true));
|
->will($this->returnValue(true));
|
||||||
|
|
||||||
$uid = 'alice';
|
$uid = 'alice';
|
||||||
|
@ -278,14 +278,14 @@ class Test_User_User extends \Test\TestCase {
|
||||||
->method('readAttribute')
|
->method('readAttribute')
|
||||||
->with($this->equalTo('uid=alice,dc=foo,dc=bar'),
|
->with($this->equalTo('uid=alice,dc=foo,dc=bar'),
|
||||||
$this->equalTo('myquota'))
|
$this->equalTo('myquota'))
|
||||||
->will($this->returnValue(array('23 GB')));
|
->will($this->returnValue(array('27 GB')));
|
||||||
|
|
||||||
$config->expects($this->once())
|
$config->expects($this->once())
|
||||||
->method('setUserValue')
|
->method('setUserValue')
|
||||||
->with($this->equalTo('alice'),
|
->with($this->equalTo('alice'),
|
||||||
$this->equalTo('files'),
|
$this->equalTo('files'),
|
||||||
$this->equalTo('quota'),
|
$this->equalTo('quota'),
|
||||||
$this->equalTo('23 GB'))
|
$this->equalTo('27 GB'))
|
||||||
->will($this->returnValue(true));
|
->will($this->returnValue(true));
|
||||||
|
|
||||||
$uid = 'alice';
|
$uid = 'alice';
|
||||||
|
@ -679,4 +679,61 @@ class Test_User_User extends \Test\TestCase {
|
||||||
//photo is returned
|
//photo is returned
|
||||||
$photo = $user->getAvatarImage();
|
$photo = $user->getAvatarImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testProcessAttributes() {
|
||||||
|
list(, $config, $filesys, $image, $log, $avaMgr, $dbc) =
|
||||||
|
$this->getTestInstances();
|
||||||
|
|
||||||
|
list($access, $connection) =
|
||||||
|
$this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc);
|
||||||
|
|
||||||
|
$uid = 'alice';
|
||||||
|
$dn = 'uid=alice';
|
||||||
|
|
||||||
|
$requiredMethods = array(
|
||||||
|
'markRefreshTime',
|
||||||
|
'updateQuota',
|
||||||
|
'updateEmail',
|
||||||
|
'storeDisplayName',
|
||||||
|
'storeLDAPUserName',
|
||||||
|
'getHomePath',
|
||||||
|
'updateAvatar'
|
||||||
|
);
|
||||||
|
|
||||||
|
$userMock = $this->getMockBuilder('OCA\user_ldap\lib\user\User')
|
||||||
|
->setConstructorArgs(array($uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr))
|
||||||
|
->setMethods($requiredMethods)
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$connection->setConfiguration(array(
|
||||||
|
'homeFolderNamingRule' => 'homeDirectory'
|
||||||
|
));
|
||||||
|
|
||||||
|
$connection->expects($this->any())
|
||||||
|
->method('__get')
|
||||||
|
//->will($this->returnArgument(0));
|
||||||
|
->will($this->returnCallback(function($name) {
|
||||||
|
if($name === 'homeFolderNamingRule') {
|
||||||
|
return 'attr:homeDirectory';
|
||||||
|
}
|
||||||
|
return $name;
|
||||||
|
}));
|
||||||
|
|
||||||
|
$record = array(
|
||||||
|
strtolower($connection->ldapQuotaAttribute) => array('4096'),
|
||||||
|
strtolower($connection->ldapEmailAttribute) => array('alice@wonderland.org'),
|
||||||
|
strtolower($connection->ldapUserDisplayName) => array('Aaaaalice'),
|
||||||
|
'uid' => array($uid),
|
||||||
|
'homedirectory' => array('Alice\'s Folder'),
|
||||||
|
'memberof' => array('cn=groupOne', 'cn=groupTwo'),
|
||||||
|
'jpegphoto' => array('here be an image')
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach($requiredMethods as $method) {
|
||||||
|
$userMock->expects($this->once())
|
||||||
|
->method($method);
|
||||||
|
}
|
||||||
|
|
||||||
|
$userMock->processAttributes($record);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ use \OCA\user_ldap\lib\ILDAPWrapper;
|
||||||
class Test_User_Ldap_Direct extends \Test\TestCase {
|
class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
protected $backend;
|
protected $backend;
|
||||||
protected $access;
|
protected $access;
|
||||||
|
protected $configMock;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -61,8 +62,9 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
$conMethods,
|
$conMethods,
|
||||||
array($lw, null, null));
|
array($lw, null, null));
|
||||||
|
|
||||||
|
$this->configMock = $this->getMock('\OCP\IConfig');
|
||||||
$um = new \OCA\user_ldap\lib\user\Manager(
|
$um = new \OCA\user_ldap\lib\user\Manager(
|
||||||
$this->getMock('\OCP\IConfig'),
|
$this->configMock,
|
||||||
$this->getMock('\OCA\user_ldap\lib\FilesystemHelper'),
|
$this->getMock('\OCA\user_ldap\lib\FilesystemHelper'),
|
||||||
$this->getMock('\OCA\user_ldap\lib\LogWrapper'),
|
$this->getMock('\OCA\user_ldap\lib\LogWrapper'),
|
||||||
$this->getMock('\OCP\IAvatarManager'),
|
$this->getMock('\OCP\IAvatarManager'),
|
||||||
|
@ -586,6 +588,13 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
$backend = new UserLDAP($access, $config);
|
$backend = new UserLDAP($access, $config);
|
||||||
$this->prepareMockForUserExists($access);
|
$this->prepareMockForUserExists($access);
|
||||||
|
|
||||||
|
$dataDir = \OC::$server->getConfig()->getSystemValue(
|
||||||
|
'datadirectory', \OC::$SERVERROOT.'/data');
|
||||||
|
|
||||||
|
$this->configMock->expects($this->once())
|
||||||
|
->method('getSystemValue')
|
||||||
|
->will($this->returnValue($dataDir));
|
||||||
|
|
||||||
$access->connection->expects($this->any())
|
$access->connection->expects($this->any())
|
||||||
->method('__get')
|
->method('__get')
|
||||||
->will($this->returnCallback(function($name) {
|
->will($this->returnCallback(function($name) {
|
||||||
|
@ -609,14 +618,9 @@ class Test_User_Ldap_Direct extends \Test\TestCase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
//datadir-relativ path
|
|
||||||
$datadir = '/my/data/dir';
|
|
||||||
$config->expects($this->once())
|
|
||||||
->method('getSystemValue')
|
|
||||||
->will($this->returnValue($datadir));
|
|
||||||
|
|
||||||
$result = $backend->getHome('ladyofshadows');
|
$result = $backend->getHome('ladyofshadows');
|
||||||
$this->assertEquals($datadir.'/susannah/', $result);
|
$this->assertEquals($dataDir.'/susannah/', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,9 +98,8 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
|
||||||
*/
|
*/
|
||||||
public function getLDAPUserByLoginName($loginName) {
|
public function getLDAPUserByLoginName($loginName) {
|
||||||
//find out dn of the user name
|
//find out dn of the user name
|
||||||
$attrs = array($this->access->connection->ldapUserDisplayName, 'dn',
|
$attrs = $this->access->userManager->getAttributes();
|
||||||
'uid', 'samaccountname');
|
$users = $this->access->fetchUsersByLoginName($loginName, $attrs, 1);
|
||||||
$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
|
|
||||||
if(count($users) < 1) {
|
if(count($users) < 1) {
|
||||||
throw new \Exception('No user available for the given login name.');
|
throw new \Exception('No user available for the given login name.');
|
||||||
}
|
}
|
||||||
|
@ -137,16 +136,9 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->access->cacheUserExists($user->getUsername());
|
||||||
|
$user->processAttributes($ldapRecord);
|
||||||
$user->markLogin();
|
$user->markLogin();
|
||||||
if(isset($ldapRecord[$this->access->connection->ldapUserDisplayName])) {
|
|
||||||
$dpn = $ldapRecord[$this->access->connection->ldapUserDisplayName];
|
|
||||||
$user->storeDisplayName($dpn);
|
|
||||||
}
|
|
||||||
if(isset($ldapRecord['uid'])) {
|
|
||||||
$user->storeLDAPUserName($ldapRecord['uid']);
|
|
||||||
} else if(isset($ldapRecord['samaccountname'])) {
|
|
||||||
$user->storeLDAPUserName($ldapRecord['samaccountname']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user->getUsername();
|
return $user->getUsername();
|
||||||
}
|
}
|
||||||
|
@ -188,7 +180,7 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
|
||||||
//do the search and translate results to owncloud names
|
//do the search and translate results to owncloud names
|
||||||
$ldap_users = $this->access->fetchListOfUsers(
|
$ldap_users = $this->access->fetchListOfUsers(
|
||||||
$filter,
|
$filter,
|
||||||
array($this->access->connection->ldapUserDisplayName, 'dn'),
|
$this->access->userManager->getAttributes(true),
|
||||||
$limit, $offset);
|
$limit, $offset);
|
||||||
$ldap_users = $this->access->ownCloudUserNames($ldap_users);
|
$ldap_users = $this->access->ownCloudUserNames($ldap_users);
|
||||||
\OCP\Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', \OCP\Util::DEBUG);
|
\OCP\Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', \OCP\Util::DEBUG);
|
||||||
|
@ -302,44 +294,12 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
|
||||||
if($this->access->connection->isCached($cacheKey)) {
|
if($this->access->connection->isCached($cacheKey)) {
|
||||||
return $this->access->connection->getFromCache($cacheKey);
|
return $this->access->connection->getFromCache($cacheKey);
|
||||||
}
|
}
|
||||||
if(strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0 &&
|
|
||||||
$this->access->connection->homeFolderNamingRule !== 'attr:') {
|
|
||||||
$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
|
|
||||||
$homedir = $this->access->readAttribute(
|
|
||||||
$this->access->username2dn($uid), $attr);
|
|
||||||
if($homedir && isset($homedir[0])) {
|
|
||||||
$path = $homedir[0];
|
|
||||||
//if attribute's value is an absolute path take this, otherwise append it to data dir
|
|
||||||
//check for / at the beginning or pattern c:\ resp. c:/
|
|
||||||
if(
|
|
||||||
'/' === $path[0]
|
|
||||||
|| (3 < strlen($path) && ctype_alpha($path[0])
|
|
||||||
&& $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
|
|
||||||
) {
|
|
||||||
$homedir = $path;
|
|
||||||
} else {
|
|
||||||
$homedir = $this->ocConfig->getSystemValue('datadirectory',
|
|
||||||
\OC::$SERVERROOT.'/data' ) . '/' . $homedir[0];
|
|
||||||
}
|
|
||||||
$this->access->connection->writeToCache($cacheKey, $homedir);
|
|
||||||
//we need it to store it in the DB as well in case a user gets
|
|
||||||
//deleted so we can clean up afterwards
|
|
||||||
$this->ocConfig->setUserValue(
|
|
||||||
$uid, 'user_ldap', 'homePath', $homedir
|
|
||||||
);
|
|
||||||
//TODO: if home directory changes, the old one needs to be removed.
|
|
||||||
return $homedir;
|
|
||||||
}
|
|
||||||
if($this->ocConfig->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)) {
|
|
||||||
// a naming rule attribute is defined, but it doesn't exist for that LDAP user
|
|
||||||
throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//false will apply default behaviour as defined and done by OC_User
|
$user = $this->access->userManager->get($uid);
|
||||||
$this->access->connection->writeToCache($cacheKey, false);
|
$path = $user->getHomePath();
|
||||||
$this->ocConfig->setUserValue($uid, 'user_ldap', 'homePath', '');
|
$this->access->cacheUserHome($uid, $path);
|
||||||
return false;
|
|
||||||
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue