Laravel Policies - $this->authorize not working - laravel

Task policy:
class TaskPolicy
{
use HandlesAuthorization;
public function canSeeTeam()
{
return true;
}
}
AuthServiceProvider:
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Models\Task' => 'App\Policies\TaskPolicy',
];
Task controller:
public function update(Request $request, Task $task)
{
$this->authorize('canSeeTeam');
dd('Authorized!');
}
Instead of getting Authorized! I get:
"message": "This action is unauthorized.",
"exception": "Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException",
I'm logged in, and have access to the team, not it matters because canSeeTeam always true.

You also have to pass the task object to the authorize method:
$this->authorize('canSeeTeam', $task);

Please send me error message or replace this:
public function canSeeTeam()
{
return true; => return false;
}

Related

My authorize function is always failing in laravel-5.8?

I created one policy inside create function i am checking weather this user can able to create records and i am registering the Model and policy in the AthServiceProvider.php after that i am checking inside the controller by using $this->authorize('create') it's failing always even the user is valid,can you please help me how to resolve this issue
Error:- This Action is unathorized
restaurentContoller.php
class RestaurentsController extends Controller
{
protected $repository;
public function __construct(RestaurentRepository $repository){
$this->repository = $repository;
}
public function postRestaurent(RestaurentRequest $request){
$data = $request->all();
$data['admin_id'] = $this->getAccountId($request);
$this->authorize('create');
$rest = $this->repository->create($data);
return response()->json(fractal($rest,new RestuarentTransformer));
}
}
RestaurentPolicy.php
public function create(User $user)
{
return ($user->admin_id=1) ? true : false;
}
api.php
Route::post('/postRest',[RestaurentsController::class,'postRestaurent'])->middleware(['CheckAdmin']);
If you use Request Classes you have to change authorize method return false to true
class RestaurentStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return false;
}
}

Call to a member function hasAccessOrFail() on null error when using backpack in Laravel

I've been using backpack in Laravel but I want to replace action-domain-responder architecture with MVC.So I've created an Action which my route refers like below:
Route::get('post',[
'as' => 'post.index',
'uses' => 'Core\Post\Actions\ApiGetListOfPostsAction',
'operation' => 'list'
]);
class ApiGetListOfPostsAction extends BaseAction implements IAction
{
private $service;
public function __construct(ApiGetListOfPostsService $service)
{
$this->service = $service;
}
public function __invoke(Request $request): mixed
{
$data = $this->service->process();
return response()->json($data);
}
}
and my service has this code:
class ApiGetListOfPostsService extends CrudController
{
use ListOperation, CreateOperation, DeleteOperation, UpdateOperation;
public function setup()
{
CRUD::setModel(\App\Models\Post::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/post');
CRUD::setEntityNameStrings('post', 'posts');
}
protected function setupListOperation()
{
CRUD::column('title');
CRUD::column('content');
}
public function process()
{
return $this->index();
}
}
I've extended CrudController in my service class but I've got this error:
Call to a member function hasAccessOrFail() on null
which related to the ListOperation Trait and this code:
public function index()
{
$this->crud->hasAccessOrFail('list');
}
I need to send all requests to the Service class. How can I pass requests to the service class?
When I deleted middleware from CrudController I have no problem.
$this->middleware(function ($request, $next) {
$this->crud = app()->make('crud');
$this->crud->setRequest($request);
$this->setupDefaults();
$this->setup();
$this->setupConfigurationForCurrentOperation();
return $next($request);
});
I think your Action is missing something.
When using inheritance from a parent class, it might help to put this line in your constructor.
public function __construct(ApiGetListOfPostsService $service)
{
parent::__construct(); // <- Subclass constructor
$this->service = $service;
}
Doc: https://www.php.net/manual/en/language.oop5.decon.php

Notification fake assertion not working on password reset test?

I was trying to make tests for my auth routes. For password reset route I am trying to make in which I am faking the notification module of laravel and asserting as per the docs.
This is my test file
public function testUserReceivesAnEmailWithAPasswordResetLink()
{
$this->withoutExceptionHandling();
Notification::fake();
$user = factory(User::class)->make();
$response = $this->post($this->passwordEmailPostRoute(), [
'email' => $user->email,
]);
$this->assertNotNull($token = DB::table('password_resets')->where('email', $user->email));
Notification::assertSentTo($user, PasswordReset::class);
}
While I am running this, I am getting notification was not sent error.
My User model is like this:
use Notifiable, HasApiTokens, SoftDeletes, Uuidable, Switchable, ResourceMapper;
public function role()
{
return $this->belongsTo('App\Models\Role');
}
public function company()
{
return $this->belongsTo('App\Models\Company');
}
public function AauthAccessToken()
{
return $this->hasMany('App\Models\OauthAccessToken');
}
public function isRole($role)
{
return $this->role->uuid == $role;
}
public function sendPasswordResetNotification($token)
{
$this->notify(new PasswordReset($token));
}
public function resource()
{
return $this->morphTo();
}
I can't figure whats the exact problem.

Laravel authorization policy not being called

My authorization policy is not being called and I am receiving a 403 error. This is part of an API.
I have tried calling it from the controller by using the 'authorize' helper or via middleware. I have also tried using the auth()->guard('api')->user()->can().
DeckPolicy.php
public function view(User $user, Deck $deck)
{
dd('policy called');
if ($deck->private) {
return false;
}
return true;
}
AuthServiceProvider.php
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Deck' => 'App\Policies\DeckPolicy'
];
public function boot()
{
$this->registerPolicies();
}
}
DecksController.php
public function show(Deck $deck)
{
$this->authorize('view', $deck);
return new DeckResource($deck);
}
I expect the output to be 'policy called', but all I am receiving is a 403 error page when using Postman.
I would like to understand why the 'authorize()' helper function is not working as expected.

Laravel validation site belongs to user

My User.php
class User extends Authenticatable
{
public function sites()
{
return $this->hasMany(Site::class);
}
}
My Site.php
class Site extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
My routes.php
Route::resource('site', 'SiteController');
My SiteController.php
class SiteController extends Controller
{
public function edit(int $id)
{
$site = Auth::user()->sites()->find($id);
return view('site.edit', compact('site'));
}
}
How can I validate that the site belongs to user? I understand that in my case if site doesn't belong to user, $site variable will be null. But I want more declarative way, something like laravel requests, because I need the same check in show, update, and destroy methods. But I cannot use laravel request, because checking is something like this
$siteId = Route::current()->param('site');
$ids = Auth::user()->sites()->pluck('id')->toArray();
$result = in_array($siteId, $ids);
Can anyone suggest how to achieve my goal?
Since I use laravel 5.2, solution with route filters is deprecated. Instead route filter we should use middleware.
app/Http/Middleware/RestrictPermission.php
class RestrictPermission
{
public function handle($request, Closure $next)
{
$siteId = Route::current()->parameter('site');
if (!Auth::user()->sites()->find($siteId)) {
abort(403);
}
return $next($request);
}
}
app/Http/Kernel.php
class Kernel extends HttpKernel
{
protected $routeMiddleware = [
'restrict.permission' => RestrictPermission::class,
];
}
SiteController.php
class SiteController extends Controller
{
public function __construct()
{
$this->middleware('restrict.permission', ['except' => [
'index', 'create', 'store',
]]);
}
public function edit(int $id)
{
$site = Auth::user()->sites()->find($id);
return view('site.edit', compact('site'));
}
}

Resources