adldap2 integration with laravel 5.3 binding to Auth driver - laravel-5.3

Ok, so there is some documentation on this, which I've followed (https://github.com/Adldap2/Adldap2-Laravel), but I cannot seem to get this working. I'm also using laravel 5.3 so I don't know if that has something to do with it. And please bear with me as I'm new to laravel.
I cannot authenticate using the Auth::attempt($creds) method.
I can, however authenticate with Adldap::user()->attempt($user,$pass)
I want to use the Auth facade so I can verify logins and such. If there is another way to do it without using Auth I'm all ears.
I also want to bind to the User model once that user has logged in, but I haven't gotten far enough to see if that works.
I've been working on this for a few days and I think it's time I reach out. Please help!
Here's what I'm working with...
adldap.php:
'auto_connect' => false,
adldap_auth.php:
'bind_user_to_model' => env('ADLDAP_BIND_USER_TO_MODEL', true)
auth.php:
'providers' => [
'users' => [
'driver' => 'adldap',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
app.php:
'aliases' => [
'Adldap' => Adldap\Laravel\Facades\Adldap::class,
]
'providers' => [
Adldap\Laravel\AdldapServiceProvider::class,
]
controller:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
use Illuminate\Support\Facades\Input;
class LoginController extends Controller
{
public function login()
{
$input = Input::all();
if(Auth::attempt([$input['username'],$input['password']])
{
return 'Authenticated';
}
}
}
User model:
namespace App\Models;
use Adldap\Laravel\Traits\AdldapUserModelTrait;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements AuthenticatableContract
{
use Authenticatable, AdldapUserModelTrait;
use Authenticatable, AdldapUserModelTrait;
}

Related

Temporarly disabling a doctrine entity listener

I use doctrine entity listeners to send mail whenever an entity is created. I want to be able to disable this event listener when performing certain operations (fixtures are mailbombing me as soon as I try to populate my database with fake entities).
I tried to disable the listener by using the clear method of the EntityListenerResolver class without success.
Here is my listener configuration:
services:
mail_on_create_document_listener:
class: App\EventListener\MailOnCreateDocumentListener
autowire: true
tags:
-
name: 'doctrine.orm.entity_listener'
event: 'postPersist'
entity: 'App\Entity\Document'
I try to disable the listener with this code:
<?php
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class DebugFixture extends Fixture implements FixtureGroupInterface
{
public function load(ObjectManager $manager)
{
$manager->getConfiguration()->getEntityListenerResolver()->clear(MailOnCreateDocumentListener::class);
dump($manager->getConfiguration()->getEntityListenerResolver());
}
}
Here is the resulting dump of the EntityListenerResolver
^ Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver^ {#1233
-container: Symfony\Component\DependencyInjection\Argument\ServiceLocator^ {#5278
-factory: Symfony\Component\DependencyInjection\Container::getService($registry, string $id, ?string $method, $load)^ {#283
this: ContainerHYiq7Ex\srcApp_KernelDevDebugContainer {#4404 …}
}
-serviceMap: array:1 [
"mail_on_create_document_listener" => array:4 [
0 => "privates"
1 => "mail_on_create_document_listener"
2 => "getMailOnCreateDocumentListenerService.php"
3 => true
]
]
-serviceTypes: array:1 [
"mail_on_create_document_listener" => "?"
]
-externalId: null
-container: null
-factories: array:1 [
"mail_on_create_document_listener" => array:4 [
0 => "privates"
1 => "mail_on_create_document_listener"
2 => "getMailOnCreateDocumentListenerService.php"
3 => true
]
]
-loading: []
-providedTypes: null
}
-instances: []
-serviceIds: array:1 [
"App\EventListener\MailOnCreateDocumentListener" => "mail_on_create_document_listener"
]
}
Reading the code, it seems that the clear from EntityListenerResolver affects the instance part, but not the serviceIds.
How does this clear method is supposed to work?
Is my service declaration wrong?
EDIT: I also tried this code with no success
$evm = $manager->getEventManager();
$listeners = $evm->getListeners("postPersist");
while (count($listeners))
{
$evm->removeEventListener(array("postPersist"), array_pop($listeners));
}
But I read that entity listeners were quite different from other listeners, though it was not clear which was the difference. Here is the quote from the doc:
Different from Events an Entity Listener is invoked just to the specified entity

Api Platform Pagination json format

i need help with the api platform pagination in json format.
here is my api_platform.yaml
api_platform:
allow_plain_identifiers: true
mapping:
paths: ['%kernel.project_dir%/src/Entity']
formats:
json: ['application/json']
when i used the format hydra (default) i got something like this
"hydra:view": {
"#id": "/api/galleries?page=1",
"#type": "hydra:PartialCollectionView",
"hydra:first": "/api/galleries?page=1",
"hydra:last": "/api/galleries?page=6",
"hydra:next": "/api/galleries?page=2"
}
can anyone help me? if it's possible to get something like that in json format or another way to aply pagination with api platform or symfony
thank you
You shoud create an event Subscriber :
<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator;
final class PaginateJsonSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['normalizePagination', EventPriorities::PRE_RESPOND],
];
}
public function normalizePagination(
ViewEvent $event
): void {
$method = $event->getRequest()->getMethod();
if ($method !== Request::METHOD_GET) {
return;
}
if (($data = $event->getRequest()->attributes->get('data')) && $data instanceof Paginator) {
$json = json_decode($event->getControllerResult(), true);
$pagination = [
'first' => 1,
'current' => $data->getCurrentPage(),
'last' => $data->getLastPage(),
'previous' => $data->getCurrentPage() - 1 <= 0 ? 1 : $data->getCurrentPage() - 1,
'next' => $data->getCurrentPage() + 1 > $data->getLastPage() ? $data->getLastPage() : $data->getCurrentPage() + 1,
'totalItems' => $data->getTotalItems(),
'parPage' => count($data)
];
$res = [
"data" => $json,
"pagination" => $pagination
];
$event->setControllerResult(json_encode($res));
}
}
}
In API Platform we have the jsonapi format which provides us the support for pagination. You can set the default config for number of records per page in api platform as:
# api/config/packages/api_platform.yaml
api_platform:
defaults:
pagination_items_per_page: 30 # Default value
formats:
jsonapi: ['application/vnd.api+json']
With this configuration you would require to either have an item and collection normalizer to customise the structure of the response with pagination metadata OR you can use state providers for this purpose (check here)
You would still get all the necessary pagination metadata if you just leave your default format as jsonapi
This is the very good resource to read more about API Platform pagination

laravel phpunit withexceptionhandling

I'm in the process of writing a web app using Laravel 5.5 and Vue.js. PHPUnit version is 6.3.1.
I'm testing for validation errors when a user registers using Form Requests.
Route:
// web.php
Route::post('/register', 'Auth\RegisterController#store')->name('register.store');
This is my passing test:
/** #test */
function validation_fails_if_username_is_missing()
{
$this->withExceptionHandling();
$this->json('POST', route('register.store'), [
'email' => 'johndoe#example.com',
'password' => 'secret',
'password_confirmation' => 'secret'
])->assertStatus(422);
}
However, it fails when I remove exception handling:
/** #test */
function validation_fails_if_username_is_missing()
{
$this->json('POST', route('register.store'), [
'email' => 'johndoe#example.com',
'password' => 'secret',
'password_confirmation' => 'secret'
])->assertStatus(422);
}
I do not understand why this test fails without exception handling as it's stated in the Laravel documentation that
If the request was an AJAX request, a HTTP response with a 422 status
code will be returned
I already tried to declare this particular route in the api middleware group, but that didn't change anything.
Can someone with more experience than I do explain to me why that is? Thanks in advance.
EDIT: This is the content of my Handler.php class file. I don't think anything was edited.
protected $dontReport = [
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Session\TokenMismatchException::class,
\Illuminate\Validation\ValidationException::class,
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}

Laravel Testing login Credential using phpunit + multiprocess

I'm pretty new on unit testing and I want to try to test my login page
my Goal for this unit are :
-> if it match in database -> redirect to route '/'
-> if not -> redirect to route '/login'
<?php
namespace Tests\Feature;
use App\Domain\Core\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class userTest extends TestCase
{
use DatabaseMigrations;
/**
* A basic test example.
*
* #return void
*/
public function testLoginTrue()
{
$credential = [
'email' => 'user#ad.com',
'password' => 'user'
];
$this->post('login',$credential)->assertRedirect('/');
}
public function testLoginFalse()
{
$credential = [
'email' => 'user#ad.com',
'password' => 'usera'
];
$this->post('login',$credential)->assertRedirect('/login');
}
}
when I test on TestLoginTrue , its successfully return to '/' But when i try the TestLoginFalse ... it return same like TestLoginTrue, it should be stayed on '/login' route,
Any Idea?
Plus I want to try to check if when I already login I couldn't access the login page so my initial idea is :
public function testLoginTrue()
{
$credential = [
'email' => 'user#ad.com',
'password' => 'user'
];
$this->post('login',$credential)
->assertRedirect('/')
->get('/login')
->assertRedirect('/');
}
but... it returns
1) Tests\Feature\userTest::testLoginTrue BadMethodCallException:
Method [get] does not exist on Redirect.
So how to do it correctly?
Thanks in advance
I am also a bit stuck with Laravel 5.4 testing follow redirects case.
As a workaround, you may check $response->assertSessionHasErrors(). This way it should work:
public function testLoginFalse()
{
$credential = [
'email' => 'user#ad.com',
'password' => 'incorrectpass'
];
$response = $this->post('login',$credential);
$response->assertSessionHasErrors();
}
Also, in testLoginTrue() you may check, that session missing errors:
$response = $this->post('login',$credential);
$response->assertSessionMissing('errors');
Hope this helps!

