Omer
Omer

Reputation: 164

laravel multiple models in policy

I have a two level resource in Laravel as below;

Route::resource("domains", "DomainsController");
Route::resource("domains/{domain}/subdomains", "SubDomainsController");

and I have two policies;

DomainPolicy.php
SubDomainPolicy.php

the problem is that these domains belong to different users, so I have to authorize these domains and subdomains. I can authorize DomainsController easily since all I have to do is Domain::class => DomainPolicy::class in AuthServiceProvider.php.

When it comes to authorizing SubDomainsController I can use the same policy input such as SubDomain::class => SubDomainPolicy::class, BUT when I access the /domains/1/subdomains/create link since there is no Domain::class delivered to the SubDomainPolicy::class it always prevents access to create page.

I use $this->authorizeResource(Domain::class) and $this->authorizeResource(SubDomain::class) in resource controller constructors without any arguments.

I need to pass Domain model to the SubDomainPolicy someway, thanks in advance.

Upvotes: 1

Views: 1916

Answers (1)

Omer
Omer

Reputation: 164

I have found the solution not through a policy but a middleware. Since the models are binded on web.php Domain::class is always delivered to the SubDomainsController class, so I changed the constructor as;

public function __construct(Domain $domain) {
    $this->middleware("domain-access");
}

or you can set it on web.php as a middleware group (eg. ['middleware' => 'domain-access']).

In middleware folder create a middleware named DomainAccess.php with this content;

namespace App\Http\Middleware;

use Closure; use Illuminate\Auth\Access\AuthorizationException;

class DomainAccess
{

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user   = $request->user();
        $domain = $request->domain;

        if ($domain->user_id != $user->id) {
            return redirect("/");
        }

        return $next($request);
    }
}

And, voila! Everything is working perfectly.

Have a beautiful day.

Upvotes: 1

Related Questions