I want to have multiple LDAP attributes in my user’s display name so that whenever a user is being searched, it shows up the entire name such as: Title FirstName LastName → Developer John Doe
In my case I have to use 4 additional LDAP attributes namely, Rank, Unit, Designation and PersonalNumber. I tried searching for solutions for it but can’t find one, maybe I need to modify some code which I require help in… Any assistance is greately appreciated.
I am using LDAP user and group backend application as addon.
Hi there.
I guess you have checked the Settings under Advanced / Directory Settings and found the two attribute mappigs User Display Name Field and 2nd User Display Name Field. Here you could set a second field in addition to display name. I would go for changing the data in the directory, if somehow possible. If you want to hack this into the code, you can start by checking out the handling of ldapUserDisplayName2 field in apps/user_ldap.
Maybe, I can give you some assistance with this. First, I would suggest moving this conversation to Development forum, because it’s rather development than support issue. Second, I wonder if you can share some details about your nextcloud environment, like OS and version.
If you’re familiar with PHP start looking into apps/user_ldap/lib/User/User.php at function processAttributes where you find the values from LDAP being put together for Nextcloud. I can have a look myself in the next few days too.
I found that id of the settings page field for 2nd display name was ldap_user_display_name_2 so I tried changing these files to have a similar field for ldap_user_display_name_3 and setter methods accordingly
This added the required field in the UI on the Advanced / Directory Settings page but it does not display the 3rd attribute by picking up from the ldap server
Thanks for pointing this out. I am checking it
A side quest as well in the same:-
My case is that organization officers have rank unit, designation and a personal No. as attributes which are needed to distinguish users… So I set up a test user Naufil Asar in which attributes rank has value of ‘egRank’, unit = egUnit and so on
The expected result would be, so need to remove the parenthesis put in those 2nd displayName: egRank Naufil Asar egUnit egDesignation egPersonalNo
Also I do not have authority to modify AD in the production environment, this is my test machine and I have only basic understanding of general programming so php syntax is intimidating for first time for me…
Okay. For moving the thread to Development I guess you need to edit your initial post and change the category. I haven’t done or tried either.
For the coding, you can have a look at Pull Request 36565 to get an better idea of what needs to be done for adding more LDAP attributes.
I’ll try to explain and clearify how it’s connected.
apps/user_ldap/templates/settings.php
PHP producing the HTML settings page.
apps/user_ldap/js/wizard/wizardTabAdvanced.js
JavaScript for handling the Advanced settings tab. Needs to define the Element, the configuration field, and a method to set the value.
apps/user_ldap/lib/Configuration.php
PHP configuration class for the LDAP/AD integration. Configuration array element and default value. Mapping HTML/JavaScript variable to configuration array element.
apps/user_ldap/lib/Connection.php
PHP class connecting the configuration array with the database.
apps/user_ldap/lib/User/Manager.php
PHP class handling the user. In function getAttributes it’s setup, what to read from LDAP/AD.
apps/user_ldap/lib/User/User.php
PHP class doing the work. In function processAttributes the user gets prepared and updated.
So far… I think the best approach could be changing ldap_user_display_name_2 from single value to multi line array. This could minimize the change needed and keep it clean and simple.
Hi again. I made a quick hack for you, so you can try out. It’s not nice yet more a proof of concept stage. Hope it helps.
Here is what I changed and how it works…
It’s using the configuration field ldapUserDisplayName2 as list of attributes, seperated with ++. So, you set the User Display Name Field to egRank and 2nd User Display Name Field to displayName++egUnit++egDesignation++egPersonalNo and all four fields are added, if found.
apps/user_ldap/lib/User/Manager.php in function getAttributes
I removed the fixed ldapUserDisplayName2 from the attributes array definition
I added a foreach loop to add every attribute listet in ldapUserDisplayName2 seperatly
explode("++",$this->access->getConnection()->ldapUserDisplayName2) converts the list to array
foreach (explode( ... ) as $attr2) loop through the array and process each attribute name as $attr2
array_push($attributes,$attr2); append each listet attribute name to the list of attributes
apps/user_ldap/lib/User/User.php in function processAttributes
if there is ++ found in the attribute name (strpos($attr,"++") !== false) we treat it as list of attributes.
foreach (...) again loops through the list
if attribute $attr2 was returned from the directory isset($ldapEntry[$attr2])
we append space (empty($displayName2) ?"" :" ") and the attribute value (string)$ldapEntry[$attr2][0] to $displayName2
(empty($displayName2) ?"" :" ") if empty use “” and otherwise " "
(string)$ldapEntry[$attr2][0] ensure value is a string
Following is a patch file, you can download at github.com
diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index 04c67a537b8..130a2271351 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -163,6 +163,10 @@ class Manager {
$this->access->getConnection()->ldapAttributeHeadline,
$this->access->getConnection()->ldapAttributeBiography,
];
+ // parse attribute list and add each
+ foreach (explode("++",$this->access->getConnection()->ldapUserDisplayName2) as $attr2) {
+ array_push($attributes,$attr2);
+ }
$homeRule = (string)$this->access->getConnection()->homeFolderNamingRule;
if (strpos($homeRule, 'attr:') === 0) {
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index f85e4206eff..d5f273c0447 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -184,8 +184,15 @@ class User {
$displayName = (string)$ldapEntry[$attr][0];
}
$attr = strtolower($this->connection->ldapUserDisplayName2);
- if (isset($ldapEntry[$attr])) {
+ if (isset($ldapEntry[$attr])) { // attribute found
$displayName2 = (string)$ldapEntry[$attr][0];
+ } elseif (strpos($attr,"++") !== false) {
+ // list of attributes
+ foreach (explode("++",$attr) as $attr2) {
+ if (isset($ldapEntry[$attr2])) {
+ $displayName2 .= (empty($displayName2) ?"" :" ") . ((string)$ldapEntry[$attr2][0]);
+ }
+ }
}
if ($displayName !== '') {
$this->composeAndStoreDisplayName($displayName, $displayName2);
EDIT: I needed to fix the $displayName2 concatenation
EDIT2: DisplayName2 is added in paranthesis, so maybe you should set 2nd User Display Name Field to Rank++Unit++Designation++PersonalNo.
This solution is easier and more logical than what I had been trying, but even after implementing this, the DisplayName2 field is never shown, that is:
So, only the rank field is being shown… I tried debugging and print statements but none worked, so I tried throwing an Exception in Manager.php which showed that getAttribute function receives all the data as expected but exceptions in User.php don’t show up anywhere so I am not sure why this is happening
Hmmm. I will have a closer look later, when i`m at my laptop.
Sorry, if this sounds dumb, its not intented to. Do you know, processAttributes is only called on few events? And it sounds like it didnt fire any of those events for the given user. You can use the occ script to update, which I prefer, for showing the attributes on command output. Even quickndirty debugging with echo/print would show in the output. php occ ldap:check-user --update <user uid>
The user uid is shown under the users displayname in the list. For egRank it`s starting with D58E…
If you place the output or exception in processAttributes you can better check, i think.
No, It sounds perfectly logical… I tried generating exception in the composeAndStoreDisplayName() which is called inside it and it logged the exception normally
I’m surprised it does fetch everything for following setting
I don’t think so and I have no glue. I would think this is an cache issue, because the data should’nt be updated while cached. At least if you have Memcache configured. If this is an test instance, without real traffic, you could check by setting Cache TTL to 60 seconds (i think it’s in settings, advanced, connection settings). So it would at least update after 1 minute.
AND my bet would be however, that there’s another function setting the Display Name. So it would get changed by processAttribute and rechanged by the other function. I can check this, when I have access to my developing machine.
EDIT: After a quick search I found at least function getDisplayName in lib/User_LDAP.php building the DisplayName and calling composeAndStoreDisplayName.