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