In my Laravel project I use Ldap-connector package to authenticate users against LDAP
Auth works fine out of the box.
In /app/providers/AuthServiceProvider.php I have a policy defined to manage LDAP user access, for example:
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->define('rewards', function ($user) {
return ($user->getAdLDAP()->inGroup('Admin') || $user->getAdLDAP()->inGroup('Marketing')) ? true : false;
});
// other policies
// ...
}
In the controller I check the policy for logged in user like:
class RewardController extends Controller {
public function __construct($handler = null) {
$this->authorize('rewards');
}
// other methods
// ...
}
Everything works fine and if logged in user doesn't have Marketing or Admin group, the controller will throw 403 exception.
Now, for my phpunit tests I need to mock LDAP auth and provide the access to the controller to tests it's methods, otherwise policy throws me This action is unauthorized. error
Since ldap auth driver is implemented I don't think user model App/User is used and I can't just have it done with $this->actingAs($user) from Laravel docs from here
I was able to find solution by myself
I switched LDAP connection package to Adldap2/Adldap2-Laravel
I used existing unit tests and created my own auth with Admin group user:
<?php
use Adldap\Auth\Guard;
use Adldap\Connections\Manager;
use Adldap\Connections\Provider;
use Adldap\Contracts\Connections\ConnectionInterface;
use Adldap\Laravel\Facades\Adldap;
use Adldap\Models\User;
use Adldap\Query\Builder;
use Adldap\Schemas\Schema;
use Adldap\Search\Factory;
use Illuminate\Support\Facades\Auth;
use Adldap\Models\Group;
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
public function pass_auth() {
$mockedProvider = $this->mock(Provider::class);
$mockedBuilder = $this->mock(Builder::class);
$mockedSearch = $this->mock(Factory::class);
$mockedAuth = $this->mock(Guard::class);
$mockedConnection = $this->mock(ConnectionInterface::class);
$mockedConnection->shouldReceive('isBound')->once()->andReturn(true);
$mockedBuilder->shouldReceive('getSchema')->once()->andReturn(Schema::get());
$mockedBuilder->shouldReceive('getConnection')->once()->andReturn($mockedConnection);
$adUser = (new User([], $mockedBuilder))->setRawAttributes([
'samaccountname' => ['jdoe'],
'mail' => ['[email protected]'],
'cn' => ['John Doe'],
]);
$manager = new Manager();
$manager->add('default', $mockedProvider);
Adldap::shouldReceive('getManager')->andReturn($manager);
$mockedProvider->shouldReceive('search')->once()->andReturn($mockedSearch);
$mockedProvider->shouldReceive('getSchema')->andReturn(Schema::get());
$mockedProvider->shouldReceive('auth')->once()->andReturn($mockedAuth);
$mockedSearch->shouldReceive('users')->once()->andReturn($mockedSearch);
$mockedSearch->shouldReceive('select')->once()->andReturn($mockedBuilder);
$mockedBuilder->shouldReceive('whereEquals')->once()->andReturn($mockedBuilder);
$mockedBuilder->shouldReceive('first')->once()->andReturn($adUser);
$mockedAuth->shouldReceive('attempt')->once()->andReturn(true);
$this->assertTrue(Auth::attempt(['username' => 'jdoe', 'password' => '12345']));
$mockedGroup = $this->mock(Group::class);
$mockedGroup->shouldReceive('getName')->once()->andReturn('Admin');
$mockedBuilder->shouldReceive('newInstance')->andReturnSelf();
$mockedBuilder->shouldReceive('newCollection')->andReturn([$mockedGroup]);
}
}
This part adds Admin group to the user mock
$mockedGroup = $this->mock(Group::class);
$mockedGroup->shouldReceive('getName')->once()->andReturn('Admin');
$mockedBuilder->shouldReceive('newInstance')->andReturnSelf();
$mockedBuilder->shouldReceive('newCollection')->andReturn([$mockedGroup]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With