Here are the domain classes :
class AuthorAR {
private $authorId;
}
class BookAR {
private $bookId;
// book owner
private $authorId;
private $title;
public function changeTitle($title) {
$this->title = $title;
}
}
// This will be in the domain layer to make explicit the finding of the book
interface BookRepository {
public function findByBookId($bookId);
public function findForAuthorIdByBookId($authorId, $bookId);
}
Here is the Dao class used for authorization outside of the domain :
class AuthorizationDao {
public function findBookOfIdForAuthorId($bookId, $authorId) {}
}
Here are the 2 aproaches that I've seen in some places and don't know which is better, which one is considered a good practice (this is just a naive example, the main question is where to put this type of authorization) :
// Aproach 1 : call the repository with the method made explicit in the domain,
// in order to check if the book with a specific author exists
class ChangeBookTitleCommandHander {
public function handle($command) {
$book = $bookRepository->findForAuthorIdByBookId($command->authorId, $command->bookId );
if($book === NULL) {
throw new CommandHandlingFailedException();
}
}
}
// Aproach 2 use an authorization service inside the controller to check if a user
// has access to the specific book resource in order to change it's title
class Controller {
public function changeTitleAction() {
// This will use the authorizationDao->findBookOfIdForAuthorId($bookId, $authorId) to allow
// access for changing that resource
// @throws UnauthorizeAccessException
$authorizationService->authorizeCommand($changeBookTitleCommand);
}
}
So how to design this type of permission checking (authorization)? How to design the verification if a particular author is the owner of the book before allowing the BookAR to change it's state (in the case of CQRS where no querying permission is needed, just state change permission) ?