Added LDAP group debugging env option

Closes #3345
This commit is contained in:
Dan Brown 2022-03-23 16:34:23 +00:00
parent dd7463259a
commit 8594f42584
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
5 changed files with 88 additions and 11 deletions

View File

@ -5,6 +5,7 @@ namespace BookStack\Auth\Access\Guards;
use BookStack\Auth\Access\LdapService; use BookStack\Auth\Access\LdapService;
use BookStack\Auth\Access\RegistrationService; use BookStack\Auth\Access\RegistrationService;
use BookStack\Auth\User; use BookStack\Auth\User;
use BookStack\Exceptions\JsonDebugException;
use BookStack\Exceptions\LdapException; use BookStack\Exceptions\LdapException;
use BookStack\Exceptions\LoginAttemptEmailNeededException; use BookStack\Exceptions\LoginAttemptEmailNeededException;
use BookStack\Exceptions\LoginAttemptException; use BookStack\Exceptions\LoginAttemptException;
@ -15,7 +16,7 @@ use Illuminate\Support\Str;
class LdapSessionGuard extends ExternalBaseSessionGuard class LdapSessionGuard extends ExternalBaseSessionGuard
{ {
protected $ldapService; protected LdapService $ldapService;
/** /**
* LdapSessionGuard constructor. * LdapSessionGuard constructor.
@ -57,12 +58,13 @@ class LdapSessionGuard extends ExternalBaseSessionGuard
* Attempt to authenticate a user using the given credentials. * Attempt to authenticate a user using the given credentials.
* *
* @param array $credentials * @param array $credentials
* @param bool $remember * @param bool $remember
*
* @throws LoginAttemptException
* @throws LdapException
* *
* @return bool * @return bool
* @throws LdapException*@throws \BookStack\Exceptions\JsonDebugException
*
* @throws LoginAttemptException
* @throws JsonDebugException
*/ */
public function attempt(array $credentials = [], $remember = false) public function attempt(array $credentials = [], $remember = false)
{ {

View File

@ -15,12 +15,17 @@ use Illuminate\Support\Facades\Log;
*/ */
class LdapService class LdapService
{ {
protected $ldap; protected Ldap $ldap;
protected $groupSyncService; protected GroupSyncService $groupSyncService;
protected UserAvatars $userAvatars;
/**
* @var resource
*/
protected $ldapConnection; protected $ldapConnection;
protected $userAvatars;
protected $config; protected array $config;
protected $enabled; protected bool $enabled;
/** /**
* LdapService constructor. * LdapService constructor.
@ -274,6 +279,7 @@ class LdapService
* Get the groups a user is a part of on ldap. * Get the groups a user is a part of on ldap.
* *
* @throws LdapException * @throws LdapException
* @throws JsonDebugException
*/ */
public function getUserGroups(string $userName): array public function getUserGroups(string $userName): array
{ {
@ -285,8 +291,17 @@ class LdapService
} }
$userGroups = $this->groupFilter($user); $userGroups = $this->groupFilter($user);
$allGroups = $this->getGroupsRecursive($userGroups, []);
return $this->getGroupsRecursive($userGroups, []); if ($this->config['dump_user_groups']) {
throw new JsonDebugException([
'details_from_ldap' => $user,
'parsed_direct_user_groups' => $userGroups,
'parsed_recursive_user_groups' => $allGroups,
]);
}
return $allGroups;
} }
/** /**
@ -369,6 +384,7 @@ class LdapService
* Sync the LDAP groups to the user roles for the current user. * Sync the LDAP groups to the user roles for the current user.
* *
* @throws LdapException * @throws LdapException
* @throws JsonDebugException
*/ */
public function syncGroups(User $user, string $username) public function syncGroups(User $user, string $username)
{ {

View File

@ -119,6 +119,7 @@ return [
'ldap' => [ 'ldap' => [
'server' => env('LDAP_SERVER', false), 'server' => env('LDAP_SERVER', false),
'dump_user_details' => env('LDAP_DUMP_USER_DETAILS', false), 'dump_user_details' => env('LDAP_DUMP_USER_DETAILS', false),
'dump_user_groups' => env('LDAP_DUMP_USER_GROUPS', false),
'dn' => env('LDAP_DN', false), 'dn' => env('LDAP_DN', false),
'pass' => env('LDAP_PASS', false), 'pass' => env('LDAP_PASS', false),
'base_dn' => env('LDAP_BASE_DN', false), 'base_dn' => env('LDAP_BASE_DN', false),

View File

@ -34,6 +34,8 @@
<server name="AVATAR_URL" value=""/> <server name="AVATAR_URL" value=""/>
<server name="LDAP_START_TLS" value="false"/> <server name="LDAP_START_TLS" value="false"/>
<server name="LDAP_VERSION" value="3"/> <server name="LDAP_VERSION" value="3"/>
<server name="LDAP_DUMP_USER_DETAILS" value="false"/>
<server name="LDAP_DUMP_USER_GROUPS" value="false"/>
<server name="SESSION_SECURE_COOKIE" value="null"/> <server name="SESSION_SECURE_COOKIE" value="null"/>
<server name="STORAGE_TYPE" value="local"/> <server name="STORAGE_TYPE" value="local"/>
<server name="STORAGE_ATTACHMENT_TYPE" value="local"/> <server name="STORAGE_ATTACHMENT_TYPE" value="local"/>

View File

@ -348,6 +348,62 @@ class LdapTest extends TestCase
]); ]);
} }
public function test_dump_user_groups_shows_group_related_details_as_json()
{
app('config')->set([
'services.ldap.user_to_groups' => true,
'services.ldap.group_attribute' => 'memberOf',
'services.ldap.remove_from_groups' => true,
'services.ldap.dump_user_groups' => true,
]);
$userResp = ['count' => 1, 0 => [
'uid' => [$this->mockUser->name],
'cn' => [$this->mockUser->name],
'dn' => 'dc=test,' . config('services.ldap.base_dn'),
'mail' => [$this->mockUser->email],
]];
$this->commonLdapMocks(1, 1, 4, 5, 4, 2);
$this->mockLdap->shouldReceive('searchAndGetEntries')->times(4)
->with($this->resourceId, config('services.ldap.base_dn'), \Mockery::type('string'), \Mockery::type('array'))
->andReturn($userResp, ['count' => 1,
0 => [
'dn' => 'dc=test,' . config('services.ldap.base_dn'),
'memberof' => [
'count' => 1,
0 => 'cn=ldaptester,ou=groups,dc=example,dc=com',
],
],
], [
'count' => 1,
0 => [
'dn' => 'cn=ldaptester,ou=groups,dc=example,dc=com',
'memberof' => [
'count' => 1,
0 => 'cn=monsters,ou=groups,dc=example,dc=com',
],
]
], ['count' => 0]);
$resp = $this->mockUserLogin();
$resp->assertJson([
'details_from_ldap' => [
'dn' => 'dc=test,' . config('services.ldap.base_dn'),
'memberof' => [
0 => 'cn=ldaptester,ou=groups,dc=example,dc=com',
'count' => 1,
]
],
'parsed_direct_user_groups' => [
'ldaptester',
],
'parsed_recursive_user_groups' => [
'ldaptester',
'monsters',
],
]);
}
public function test_external_auth_id_visible_in_roles_page_when_ldap_active() public function test_external_auth_id_visible_in_roles_page_when_ldap_active()
{ {
$role = Role::factory()->create(['display_name' => 'ldaptester', 'external_auth_id' => 'ex-auth-a, test-second-param']); $role = Role::factory()->create(['display_name' => 'ldaptester', 'external_auth_id' => 'ex-auth-a, test-second-param']);