BackendAuth Not working correctly.
When i try to instance BackendAuth::getUser or anything method inside the plugin controllers on backend, return null value. On the case of the BackendAuth::check method return false.
For example on the boot of my core custom plugin, i make the instance of the getUser method to filter to a menu items
`
Event::listen('backend.menu.extendItems', function ($manager) use ($restorant, $site) {
$user = BackendAuth::getUser();
$restorant = $restorant->find($user->restorant_principal_id);
$site = $site->find($user->site_principal_id);
if (($user->role_id == 2 || $user->role_id == 4) && $site) {
$manager->addMainMenuItem('hm.app', 'chain', [
'label' => 'Chain',
'url' => Backend::url('hm/app/restorants'),
'icon' => 'icon-chain',
'permissions' => ['hm.app.chain'],
'order' => 100,
]);
}});
`
@bennothommo can you look into this? Since most plugin controllers use __construct() to set the BackendMenu context, which would instantiate the BackendMenu firing this event, we might have a bigger issue then we originally thought with having those controllers instantiated before the session gets started.
Might have to investigate another layer for middleware processing within October instead of relying solely on Laravel鈥檚 implementation so that the BackendController has its middleware processed before checking the plugin / module controllers for middleware to process
I'm hesitant to introduce a new middleware pipeline because there's a lot of avenues for it to go wrong. Taylor Otwell mentioned that using the constructor for Auth checks and the like is inherently the wrong way to do things because technically the request is not processed yet, but I understand that it's the way that October has advertised it in the docs for some time.
I will have a look at some options going forward and will let you know.
@bennothommo it's not even just Auth checks in the controller constructor that's the issue, the constructor usually calls other things that fire events that one would reasonably expect the session to be started by the time they would typically fire.
How do you mean? Couldn't we define a closure middleware in the BackendController constructor that then processes the desired actual Controller middleware inside of it? Something like the following:
public function __construct()
{
$this->middleware(function ($request, $next) {
$middleware = // get the desired controller instance here to get its middleware
// run the middleware pipeline here by passing on the request and next variables
// return any relevant result
}
}
@LukeTowers The main issue is how do we determine that the plugin/module controller in question has any middleware without executing its constructor. It may be a moot point if we chain the middleware like you suggest, but I'll have to investigate it.
@LukeTowers I've come across a possible solution. We can use ReflectionClass to generate an instance of the requested controller without running its constructor (via the newInstanceWithoutConstructor method). The only catch would be that another method would need to be called in the requested controller to define the middleware, ie. defineMiddleware(). I've tested it out and it does work.
My concern with your suggested approach was that the requested controller's constructor would still be run twice, so even if it does resolve the issue, there could be the potential for double-ups in any event hooks or extend calls.
Would you foresee any difficulties in this approach?
The only down side of that approach is the difference between it and the default laravel way of specifying controller middleware. I'd prefer to avoid that if possible
I don't think there's any way around it, unfortunately.
The only way I can think of extracting the middleware from the constructor of a controller without executing said constructor would be to parse the file or tokens of the file and manually retrieve the middleware code from the source. I think such a change would be a hack, at best.
@bennothommo could you try the nested middleware approach I suggested? That should resolve any issues by having the middleware run after the session has been started
@LukeTowers I've tried it out - PR #4190, but there is a caveat which is explained there.
Do now know, why but also for me it returns null.
It's regular backend controller nothing special.
protected function getSchoolId()
{
return BackendAuth::getUser()->current_cluster_id;
}
Any hingfor quick fix?
Do now know, why but also for me it returns null.
It's regular backend controller nothing special.protected function getSchoolId() { return BackendAuth::getUser()->current_cluster_id; }Any hingfor quick fix?
@roulendz
Luckily I have 3 projects with october now with different versions of October, to solve radically replaced all inside modules path in a project that worked for me, then when it is solved I will have to see how to correct all this.
Tt was not a good practice, but to solve it momentarily I had no better option.
@roulendz Is that particular method being called inside the constructor of your backend controller, or is it used within another method (ie. one used for an action within a plugin)? You could try using the changes in PR #4190 and see if that helps.
@leonarpv @roulendz @filipac could you re-test your issue with @bennothommo PR #4190 and put up few comments in PR if it's fixed or not.
So, we could proceed! Thanks a lot ;)
Hi friends, Grappled the whole night (& a better part if the day) yesterday with this issue.
I have found a solution / workaround.
Tried the partials method but still got the BackendAuth::getUser()->id returning '' (NULL). Didn't work.
Didn't work from the controller but it worked from the model without the partial but strangely, if we set readOnly to '1' or '0' instead of 'true' or 'false'.
Here's what worked -
public function formExtendFields($form)
{
if (!$this->user->hasAnyAccess(['daf.erp.manage_employee_tickets'])) {
$form->addFields([
'backenduser_id' => [
'label' => 'daf.erp::lang.ticket.backenduser',
'emptyOption' => '-- Select --',
'showSearch' => 'false',
'span' => 'auto',
'required' => '1',
'readOnly' => '1',
'default' => BackendAuth::getUser()->id,
'type' => 'dropdown'
],
]);
}else {
$form->addFields([
'backenduser_id' => [
'label' => 'daf.erp::lang.ticket.backenduser',
'emptyOption' => '-- Select --',
'showSearch' => 'true',
'span' => 'auto',
'required' => '1',
'readOnly' => '0',
'default' => BackendAuth::getUser()->id,
'type' => 'dropdown'
],
]);
}
}
Its like 2 issues happening at the same time. Basis the set permission, the model needs to retweet the BackendAuth::getUser()->id to the field.yaml and we need to reset readOnly='1' or '0' instead of 'true' or 'false' while changing the drop down attributes.
I'm sorry not from the model but the controller.
Most helpful comment
@roulendz Is that particular method being called inside the constructor of your backend controller, or is it used within another method (ie. one used for an action within a plugin)? You could try using the changes in PR #4190 and see if that helps.