Ldaprecord-laravel: [Bug] DirectoryEmulator and logoutUnauthenticatedUsers() do not play nice

Created on 12 Aug 2020  路  3Comments  路  Source: DirectoryTree/LdapRecord-Laravel

Environment:

  • LDAP Server Type: ActiveDirectory
  • PHP Version: 7.4

Describe the bug:
We are using static::logoutUnauthenticatedUsers(); in our middleware extension of your WindowsAuthenticate and it is working nicely - thanks for that option.

My issue comes when trying to write tests. I've followed the steps you've outlined in the documentation for testing here: https://ldaprecord.com/docs/laravel/auth/testing/. For context, my test looks like this:

    $fakeAD = DirectoryEmulator::setup('default', ['database' => storage_path('ldap_test_database.sqlite')]);

    $ldapUser = LdapUser::create([
        'displayname' => $this->faker->name(),
        'samaccountname' => $this->faker->userName,
        'mail' => $this->faker->unique()->safeEmail,
        'telephonenumber' => $this->faker->numberBetween(10000, 99999),
    ]);

    $fakeAD->actingAs($ldapUser);

    $response = get('/some-url');

    $response->assertOk();

This works fine if we don't use the static::logoutUnauthenticatedUsers(); feature but will always logout the actingAs user if we do. Admittedly, I am new to writing tests in general. Is there a way to approach this to successfully have a faked user stay authenticated while using that feature?

bug

All 3 comments

Hi there @RyanPriceDotCa! Great question!

I don't have this documented -- but you will likely have to set the $_SERVER['AUTH_USER'] parameter before executing your test request:

$fakeAD = DirectoryEmulator::setup('default', ['database' => storage_path('ldap_test_database.sqlite')]);

$ldapUser = LdapUser::create([
    'displayname' => $this->faker->name(),
    'samaccountname' => $this->faker->userName,
    'mail' => $this->faker->unique()->safeEmail,
    'telephonenumber' => $this->faker->numberBetween(10000, 99999),
]);

// We won't need this, since WindowsAuthenticated
// users don't authenticate against our LDAP
// domain (they are already authenticated).
// $fakeAD->actingAs($ldapUser);

// Set the WindowsAuthenticated user.
$_SERVER['AUTH_USER'] = implode('\\', [
    'DOMAIN',
    $ldapUser->getFirstAttribute('samaccountname')
]);

$response = get('/some-url');

$response->assertOk();

You will need to replace DOMAIN with a domain component from your configured LDAP base_dn.

For example, if we have the following base DN:

dc=company,dc=com

Then we would set DOMAIN to COMPANY.

Can you give that a shot and let me know if that works?

That got me going in the right direction. Unfortunately simply setting the $_SERVER variable doesn't persist it with the test request, so the request needs to be passed the server variable.

Digging into the code I found an undocumented withServerVariables function (https://laravel.com/api/7.x/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.html#method_withServerVariables) that accomplishes that.

So the final product ends up looking like this:

    $fakeAD = DirectoryEmulator::setup('default', ['database' => storage_path('ldap_test_database.sqlite')]);

    $ldapUser = LdapUser::create([
        'displayname' => $this->faker->name(),
        'samaccountname' => $this->faker->userName,
        'mail' => $this->faker->unique()->safeEmail,
        'telephonenumber' => $this->faker->numberBetween(10000, 99999),
    ]);

    // Set the WindowsAuthenticated user.
    $remoteUser = implode('\\', [
        'myDomain',
        $ldapUser->getFirstAttribute('samaccountname')
    ]);

    $response = withServerVariables(['REMOTE_USER' => $remoteUser])->get('/');
    $response->assertOk();

Note: I am testing with pestphp. If you're using phpunit, the line would look like this:

$this->withServerVariables(['REMOTE_USER' => $remoteUser])->get('/');

Thanks for your help, hopefully this helps someone else down the road too.

Awesome, thanks for replying back with your solution @RyanPriceDotCa! I'm going to add this into the documentation :smile:

Was this page helpful?
0 / 5 - 0 ratings