Polityka dostępu bez przekazywania modelu

0

Hej,

mam trzy encje:
user: id, customer_id
customer: id......
location: id, customer_id

i teraz chciałbym pozwolić na edycję tylko swoich lokalizacji.

class UserPolicy
{
    use HandlesAuthorization;

    public function locationAccess(User $user, $locationId)
    {
        $userLocations = $user->customer->locations;

        if ($user->hasAnyRole([User::ROLE_ADMINISTRATOR])) {
            return true;
        }
die($locationId);  // tutaj mam pusto gdy nie jestem adminem
        return $userLocations->contains('id', $locationId);
    }
}

wywołanie w kontrolerze

$this->authorize('locationAccess', [Location::class, $locationRequest->id]);

zarejestrowalem tak

Location::class => UserPolicy::class

wg mnie nie potrzebuję przekazywać modelu. Pytanie jak przekazać id edytowanej lokalizacji do polityki?

0

popełniłem błąd tutaj

$this->authorize('locationAccess', [Location::class, $locationRequest->id]); // ma być $locationRequest->location_id

ale mam dodatkowe pytanie.
User jest przekazywany automatycznie. Czy to jest User zalogowany czy potrzebuję jeszcze go porównać w stylu
Auth::user()->id === $user->id
?

0

Czy to jest User zalogowany czy potrzebuję jeszcze go porównać w stylu

Jeśli użytkownik jest niezalogowany, polityka z automatu zwraca false - zatem: nie, nie ma potrzeby dodawania takiego warunku.


Btw 1: Twój kod wygląda trochę niecodziennie - mógłbyś wrzucić całą tę metodę kontrolera? Idealnie powinieneś przekazywać tam modele, a nie idki - zatem powinieneś mieć:

$this->authorize('locationAccess', $location);

Btw 2: staraj się nazywać metody polityki sensowniej, np. canUserAccessLocation - dzięki temu będziesz miał samo-dokumentujący się kod:

$this->authorize('canUserAccessLocation', $location);
0

@Patryk27: nie wrzucę kontrollera bo nie ma co, zrobiłem jak należy. Była to metoda do edycji czegoś tam przez, czyli z parametrem ID rekordu. To właśnie to ID przekazałem do polityki.
To tak inicjalnie, dalej wrzuciłem to wszystko w serwis.

0

Czej, dlaczego wrzuciłeś to w serwis?
Za autoryzację powinien odpowiadać kontroler.

0

Hej @Patryk27
czyli jak mam tak:

    public function edit(LocationRequest $locationRequest)
    {
        $this->locationService->update($locationRequest);

        return back()->withInput();
    }

i serwis

    public function update(LocationRequest $locationRequest)
    {
        $location = $this->locationRepository->getOrFail($locationRequest->location_id);

        $this->authorize('canUserAccessLocation', $location);

        $location->location_name = $locationRequest->location_name;
        $location->locality = $locationRequest->locality;

        $this->locationRepository->persist($location);
    }

teraz jest wszystko ładnie w serwisie i kontroller jest czysty.
Jakbyś to przerobił?

0

np. zobacz tutaj
https://stackoverflow.com/questions/23595036/mvc-laravel-where-to-add-logic/25298736#25298736

1 użytkowników online, w tym zalogowanych: 0, gości: 1