Skip to content

Commit 90fe1d1

Browse files
committed
ISSUE-345: refactor session controller
1 parent 5e58320 commit 90fe1d1

File tree

6 files changed

+131
-65
lines changed

6 files changed

+131
-65
lines changed

config/services/managers.yml

+4
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ services:
77
PhpList\RestBundle\Service\Manager\SubscriberManager:
88
autowire: true
99
autoconfigure: true
10+
11+
PhpList\RestBundle\Service\Manager\SessionManager:
12+
autowire: true
13+
autoconfigure: true

config/services/normalizers.yml

+4
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ services:
1414
PhpList\RestBundle\Serializer\SubscriberNormalizer:
1515
tags: [ 'serializer.normalizer' ]
1616
autowire: true
17+
18+
PhpList\RestBundle\Serializer\AdministratorTokenNormalizer:
19+
tags: [ 'serializer.normalizer' ]
20+
autowire: true

src/Controller/SessionController.php

+24-65
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
namespace PhpList\RestBundle\Controller;
66

7+
use PhpList\RestBundle\Entity\CreateSessionRequest;
8+
use PhpList\RestBundle\Serializer\AdministratorTokenNormalizer;
9+
use PhpList\RestBundle\Service\Manager\SessionManager;
10+
use PhpList\RestBundle\Validator\RequestValidator;
711
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
812
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
9-
use PhpList\Core\Domain\Model\Identity\Administrator;
1013
use PhpList\Core\Domain\Model\Identity\AdministratorToken;
1114
use PhpList\Core\Domain\Repository\Identity\AdministratorRepository;
12-
use PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository;
1315
use PhpList\Core\Security\Authentication;
1416
use PhpList\RestBundle\Controller\Traits\AuthenticationTrait;
1517
use Symfony\Component\HttpFoundation\JsonResponse;
1618
use Symfony\Component\HttpFoundation\Request;
1719
use Symfony\Component\HttpFoundation\Response;
1820
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
19-
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
20-
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
2121
use Symfony\Component\Routing\Attribute\Route;
2222
use Symfony\Component\Serializer\SerializerInterface;
2323
use OpenApi\Attributes as OA;
@@ -26,33 +26,30 @@
2626
* This controller provides methods to create and destroy REST API sessions.
2727
*
2828
* @author Oliver Klee <[email protected]>
29+
* @author Tatevik Grigoryan <[email protected]>
2930
*/
31+
#[Route('/sessions')]
3032
class SessionController extends AbstractController
3133
{
3234
use AuthenticationTrait;
3335

3436
private AdministratorRepository $administratorRepository;
35-
private AdministratorTokenRepository $tokenRepository;
3637
private SerializerInterface $serializer;
38+
private SessionManager $sessionManager;
3739

3840
public function __construct(
3941
Authentication $authentication,
4042
AdministratorRepository $administratorRepository,
41-
AdministratorTokenRepository $tokenRepository,
42-
SerializerInterface $serializer
43+
SerializerInterface $serializer,
44+
SessionManager $sessionManager,
4345
) {
4446
$this->authentication = $authentication;
4547
$this->administratorRepository = $administratorRepository;
46-
$this->tokenRepository = $tokenRepository;
4748
$this->serializer = $serializer;
49+
$this->sessionManager = $sessionManager;
4850
}
4951

50-
/**
51-
* Creates a new session (if the provided credentials are valid).
52-
*
53-
* @throws UnauthorizedHttpException
54-
*/
55-
#[Route('/sessions', name: 'create_session', methods: ['POST'])]
52+
#[Route('', name: 'create_session', methods: ['POST'])]
5653
#[OA\Post(
5754
path: '/sessions',
5855
description: 'Given valid login data, this will generate a login token that will be valid for 1 hour.',
@@ -105,21 +102,18 @@ public function __construct(
105102
)
106103
]
107104
)]
108-
public function createSession(Request $request): JsonResponse
109-
{
110-
$this->validateCreateRequest($request);
111-
$administrator = $this->administratorRepository->findOneByLoginCredentials(
112-
$request->getPayload()->get('login_name'),
113-
$request->getPayload()->get('password')
114-
);
115-
if ($administrator === null) {
116-
throw new UnauthorizedHttpException('', 'Not authorized', null, 1500567098);
117-
}
105+
public function createSession(
106+
Request $request,
107+
RequestValidator $validator,
108+
AdministratorTokenNormalizer $normalizer
109+
): JsonResponse {
110+
/** @var CreateSessionRequest $createSessionRequest */
111+
$createSessionRequest = $validator->validate($request, CreateSessionRequest::class);
112+
$token = $this->sessionManager->createSession($createSessionRequest);
118113

119-
$token = $this->createAndPersistToken($administrator);
120-
$json = $this->serializer->serialize($token, 'json');
114+
$json = $normalizer->normalize($token, 'json');
121115

122-
return new JsonResponse($json, Response::HTTP_CREATED, [], true);
116+
return new JsonResponse($json, Response::HTTP_CREATED, [], false);
123117
}
124118

125119
/**
@@ -129,7 +123,7 @@ public function createSession(Request $request): JsonResponse
129123
*
130124
* @throws AccessDeniedHttpException
131125
*/
132-
#[Route('/sessions/{sessionId}', name: 'delete_session', methods: ['DELETE'])]
126+
#[Route('/{sessionId}', name: 'delete_session', methods: ['DELETE'])]
133127
#[OA\Delete(
134128
path: '/sessions/{sessionId}',
135129
description: 'Delete the session passed as a parameter.',
@@ -177,7 +171,7 @@ public function createSession(Request $request): JsonResponse
177171
)
178172
]
179173
)]
180-
public function deleteAction(
174+
public function deleteSession(
181175
Request $request,
182176
#[MapEntity(mapping: ['sessionId' => 'id'])] AdministratorToken $token
183177
): JsonResponse {
@@ -186,43 +180,8 @@ public function deleteAction(
186180
throw new AccessDeniedHttpException('You do not have access to this session.', null, 1519831644);
187181
}
188182

189-
$this->tokenRepository->remove($token);
183+
$this->sessionManager->deleteSession($token);
190184

191185
return new JsonResponse(null, Response::HTTP_NO_CONTENT, [], false);
192186
}
193-
194-
/**
195-
* Validates the request. If is it not valid, throws an exception.
196-
*
197-
* @param Request $request
198-
*
199-
* @return void
200-
*
201-
* @throws BadRequestHttpException
202-
*/
203-
private function validateCreateRequest(Request $request): void
204-
{
205-
if ($request->getContent() === '') {
206-
throw new BadRequestHttpException('Empty JSON data', null, 1500559729);
207-
}
208-
if (empty($request->getPayload()->get('login_name')) || empty($request->getPayload()->get('password'))) {
209-
throw new BadRequestHttpException('Incomplete credentials', null, 1500562647);
210-
}
211-
}
212-
213-
/**
214-
* @param Administrator $administrator
215-
*
216-
* @return AdministratorToken
217-
*/
218-
private function createAndPersistToken(Administrator $administrator): AdministratorToken
219-
{
220-
$token = new AdministratorToken();
221-
$token->setAdministrator($administrator);
222-
$token->generateExpiry();
223-
$token->generateKey();
224-
$this->tokenRepository->save($token);
225-
226-
return $token;
227-
}
228187
}

