Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[full-ci] [tests-only] Test expose group displayname #749

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions appinfo/Migrations/Version20220725070804.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
namespace OCA\User_LDAP\Migrations;

use OCP\Migration\ISimpleMigration;
use OCP\Migration\IOutput;
use OCP\IConfig;
use OCA\User_LDAP\Helper;

class Version20220725070804 implements ISimpleMigration {
/** @var IConfig */
private $config;
/** @var $helper */
private $helper;

/**
* @param IConfig $config
*/
public function __construct(IConfig $config, Helper $helper) {
$this->config = $config;
$this->helper = $helper;
}
/**
* @param IOutput $out
*/
public function run(IOutput $out) {
$prefixes = $this->helper->getServerConfigurationPrefixes();
foreach ($prefixes as $prefix) {
$groupnameValue = $this->config->getAppValue('user_ldap', "{$prefix}ldap_expert_groupname_attr", null);
if ($groupnameValue === null) {
$groupDisplaynameValue = $this->config->getAppValue('user_ldap', "{$prefix}ldap_group_display_name", null);
if ($groupDisplaynameValue !== null) {
$this->config->setAppValue('user_ldap', "{$prefix}ldap_expert_groupname_attr", $groupDisplaynameValue);
}
}
}
}
}
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ More information is available in the [LDAP User and Group Backend documentation]
</description>
<licence>AGPL</licence>
<author>Jörn Friedrich Dreyer, Tom Needham, Juan Pablo Villafañez Ramos, Dominik Schmidt and Arthur Schiwon</author>
<version>0.16.0</version>
<version>0.17.0</version>
<types>
<authentication/>
</types>
Expand Down
13 changes: 13 additions & 0 deletions js/wizard/wizardTabExpert.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ OCA = OCA || {};
$element: $('#ldap_expert_username_attr'),
setMethod: 'setUsernameAttribute'
},
ldap_expert_groupname_attr: {
$element: $('#ldap_expert_groupname_attr'),
setMethod: 'setGroupnameAttribute'
},
ldap_expert_uuid_user_attr: {
$element: $('#ldap_expert_uuid_user_attr'),
setMethod: 'setUserUUIDAttribute'
Expand Down Expand Up @@ -73,6 +77,15 @@ OCA = OCA || {};
this.setElementValue(this.managedItems.ldap_expert_username_attr.$element, attribute);
},

/**
* sets the attribute to be used to create an ownCloud ID (groupname)
*
* @param {string} attribute
*/
setGroupnameAttribute: function(attribute) {
this.setElementValue(this.managedItems.ldap_expert_groupname_attr.$element, attribute);
},

/**
* sets the attribute that provides an unique identifier per LDAP user
* entry
Expand Down
58 changes: 13 additions & 45 deletions lib/Access.php
Original file line number Diff line number Diff line change
Expand Up @@ -472,19 +472,18 @@ public function username2dn($name) {
* returns the internal ownCloud name for the given LDAP DN of the group, false on DN outside of search DN or failure
*
* @param string $fdn the dn of the group object
* @param string $ldapName optional, the display name of the object
* @return string|false with the name to use in ownCloud, false on DN outside of search DN
* @throws \OC\ServerNotAvailableException
*/
public function dn2groupname($fdn, $ldapName = null) {
public function dn2groupname($fdn) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
if (!$this->isDNPartOfBase($fdn, $this->connection->ldapBaseGroups)) {
return false;
}

return $this->dn2ocname($fdn, $ldapName, false);
return $this->dn2ocname($fdn, false);
}

