]> BookStack Code Mirror - bookstack/commitdiff
LDAP: Review and testing of mulitple-display-name attr support
authorDan Brown <redacted>
Sun, 1 Dec 2024 18:42:54 +0000 (18:42 +0000)
committerDan Brown <redacted>
Sun, 1 Dec 2024 18:42:54 +0000 (18:42 +0000)
Review of #5295
Added test to cover functionality.
Moved splitting from config to service.

app/Access/LdapService.php
app/Config/services.php
tests/Auth/LdapTest.php

index ef6d33f4db146b188495dcbf9732456bcbd74e67..e5037ad2f95699243f495943fbb667b26d96d3a3 100644 (file)
@@ -72,25 +72,23 @@ class LdapService
     }
 
     /**
-     * Calculate the display name.
+     * Build the user display name from the (potentially multiple) attributes defined by the configuration.
      */
-    protected function getUserDisplayName(array $displayNameAttr, array $userDetails, string $defaultValue): string
+    protected function getUserDisplayName(array $userDetails, array $displayNameAttrs, string $defaultValue): string
     {
-        $displayName = [];
-        foreach ($displayNameAttr as $dnAttr) {
+        $displayNameParts = [];
+        foreach ($displayNameAttrs as $dnAttr) {
             $dnComponent = $this->getUserResponseProperty($userDetails, $dnAttr, null);
-            if ($dnComponent !== null) {
-                $displayName[] = $dnComponent;
+            if ($dnComponent) {
+                $displayNameParts[] = $dnComponent;
             }
         }
 
-        if (count($displayName) == 0) {
-            $displayName = $defaultValue;
-        } else {
-            $displayName = implode(' ', $displayName);
+        if (empty($displayNameParts)) {
+            return $defaultValue;
         }
 
-        return $displayName;
+        return implode(' ', $displayNameParts);
     }
 
     /**
@@ -103,12 +101,12 @@ class LdapService
     {
         $idAttr = $this->config['id_attribute'];
         $emailAttr = $this->config['email_attribute'];
-        $displayNameAttr = $this->config['display_name_attribute'];
+        $displayNameAttrs = explode('|', $this->config['display_name_attribute']);
         $thumbnailAttr = $this->config['thumbnail_attribute'];
 
-        $user = $this->getUserWithAttributes($userName, array_filter(array_merge($displayNameAttr, [
-            'cn', 'dn', $idAttr, $emailAttr, $thumbnailAttr,
-        ])));
+        $user = $this->getUserWithAttributes($userName, array_filter([
+            'cn', 'dn', $idAttr, $emailAttr, ...$displayNameAttrs, $thumbnailAttr,
+        ]));
 
         if (is_null($user)) {
             return null;
@@ -117,7 +115,7 @@ class LdapService
         $userCn = $this->getUserResponseProperty($user, 'cn', null);
         $formatted = [
             'uid'   => $this->getUserResponseProperty($user, $idAttr, $user['dn']),
-            'name'  => $this->getUserDisplayName($displayNameAttr, $user, $userCn),
+            'name'  => $this->getUserDisplayName($user, $displayNameAttrs, $userCn),
             'dn'    => $user['dn'],
             'email' => $this->getUserResponseProperty($user, $emailAttr, null),
             'avatar' => $thumbnailAttr ? $this->getUserResponseProperty($user, $thumbnailAttr, null) : null,
index 4e27896870afb67ed19b40f196a00df974428c0e..d73458231506cb56cc16ec81d4329709b14dbf95 100644 (file)
@@ -127,7 +127,7 @@ return [
         'version'                => env('LDAP_VERSION', false),
         'id_attribute'           => env('LDAP_ID_ATTRIBUTE', 'uid'),
         'email_attribute'        => env('LDAP_EMAIL_ATTRIBUTE', 'mail'),
-        'display_name_attribute' => explode('|', env('LDAP_DISPLAY_NAME_ATTRIBUTE', 'cn')),
+        'display_name_attribute' => env('LDAP_DISPLAY_NAME_ATTRIBUTE', 'cn'),
         'follow_referrals'       => env('LDAP_FOLLOW_REFERRALS', false),
         'user_to_groups'         => env('LDAP_USER_TO_GROUPS', false),
         'group_attribute'        => env('LDAP_GROUP_ATTRIBUTE', 'memberOf'),
index 27169a2becff30e878c3f164cb255affd6bcf0eb..9a00c983a50475ee70dbfedc2fe5ce53323555c8 100644 (file)
@@ -29,7 +29,7 @@ class LdapTest extends TestCase
             'auth.defaults.guard'                  => 'ldap',
             'services.ldap.base_dn'                => 'dc=ldap,dc=local',
             'services.ldap.email_attribute'        => 'mail',
-            'services.ldap.display_name_attribute' => ['cn'],
+            'services.ldap.display_name_attribute' => 'cn',
             'services.ldap.id_attribute'           => 'uid',
             'services.ldap.user_to_groups'         => false,
             'services.ldap.version'                => '3',
@@ -581,7 +581,7 @@ class LdapTest extends TestCase
     public function test_login_uses_specified_display_name_attribute()
     {
         app('config')->set([
-            'services.ldap.display_name_attribute' => ['displayName'],
+            'services.ldap.display_name_attribute' => 'displayName',
         ]);
 
         $this->commonLdapMocks(1, 1, 2, 4, 2);
@@ -603,10 +603,37 @@ class LdapTest extends TestCase
         $this->assertDatabaseHas('users', ['email' => $this->mockUser->email, 'email_confirmed' => false, 'external_auth_id' => $this->mockUser->name, 'name' => 'displayNameAttribute']);
     }
 
+    public function test_login_uses_multiple_display_properties_if_defined()
+    {
+        app('config')->set([
+            'services.ldap.display_name_attribute' => 'firstname|middlename|noname|lastname',
+        ]);
+
+        $this->commonLdapMocks(1, 1, 1, 2, 1);
+        $this->mockLdap->shouldReceive('searchAndGetEntries')->times(1)
+            ->with($this->resourceId, config('services.ldap.base_dn'), \Mockery::type('string'), \Mockery::type('array'))
+            ->andReturn(['count' => 1, 0 => [
+                'uid'         => [$this->mockUser->name],
+                'cn'          => [$this->mockUser->name],
+                'dn'          => 'dc=test' . config('services.ldap.base_dn'),
+                'firstname' => ['Barry'],
+                'middlename' => ['Elliott'],
+                'lastname' => ['Chuckle'],
+                'mail'     => [$this->mockUser->email],
+            ]]);
+
+        $this->mockUserLogin();
+
+        $this->assertDatabaseHas('users', [
+            'email' => $this->mockUser->email,
+            'name' => 'Barry Elliott Chuckle',
+        ]);
+    }
+
     public function test_login_uses_default_display_name_attribute_if_specified_not_present()
     {
         app('config')->set([
-            'services.ldap.display_name_attribute' => ['displayName'],
+            'services.ldap.display_name_attribute' => 'displayName',
         ]);
 
         $this->commonLdapMocks(1, 1, 2, 4, 2);
Morty Proxy This is a proxified and sanitized view of the page, visit original site.