src/Entity/CreateSessionRequest.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Entity;
6+
7+
use Symfony\Component\Validator\Constraints as Assert;
8+
9+
class CreateSessionRequest implements RequestInterface
10+
{
11+
#[Assert\NotBlank]
12+
#[Assert\Type(type: 'string')]
13+
public string $loginName;
14+
15+
#[Assert\NotBlank]
16+
#[Assert\Type(type: 'string')]
17+
public string $password;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Serializer;
6+
7+
use PhpList\Core\Domain\Model\Identity\AdministratorToken;
8+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
9+
10+
class AdministratorTokenNormalizer implements NormalizerInterface
11+
{
12+
public function normalize($object, string $format = null, array $context = []): array
13+
{
14+
if (!$object instanceof AdministratorToken) {
15+
return [];
16+
}
17+
18+
return [
19+
'id' => $object->getId(),
20+
'key' => $object->getKey(),
21+
'expiry' => $object->getExpiry()->format('Y-m-d\TH:i:sP'),
22+
];
23+
}
24+
25+
/**
26+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
27+
*/
28+
public function supportsNormalization($data, string $format = null): bool
29+
{
30+
return $data instanceof AdministratorToken;
31+
}
32+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Service\Manager;
6+
7+
use PhpList\Core\Domain\Model\Identity\AdministratorToken;
8+
use PhpList\Core\Domain\Repository\Identity\AdministratorRepository;
9+
use PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository;
10+
use PhpList\RestBundle\Entity\CreateSessionRequest;
11+
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
12+
13+
class SessionManager
14+
{
15+
private AdministratorTokenRepository $tokenRepository;
16+
private AdministratorRepository $administratorRepository;
17+
18+
public function __construct(
19+
AdministratorTokenRepository $tokenRepository,
20+
AdministratorRepository $administratorRepository
21+
) {
22+
$this->tokenRepository = $tokenRepository;
23+
$this->administratorRepository = $administratorRepository;
24+
}
25+
26+
public function createSession(CreateSessionRequest $createSessionRequest): AdministratorToken
27+
{
28+
$administrator = $this->administratorRepository->findOneByLoginCredentials(
29+
$createSessionRequest->loginName,
30+
$createSessionRequest->password
31+
);
32+
if ($administrator === null) {
33+
throw new UnauthorizedHttpException('', 'Not authorized', null, 1500567098);
34+
}
35+
36+
$token = new AdministratorToken();
37+
$token->setAdministrator($administrator);
38+
$token->generateExpiry();
39+
$token->generateKey();
40+
$this->tokenRepository->save($token);
41+
42+
return $token;
43+
}
44+
45+
public function deleteSession(AdministratorToken $token): void
46+
{
47+
$this->tokenRepository->remove($token);
48+
}
49+
}

0 commit comments

Comments
 (0)