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\Text;
|
||||||
use App\Text\CreateTextDto;
|
use App\Text\CreateTextDto;
|
||||||
use App\Text\TextRepository;
|
use App\Text\TextRepository;
|
||||||
|
use App\User\User;
|
||||||
use App\User\UserRepository;
|
use App\User\UserRepository;
|
||||||
use DomainException;
|
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
|
private function hydrate(array $data): Text
|
||||||
{
|
{
|
||||||
$user = $this->userRepo->find($data['userId']);
|
$user = $this->userRepo->find($data['userId']);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class TextController
|
||||||
private TextRepository $textRepository,
|
private TextRepository $textRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function getTexts(Response $response): Response
|
public function getAllTexts(Response $response): Response
|
||||||
{
|
{
|
||||||
$texts = $this->textRepository->getAll();
|
$texts = $this->textRepository->getAll();
|
||||||
|
|
||||||
|
|
@ -31,14 +31,63 @@ class TextController
|
||||||
return $response->withHeader('Content-Type', 'application/json');
|
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);
|
$text = $this->textRepository->find($textId);
|
||||||
|
|
||||||
if ($text === null) {
|
if ($text === null) {
|
||||||
return $response->withStatus(404);
|
return $response->withStatus(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
$text->getUser()->getId() !== $user->getId()
|
||||||
|
&& !$user->isAdmin()
|
||||||
|
) {
|
||||||
|
return $this->errorResponse(
|
||||||
|
$response,
|
||||||
|
403,
|
||||||
|
'forbidden'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$response->getBody()->write(json_encode([
|
$response->getBody()->write(json_encode([
|
||||||
'id' => $text->getId(),
|
'id' => $text->getId(),
|
||||||
'name' => $text->getName(),
|
'name' => $text->getName(),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Text;
|
||||||
|
|
||||||
use App\Text\Text;
|
use App\Text\Text;
|
||||||
use App\Text\CreateTextDto;
|
use App\Text\CreateTextDto;
|
||||||
|
use App\User\User;
|
||||||
|
|
||||||
interface TextRepository
|
interface TextRepository
|
||||||
{
|
{
|
||||||
|
|
@ -15,4 +16,9 @@ interface TextRepository
|
||||||
* @return Text[]
|
* @return Text[]
|
||||||
*/
|
*/
|
||||||
public function getAll(): array;
|
public function getAll(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Text[]
|
||||||
|
*/
|
||||||
|
public function findByUser(User $user): array;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ namespace Tests\Fakes;
|
||||||
use App\Text\CreateTextDto;
|
use App\Text\CreateTextDto;
|
||||||
use App\Text\Text;
|
use App\Text\Text;
|
||||||
use App\Text\TextRepository;
|
use App\Text\TextRepository;
|
||||||
|
use App\User\User;
|
||||||
|
|
||||||
class FakeTextRepository implements TextRepository
|
class FakeTextRepository implements TextRepository
|
||||||
{
|
{
|
||||||
|
|
@ -61,4 +62,29 @@ class FakeTextRepository implements TextRepository
|
||||||
array_values($this->existingTexts)
|
array_values($this->existingTexts)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Text[]
|
||||||
|
*/
|
||||||
|
public function findByUser(User $user): array
|
||||||
|
{
|
||||||
|
$userId = $user->getId();
|
||||||
|
$owned = array_filter(
|
||||||
|
$this->existingTexts,
|
||||||
|
function (Text $text) use ($userId) {
|
||||||
|
return $text->getUser()->getId() === $userId;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return array_map(
|
||||||
|
function (Text $text) {
|
||||||
|
return new Text(
|
||||||
|
id: $text->getId(),
|
||||||
|
name: $text->getName(),
|
||||||
|
user: $text->getUser(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
array_values($owned)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue