allow admin to disable fetching of avatars as well as a specific attribute

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
Arthur Schiwon 2018-07-04 00:10:43 +02:00
parent 86d9528bc9
commit 343036e55c
No known key found for this signature in database
GPG Key ID: 7424F1874854DF23
7 changed files with 126 additions and 33 deletions

View File

@ -35,8 +35,13 @@ namespace OCA\User_LDAP;
/** /**
* @property int ldapPagingSize holds an integer * @property int ldapPagingSize holds an integer
* @property string ldapUserAvatarRule
*/ */
class Configuration { class Configuration {
const AVATAR_PREFIX_DEFAULT = 'default';
const AVATAR_PREFIX_NONE = 'none';
const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
protected $configPrefix = null; protected $configPrefix = null;
protected $configRead = false; protected $configRead = false;
/** /**
@ -61,6 +66,7 @@ class Configuration {
'ldapIgnoreNamingRules' => null, 'ldapIgnoreNamingRules' => null,
'ldapUserDisplayName' => null, 'ldapUserDisplayName' => null,
'ldapUserDisplayName2' => null, 'ldapUserDisplayName2' => null,
'ldapUserAvatarRule' => null,
'ldapGidNumber' => null, 'ldapGidNumber' => null,
'ldapUserFilterObjectclass' => null, 'ldapUserFilterObjectclass' => null,
'ldapUserFilterGroups' => null, 'ldapUserFilterGroups' => null,
@ -472,6 +478,7 @@ class Configuration {
'ldap_experienced_admin' => 0, 'ldap_experienced_admin' => 0,
'ldap_dynamic_group_member_url' => '', 'ldap_dynamic_group_member_url' => '',
'ldap_default_ppolicy_dn' => '', 'ldap_default_ppolicy_dn' => '',
'ldap_user_avatar_rule' => 'default',
); );
} }
@ -495,6 +502,7 @@ class Configuration {
'ldap_userfilter_groups' => 'ldapUserFilterGroups', 'ldap_userfilter_groups' => 'ldapUserFilterGroups',
'ldap_userlist_filter' => 'ldapUserFilter', 'ldap_userlist_filter' => 'ldapUserFilter',
'ldap_user_filter_mode' => 'ldapUserFilterMode', 'ldap_user_filter_mode' => 'ldapUserFilterMode',
'ldap_user_avatar_rule' => 'ldapUserAvatarRule',
'ldap_login_filter' => 'ldapLoginFilter', 'ldap_login_filter' => 'ldapLoginFilter',
'ldap_login_filter_mode' => 'ldapLoginFilterMode', 'ldap_login_filter_mode' => 'ldapLoginFilterMode',
'ldap_loginfilter_email' => 'ldapLoginFilterEmail', 'ldap_loginfilter_email' => 'ldapLoginFilterEmail',
@ -536,4 +544,36 @@ class Configuration {
return $array; return $array;
} }
/**
* @param string $rule
* @return array
* @throws \RuntimeException
*/
public function resolveRule($rule) {
if($rule === 'avatar') {
return $this->getAvatarAttributes();
}
throw new \RuntimeException('Invalid rule');
}
public function getAvatarAttributes() {
$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
if($value === self::AVATAR_PREFIX_NONE) {
return [];
}
if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
if($attribute === '') {
return $defaultAttributes;
}
return [$attribute];
}
if($value !== self::AVATAR_PREFIX_DEFAULT) {
\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
}
return $defaultAttributes;
}
} }

View File