ZF2 - ServiceManager & getServiceConfig problems - unable to fetch or create instance

I am coming across some problems when trying to use ZF2's authentication services. I have to following Module.php getServiceConfig function:
<?php
public function getServiceConfig()
{
return array(
'factories' => array(
'Auth\Model\CustomerTable' => function($sm) {
$tableGateway = $sm->get('CustomerTableGateway');
$table = new CustomerTable($tableGateway);
return $table;
},
'CustomerTableGateway' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Customer()); // prototype pattern implemented.
return new TableGateway('customer', $dbAdapter, null, $resultSetPrototype);
},
'Auth\Model\AuthStorage' => function($sm){
return new \Auth\Model\AuthStorage('jamietech');
},
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter,
'customer','username','password');
$authService = new AuthenticationService();
$authService->setAdapter($dbTableAuthAdapter);
$authService->setStorage($sm->get('Auth\Model\AuthStorage'));
return $authService;
},
),
);
}
The AuthStorage factory simply creates a new AuthStorage for us to keep track of the rememberMe function I have, and the AuthService factory creates a new Authentication Service for us. I can't see anything that I have done wrong but when running the following code in the AuthController.php:
<?php
public function loginAction()
{
//if already login, redirect to success page
if ($this->getAuthService()->hasIdentity()){
return $this->redirect()->toRoute('success');
}
$form = new LoginForm();
return array(
'form' => $form,
'messages' => $this->flashmessenger()->getMessages()
);
}
public function logoutAction()
{
$this->getSessionStorage()->forgetMe();
$this->getAuthService()->clearIdentity();
$this->flashmessenger()->addMessage("You have logged out successfully.");
return $this->redirect()->toRoute('auth', array('action'=>'login'));
}
PHPUnit encounters the following errors when running the PHPUnit command:
1: "testLoginActionCanBeAccessed - Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance of Zend\Db\Adapter\Adapter
1: "testLogoutActionCanBeAccessed - session_regenerate_id(): cannot regenerate session id - headers already sent.
And this error for both login and logout when the -process-isolation command is run:
"Serialization of closure is not allowed in: C;\Users\-----\AppData\Local\Temp\-----
If somebody could help that would be great. I am a ZF noob so try not to be too harsh.
EDIT: BTW THe global.php file includes the service_manager adapter factory illustrated in the ZF2 tutorial application.
Thank you!
Jamie Mclaughlan
did you check these:
autoload_classmap.php (for your module)
in your module.config.php
like this
service_manager' => array(
'aliases' => array(
'mymodule-ZendDbAdapter' => 'Zend\Db\Adapter\Adapter',
),
);
I hope it helps you to find the answer

Resources