/**
Expand Down Expand Up @@ -530,38 +529,36 @@ public function groupsMatchFilter($groupDNs) {
* returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN or failure
*
* @param string $fdn the dn of the user object
* @param string $ldapName optional, the display name of the object
* @return string|false with with the name to use in ownCloud
* @throws \OC\ServerNotAvailableException
*/
public function dn2username($fdn, $ldapName = null) {
public function dn2username($fdn) {
//To avoid bypassing the base DN settings under certain circumstances
//with the group support, check whether the provided DN matches one of
//the given Bases
if (!$this->isDNPartOfBase($fdn, $this->connection->ldapBaseUsers)) {
return false;
}

return $this->dn2ocname($fdn, $ldapName, true);
return $this->dn2ocname($fdn, true);
}

/**
* returns an internal ownCloud name for the given LDAP DN, false on DN outside of search DN
*
* @param string $fdn the dn of the user object
* @param string $ldapDisplayName optional, the display name of the object
* @param bool $isUser optional, whether it is a user object (otherwise group assumed)
* @return string|false with with the name to use in ownCloud
* @throws \BadMethodCallException
* @throws \OC\ServerNotAvailableException
*/
public function dn2ocname($fdn, $ldapDisplayName = null, $isUser = true) {
public function dn2ocname($fdn, $isUser = true) {
if ($isUser) {
$mapper = $this->getUserMapper();
$displayNameAttribute = $this->connection->ldapUserDisplayName;
$nameAttribute = (string)$this->connection->ldapExpertUsernameAttr;
} else {
$mapper = $this->getGroupMapper();
$displayNameAttribute = $this->connection->ldapGroupDisplayName;
$nameAttribute = (string)$this->connection->ldapExpertGroupnameAttr;
}

//let's try to retrieve the ownCloud name from the mappings table
Expand All @@ -587,30 +584,13 @@ public function dn2ocname($fdn, $ldapDisplayName = null, $isUser = true) {
return false;
}

if ($ldapDisplayName === null) {
$ldapDisplayName = $this->readAttribute($fdn, $displayNameAttribute);
if (!isset($ldapDisplayName[0]) && empty($ldapDisplayName[0])) {
\OC::$server->getLogger()->error(
"No or empty name for $fdn.",
['app' => 'user_ldap']
);
return false;
}
$ldapDisplayName = $ldapDisplayName[0];
}

if ($isUser) {
$usernameAttribute = (string)$this->connection->ldapExpertUsernameAttr;
if ($usernameAttribute !== '') {
$username = $this->readAttribute($fdn, $usernameAttribute);
$username = $username[0];
} else {
$username = $uuid;
}
$intName = $this->sanitizeUsername($username);
if ($nameAttribute !== '') {
$name = $this->readAttribute($fdn, $nameAttribute);
$name = $name[0];
} else {
$intName = $ldapDisplayName;
$name = $uuid;
}
$intName = $this->sanitizeUsername($name);

//a new user/group! Add it only if it doesn't conflict with other backend's users or existing groups
//disabling Cache is required to avoid that the new user is cached as not-existing in fooExists check
Expand Down Expand Up @@ -708,22 +688,10 @@ public function ownCloudGroupNames($ldapGroups) {
* @throws \OC\ServerNotAvailableException
*/
private function ldap2ownCloudNames($ldapObjects, $isUsers) {
if ($isUsers) {
$nameAttribute = $this->connection->ldapUserDisplayName;
$sndAttribute = $this->connection->ldapUserDisplayName2;
} else {
$nameAttribute = $this->connection->ldapGroupDisplayName;
}
$ownCloudNames = [];

foreach ($ldapObjects as $ldapObject) {
$nameByLDAP = null;
if (isset($ldapObject[$nameAttribute][0])) {
// might be set, but not necessarily. if so, we use it.
$nameByLDAP = $ldapObject[$nameAttribute][0];
}

$ocName = $this->dn2ocname($ldapObject['dn'][0], $nameByLDAP, $isUsers);
$ocName = $this->dn2ocname($ldapObject['dn'][0], $isUsers);
if ($ocName) {
$ownCloudNames[$ldapObject['dn'][0]] = $ocName;
}
Expand Down
4 changes: 4 additions & 0 deletions lib/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
* @property string $hasMemberOfFilterSupport,
* @property string $useMemberOfToDetectMembership,
* @property string $ldapExpertUsernameAttr,
* @property string $ldapExpertGroupnameAttr,
* @property string $ldapExpertUUIDUserAttr,
* @property string $ldapExpertUUIDGroupAttr,
* @property string $lastJpegPhotoLookup,
Expand Down Expand Up @@ -148,6 +149,7 @@ class Configuration {
'hasMemberOfFilterSupport' => false,
'useMemberOfToDetectMembership' => true,
'ldapExpertUsernameAttr' => null,
'ldapExpertGroupnameAttr' => null,
'ldapExpertUUIDUserAttr' => null,
'ldapExpertUUIDGroupAttr' => null,
'lastJpegPhotoLookup' => null,
Expand Down Expand Up @@ -546,6 +548,7 @@ public function getDefaults() {
'ldap_attributes_for_user_search' => '',
'ldap_attributes_for_group_search' => '',
'ldap_expert_username_attr' => '',
'ldap_expert_groupname_attr' => '',
'ldap_expert_uuid_user_attr' => '',
'ldap_expert_uuid_group_attr' => '',
'has_memberof_filter_support' => 0,
Expand Down Expand Up @@ -605,6 +608,7 @@ public function getConfigTranslationArray() {
'ldap_attributes_for_user_search' => 'ldapAttributesForUserSearch',
'ldap_attributes_for_group_search' => 'ldapAttributesForGroupSearch',
'ldap_expert_username_attr' => 'ldapExpertUsernameAttr',
'ldap_expert_groupname_attr' => 'ldapExpertGroupnameAttr',
'ldap_expert_uuid_user_attr' => 'ldapExpertUUIDUserAttr',
'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
Expand Down
1 change: 1 addition & 0 deletions lib/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
* @property string $ldapQuotaAttribute
* @property string $ldapEmailAttribute
* @property string $ldapExpertUsernameAttr
* @property string $ldapExpertGroupnameAttr
* @property string $homeFolderNamingRule
* @property array $ldapAttributesForUserSearch
* @property string $ldapUuidUserAttribute
Expand Down
37 changes: 36 additions & 1 deletion lib/Group_LDAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,41 @@ public function groupExists($gid) {
return true;
}

public function getGroupDetails($gid) {
$cacheKey = "groupDetails-$gid";
$details = $this->access->getConnection()->getFromCache($cacheKey);
if ($details !== null) {
return $details;
}

$dn = $this->access->groupname2dn($gid);
if ($dn === false) {
// FIXME: It seems local groups also end up going through here...
// Because OC\Group]Manager\getGroupObject loops through all backends
// and when the backend implementsActions(\OC\Group\Backend::GROUP_DETAILS)
// it calls getGroupDetails without checking if the group even exists in
// that backend.
return null;
}

$attr = $this->access->getConnection()->ldapGroupDisplayName;
$displayname = $this->access->readAttribute($dn, $attr);
if (\is_array($displayname)) {
$groupDisplayName = $displayname[0];
} else {
// The attribute was not found, maybe because the group does not even exist
// Default to the group id
$groupDisplayName = $gid;
}

$details = [
'gid' => $gid,
'displayName' => $groupDisplayName,
];
$this->access->getConnection()->writeToCache($cacheKey, $details);
return $details;
}

/**
* Check if backend implements actions
* @param int $actions bitwise-or'ed actions
Expand All @@ -1010,7 +1045,7 @@ public function groupExists($gid) {
* compared with OC_USER_BACKEND_CREATE_USER etc.
*/
public function implementsActions($actions) {
return (bool)(\OC\Group\Backend::COUNT_USERS & $actions);
return (bool)((\OC\Group\Backend::COUNT_USERS | \OC\Group\Backend::GROUP_DETAILS) & $actions);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/Group_Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ public function groupExists($gid) {
return $this->handleRequest($gid, 'groupExists', [$gid]);
}

public function getGroupDetails($gid) {
return $this->handleRequest($gid, 'getGroupDetails', [$gid]);
}
/**
* Check if backend implements actions
* @param int $actions bitwise-or'ed actions
Expand Down
2 changes: 1 addition & 1 deletion lib/User/IUserTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function getConnection();

public function readAttribute($dn, $attr, $filter = 'objectClass=*');

public function dn2username($dn, $ldapname = null);
public function dn2username($dn);

/**
* returns the LDAP DN for the given internal ownCloud name of the user
Expand Down
8 changes: 8 additions & 0 deletions templates/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,14 @@
<input type="text" id="ldap_expert_username_attr" name="ldap_expert_username_attr" data-default="<?php p($_['ldap_expert_username_attr_default']); ?>" />
</div>
</section>
<section>
<h3><?php p($l->t('Internal Groupname')); ?></h3>
<p><?php p($l->t('The internal groupname is used to uniquely identify the group. It has the same restrictions as the internal username, in particular, the group name must be immutable and unique. By default, the UUID will be used. This internal groupname won\'t likely by visible because a displayname attribute is intended to be used to show the group.')); ?></p>
<div class="tablerow">
<label for="ldap_expert_groupname_attr"><?php p($l->t('Internal Groupname Attribute:')); ?></label>
<input type="text" id="ldap_expert_groupname_attr" name="ldap_expert_groupname_attr" data-default="<?php p($_['ldap_expert_groupname_attr_default']); ?>" />
</div>
</section>
<section>
<h3><?php p($l->t('Override UUID detection')); ?></h3>
<p><?php p($l->t('By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups.')); ?></p>
Expand Down
1 change: 1 addition & 0 deletions tests/acceptance/setConfig.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ configID="LDAPTestId"
./occ ldap:set-config "$configID" ldapBaseGroups "dc=owncloud,dc=com"
./occ ldap:set-config "$configID" ldapBaseUsers "dc=owncloud,dc=com"
./occ ldap:set-config "$configID" ldapEmailAttribute "mail"
./occ ldap:set-config "$configID" ldapExpertGroupnameAttr "cn"
./occ ldap:set-config "$configID" ldapExpertUUIDUserAttr "uid"
./occ ldap:set-config "$configID" ldapGroupDisplayName "cn"
./occ ldap:set-config "$configID" ldapGroupFilter "(&(|(objectclass=posixGroup)))"
Expand Down