scope text endpoints by ownership
TextRepository gains findByUser; JsonTextRepository and the fake implement filtering by stored userId. TextController splits the list endpoint into getMyTexts (own) and getAllTexts (admin), and getText now requires the session user, returning 403 to non-owners while admins bypass.
This commit is contained in:
parent
ea6d65a77d
commit
acdf703d80
4 changed files with 107 additions and 3 deletions
|
|
@ -5,6 +5,7 @@ namespace App\Text;
|
|||
use App\Text\Text;
|
||||
use App\Text\CreateTextDto;
|
||||
use App\Text\TextRepository;
|
||||
use App\User\User;
|
||||
use App\User\UserRepository;
|
||||
use DomainException;
|
||||
|
||||
|
|
@ -67,6 +68,28 @@ class JsonTextRepository implements TextRepository
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Text[]
|
||||
*/
|
||||
public function findByUser(User $user): array
|
||||
{
|
||||
$texts = $this->readTexts();
|
||||
$userId = $user->getId();
|
||||
$owned = array_filter(
|
||||
$texts,
|
||||
function (array $data) use ($userId) {
|
||||
return $data['userId'] === $userId;
|
||||
}
|
||||
);
|
||||
|
||||
return array_map(
|
||||
function (array $data) {
|
||||
return $this->hydrate($data);
|
||||
},
|
||||
array_values($owned)
|
||||
);
|
||||
}
|
||||
|
||||
private function hydrate(array $data): Text
|
||||
{
|
||||
$user = $this->userRepo->find($data['userId']);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class TextController
|
|||
private TextRepository $textRepository,
|
||||
) {}
|
||||
|
||||
public function getTexts(Response $response): Response
|
||||
public function getAllTexts(Response $response): Response
|
||||
{
|
||||
$texts = $this->textRepository->getAll();
|
||||
|
||||
|
|
@ -31,14 +31,63 @@ class TextController
|
|||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function getText(Response $response, int $textId): Response
|
||||
{
|
||||
public function getMyTexts(
|
||||
Request $request,
|
||||
Response $response,
|
||||
): Response {
|
||||
$user = $request->getAttribute('user');
|
||||
if (!$user instanceof User) {
|
||||
return $this->errorResponse(
|
||||
$response,
|
||||
401,
|
||||
'unauthenticated'
|
||||
);
|
||||
}
|
||||
|
||||
$texts = $this->textRepository->findByUser($user);
|
||||
|
||||
$data = array_map(function ($text) {
|
||||
return [
|
||||
'id' => $text->getId(),
|
||||
'name' => $text->getName(),
|
||||
];
|
||||
}, $texts);
|
||||
|
||||
$response->getBody()->write(json_encode($data));
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function getText(
|
||||
Request $request,
|
||||
Response $response,
|
||||
int $textId,
|
||||
): Response {
|
||||
$user = $request->getAttribute('user');
|
||||
if (!$user instanceof User) {
|
||||
return $this->errorResponse(
|
||||
$response,
|
||||
401,
|
||||
'unauthenticated'
|
||||
);
|
||||
}
|
||||
|
||||
$text = $this->textRepository->find($textId);
|
||||
|
||||
if ($text === null) {
|
||||
return $response->withStatus(404);
|
||||
}
|
||||
|
||||
if (
|
||||
$text->getUser()->getId() !== $user->getId()
|
||||
&& !$user->isAdmin()
|
||||
) {
|
||||
return $this->errorResponse(
|
||||
$response,
|
||||
403,
|
||||
'forbidden'
|
||||
);
|
||||
}
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'id' => $text->getId(),
|
||||
'name' => $text->getName(),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Text;
|
|||
|
||||
use App\Text\Text;
|
||||
use App\Text\CreateTextDto;
|
||||
use App\User\User;
|
||||
|
||||
interface TextRepository
|
||||
{
|
||||
|
|
@ -15,4 +16,9 @@ interface TextRepository
|
|||
* @return Text[]
|
||||
*/
|
||||
public function getAll(): array;
|
||||
|
||||
/**
|
||||
* @return Text[]
|
||||
*/
|
||||
public function findByUser(User $user): array;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue