Cytat(Sedziwoj @ 6.12.2007, 22:03:05 )

Liczyłem że zostanie skrytykowana (pozytywnie lub nie) metoda autoryzacji dostępu do treści w kodzie akcji, może się jeszcze doczekam.
Co do metody isAuthorized() to trochę jednak mnie zastanawia, ponieważ czasem zanim dostaniem się do danych nam potrzebnych do autoryzacji musimy wydobyć inne, a wtedy metoda nie robi tylko tego co powinna.
<?php
if ($user->hasCredential('Admin.Post')) {
return true;
}
...
$obj->getAuthor()->getId() == $user->getAttribute('user_id');
?>
Cytat(Sedziwoj @ 6.12.2007, 22:03:05 )

Do tego sprawdzenia powinny być nie na tym poziomie, tylko obiekt autoryzacji to powinien wiedzieć, przekazujemy autora i mamy boolean, nie obchodzi nas czy ma dostęp bo jest adminem czy dlatego że jest autorem.
Nie sądzę byś miał tutaj rację:
- Skąd SecurityManager ma wiedzieć, że ta akcja operuje na takich czy też innych obiektach?
- W jaki sposób ma odczytywać obiekty? W końcu to nie jest brocha SM.
- Co jeśli SecurityManager ma się zachowywać różnie w zależności od akcji? To znaczy są zmiany w sposobie dostępu do tego obiektu.
Osobiście pracuję w kodzie, w którym to SecurityManager ma wiedzieć czy ktoś ma dostęp do obiektu i wierz mi, jest sieczka. Są cztery klasy, każda gromada metod statycznych tylko po to by sprawdzić isUserAuthorizedForApprove(Application, Client, User). Do tego urosły wielkie utile, które są głównie używane w owych managerach.
Cytat(Sedziwoj @ 6.12.2007, 22:03:05 )

Do tego nie wiemy co mamy robić kiedy ktoś nie ma dostępu do treści, przy edycji to jest raczej oczywiste, przy podanym przeze mnie przykładzie dostępu do artykułu już nie. Ponieważ nie chcemy nic robić więcej niż wyświetlić inny szablon.
To co przemawia za tym by ten kod był właśnie w akcji to to, że akcja wie z czego będzie korzystać i z nikim innym nie musi się tym dzielić. Mylisz się twierdząc, że akcja nie wie jak zachować się w przypadku błędu z dostępem do obiektu. Może albo wywalić wyjątek, powiedzmy
new UnauthorizedObjectAccessException(object $type) a jego obsługę zrzucić na kark FrontController-a albo przekierować na odpowiednią stronę (tu dodajemy metodę do interfejsu).
<?php
interface SecureAction extends Action {
public function getCredentials();
}
interface CustomAuthorizationAction extends SecureAction {
public function isAuthorized(RequestDataHolder $rd);
public function getAuthErrorView();
}
?>
W skrajnym wypadku można wywalić CustomAuthorizationAction i pójść w abstrakcje:
<?php
abstract class CustomAuthorizationAction extends AbstractAction implements SecureAction {
public final function execute(RequestDataHolder $rd) {
if ($this->isAuthorized($rd)) { // user ma prawa do potrzebnych obiektów
return $this->doExecute($rd);
}
return $this->getAuthErrorView();
}
protected abstract doExecute(RequestDataHolder $rd);
protected abstract getAuthErrorView();
}
?>
Oczywiście nie jest to jedyne rozwiązanie, fakt faktem zgłoszone uwagi wymagały rozbudowania przykładu podanego na początku. Inny pomysł jaki przyszedł mi do głowy to tworzenie delegatów, które by się przekazywało do SecureManagera.