@ -48,6 +48,7 @@ use OCP\ILogger;
* @property string ldapUserFilter * @property string ldapUserFilter
* @property string ldapUserDisplayName * @property string ldapUserDisplayName
* @property string ldapUserDisplayName2 * @property string ldapUserDisplayName2
* @property string ldapUserAvatarRule
* @property boolean turnOnPasswordChange * @property boolean turnOnPasswordChange
* @property boolean hasPagedResultSupport * @property boolean hasPagedResultSupport
* @property string[] ldapBaseUsers * @property string[] ldapBaseUsers
@ -169,6 +170,15 @@ class Connection extends LDAPUtility {
} }
} }
/**
* @param string $rule
* @return array
* @throws \RuntimeException
*/
public function resolveRule($rule) {
return $this->configuration->resolveRule($rule);
}
/** /**
* sets whether the result of the configuration validation shall * sets whether the result of the configuration validation shall
* be ignored when establishing the connection. Used by the Wizard * be ignored when establishing the connection. Used by the Wizard

View File

@ -163,6 +163,7 @@ class Manager {
/** /**
* returns a list of attributes that will be processed further, e.g. quota, * returns a list of attributes that will be processed further, e.g. quota,
* email, displayname, or others. * email, displayname, or others.
*
* @param bool $minimal - optional, set to true to skip attributes with big * @param bool $minimal - optional, set to true to skip attributes with big
* payload * payload
* @return string[] * @return string[]
@ -190,10 +191,10 @@ class Manager {
if(!$minimal) { if(!$minimal) {
// attributes that are not really important but may come with big // attributes that are not really important but may come with big
// payload. // payload.
$attributes = array_merge($attributes, array( $attributes = array_merge(
'jpegphoto', $attributes,
'thumbnailphoto' $this->access->getConnection()->resolveRule('avatar')
)); );
} }
return $attributes; return $attributes;

View File

@ -245,10 +245,12 @@ class User {
$this->connection->writeToCache($cacheKey, $groups); $this->connection->writeToCache($cacheKey, $groups);
//Avatar //Avatar
$attrs = array('jpegphoto', 'thumbnailphoto'); /** @var Connection $connection */
foreach ($attrs as $attr) { $connection = $this->access->getConnection();
if(isset($ldapEntry[$attr])) { $attributes = $connection->resolveRule('avatar');
$this->avatarImage = $ldapEntry[$attr][0]; foreach ($attributes as $attribute) {
if(isset($ldapEntry[$attribute])) {
$this->avatarImage = $ldapEntry[$attribute][0];
// the call to the method that saves the avatar in the file // the call to the method that saves the avatar in the file
// system must be postponed after the login. It is to ensure // system must be postponed after the login. It is to ensure
// external mounts are mounted properly (e.g. with login // external mounts are mounted properly (e.g. with login
@ -348,7 +350,9 @@ class User {
} }
$this->avatarImage = false; $this->avatarImage = false;
$attributes = array('jpegPhoto', 'thumbnailPhoto'); /** @var Connection $connection */
$connection = $this->access->getConnection();
$attributes = $connection->resolveRule('avatar');
foreach($attributes as $attribute) { foreach($attributes as $attribute) {
$result = $this->access->readAttribute($this->dn, $attribute); $result = $this->access->readAttribute($this->dn, $attribute);
if($result !== false && is_array($result) && isset($result[0])) { if($result !== false && is_array($result) && isset($result[0])) {
@ -575,7 +579,7 @@ class User {
*/ */
private function setOwnCloudAvatar() { private function setOwnCloudAvatar() {
if(!$this->image->valid()) { if(!$this->image->valid()) {
$this->log->log('jpegPhoto data invalid for '.$this->dn, ILogger::ERROR); $this->log->log('avatar image data from LDAP invalid for '.$this->dn, ILogger::ERROR);
return false; return false;
} }
//make sure it is a square and not bigger than 128x128 //make sure it is a square and not bigger than 128x128

View File

@ -103,6 +103,10 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
return $this->userPluginManager->canChangeAvatar($uid); return $this->userPluginManager->canChangeAvatar($uid);
} }
if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
return true;
}
$user = $this->access->userManager->get($uid); $user = $this->access->userManager->get($uid);
if(!$user instanceof User) { if(!$user instanceof User) {
return false; return false;
@ -550,7 +554,7 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
return (bool)((Backend::CHECK_PASSWORD return (bool)((Backend::CHECK_PASSWORD
| Backend::GET_HOME | Backend::GET_HOME
| Backend::GET_DISPLAYNAME | Backend::GET_DISPLAYNAME
| Backend::PROVIDE_AVATAR | (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
| Backend::COUNT_USERS | Backend::COUNT_USERS
| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0) | (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
| $this->userPluginManager->getImplementedActions()) | $this->userPluginManager->getImplementedActions())

View File

@ -23,7 +23,16 @@
namespace OCA\User_LDAP\Tests; namespace OCA\User_LDAP\Tests;
use OCA\User_LDAP\Configuration;
class ConfigurationTest extends \Test\TestCase { class ConfigurationTest extends \Test\TestCase {
/** @var Configuration */
protected $configuration;
public function setUp() {
parent::setUp();
$this->configuration = new Configuration('t01', false);
}
public function configurationDataProvider() { public function configurationDataProvider() {
$inputWithDN = array( $inputWithDN = array(
@ -84,6 +93,10 @@ class ConfigurationTest extends \Test\TestCase {
// default behaviour, one case is enough, special needs must be tested // default behaviour, one case is enough, special needs must be tested
// individually // individually
'set string value' => array('ldapHost', $inputString, $expectedString), 'set string value' => array('ldapHost', $inputString, $expectedString),
'set avatar rule, default' => ['ldapUserAvatarRule', 'default', 'default'],
'set avatar rule, none' => ['ldapUserAvatarRule', 'none', 'none'],
'set avatar rule, data attribute' => ['ldapUserAvatarRule', 'data:jpegPhoto', 'data:jpegPhoto'],
); );
} }
@ -91,10 +104,35 @@ class ConfigurationTest extends \Test\TestCase {
* @dataProvider configurationDataProvider * @dataProvider configurationDataProvider
*/ */
public function testSetValue($key, $input, $expected) { public function testSetValue($key, $input, $expected) {
$configuration = new \OCA\User_LDAP\Configuration('t01', false); $this->configuration->setConfiguration([$key => $input]);
$this->assertSame($this->configuration->$key, $expected);
}
$configuration->setConfiguration([$key => $input]); public function avatarRuleValueProvider() {
$this->assertSame($configuration->$key, $expected); return [
['none', []],
['data:selfie', ['selfie']],
['data:', ['jpegphoto', 'thumbnailphoto']],
['default', ['jpegphoto', 'thumbnailphoto']],
['invalid#', ['jpegphoto', 'thumbnailphoto']],
];
}
/**
* @dataProvider avatarRuleValueProvider
*/
public function testGetAvatarAttributes($setting, $expected) {
$this->configuration->setConfiguration(['ldapUserAvatarRule' => $setting]);
$this->assertSame($expected, $this->configuration->getAvatarAttributes());
}
/**
* @dataProvider avatarRuleValueProvider
*/
public function testResolveRule($setting, $expected) {
$this->configuration->setConfiguration(['ldapUserAvatarRule' => $setting]);
// so far the only thing that can get resolved :)
$this->assertSame($expected, $this->configuration->resolveRule('avatar'));
} }
} }

View File

@ -238,7 +238,17 @@ class ManagerTest extends \Test\TestCase {
$this->assertNull($user); $this->assertNull($user);
} }
public function testGetAttributesAll() { public function attributeRequestProvider() {
return [
[ false ],
[ true ],
];
}
/**
* @dataProvider attributeRequestProvider
*/
public function testGetAttributes($minimal) {
list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
$this->getTestInstances(); $this->getTestInstances();
@ -246,28 +256,14 @@ class ManagerTest extends \Test\TestCase {
$manager->setLdapAccess($access); $manager->setLdapAccess($access);
$connection = $access->getConnection(); $connection = $access->getConnection();
$connection->setConfiguration(array('ldapEmailAttribute' => 'mail')); $connection->setConfiguration(['ldapEmailAttribute' => 'mail', 'ldapUserAvatarRule' => 'default']);
$attributes = $manager->getAttributes(); $attributes = $manager->getAttributes($minimal);
$this->assertTrue(in_array('dn', $attributes)); $this->assertTrue(in_array('dn', $attributes));
$this->assertTrue(in_array($access->getConnection()->ldapEmailAttribute, $attributes)); $this->assertTrue(in_array($access->getConnection()->ldapEmailAttribute, $attributes));
$this->assertTrue(in_array('jpegphoto', $attributes)); $this->assertSame(!$minimal, in_array('jpegphoto', $attributes));
$this->assertTrue(in_array('thumbnailphoto', $attributes)); $this->assertSame(!$minimal, in_array('thumbnailphoto', $attributes));
}
public function testGetAttributesMinimal() {
list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
$this->getTestInstances();
$manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
$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));
} }
} }