Skip to content

Commit

Permalink
Add HTTP header Etag to GET responses of element and collection end…
Browse files Browse the repository at this point in the history
…points, closes #88.
  • Loading branch information
Syndesi committed Jan 14, 2024
1 parent ee0e57c commit 89a7fde
Show file tree
Hide file tree
Showing 39 changed files with 1,216 additions and 198 deletions.
3 changes: 2 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
'import_classes' => true,
'import_constants' => true,
'import_functions' => true
]
],
'self_accessor' => true
])
->setFinder($finder)
;
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `/.well-known/security.txt` endpoint, documentation for it and (disabled) file check on container startup which
will crash the container intentionally if the file is missing. Check will be enabled with the release of version
0.2.0, see also #225. Closes issue #131.
- Add HTTP header `Etag` to GET responses of element and collection endpoints, closes #88.
### Changed
- Constants are changed to contain type declarations, closes #211.
- Remove timeout from PHP-tasks, closes #220. CI timeouts still apply.
- Upgrade PHP to 8.3.1, closes #223.
- Enable `composer mess` in CI due to fixed upstream issue, closes #203.
- Enable PHP CS Fixer rule `self_accessor`, which prefers `self` over the element's class name.
- Change value of HTTP header `X-Powered-By` to `Ember Nexus API`.

## 0.1.0 - 2023-12-16
### Added
Expand Down
1 change: 1 addition & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ imports:
- {resource: ../src/EventSystem/ElementDefragmentize/config.yaml}
- {resource: ../src/EventSystem/ElementFragmentize/config.yaml}
- {resource: ../src/EventSystem/EntityManager/config.yaml}
- {resource: ../src/EventSystem/Etag/config.yaml}
- {resource: ../src/EventSystem/Exception/config.yaml}
- {resource: ../src/EventSystem/Kernel/config.yaml}
- {resource: ../src/EventSystem/Request/config.yaml}
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ WORKDIR /var/www/html
FROM php as development

RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS judy-dev bsd-compat-headers \
&& pecl install xdebug-3.3.0alpha3 memprof \
&& pecl install xdebug-3.3.1 memprof-3.0.2 \
&& docker-php-ext-enable xdebug memprof \
&& apk del --no-network .build-deps \
&& apk add --no-cache judy aha git openssh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function getAlias(): string
return 'ember_nexus';
}

public function load(array $rawConfigurations, ContainerBuilder $container)
public function load(array $rawConfigurations, ContainerBuilder $container): void
{
$configuration = $this->getConfiguration($rawConfigurations, $container);
$processedConfiguration = $this->processConfiguration($configuration, $rawConfigurations);
Expand Down
26 changes: 13 additions & 13 deletions lib/EmberNexusBundle/src/Service/EmberNexusConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private static function getValueFromConfig(array $configuration, array $keyParts

public static function createFromConfiguration(array $configuration): self
{
$emberNexusConfiguration = new EmberNexusConfiguration();
$emberNexusConfiguration = new self();

$emberNexusConfiguration->setPageSizeMin((int) self::getValueFromConfig(
$configuration,
Expand Down Expand Up @@ -211,7 +211,7 @@ public function getPageSizeMin(): int
return $this->pageSizeMin;
}

public function setPageSizeMin(int $pageSizeMin): EmberNexusConfiguration
public function setPageSizeMin(int $pageSizeMin): self
{
$this->pageSizeMin = $pageSizeMin;

Expand All @@ -223,7 +223,7 @@ public function getPageSizeDefault(): int
return $this->pageSizeDefault;
}

public function setPageSizeDefault(int $pageSizeDefault): EmberNexusConfiguration
public function setPageSizeDefault(int $pageSizeDefault): self
{
$this->pageSizeDefault = $pageSizeDefault;

Expand All @@ -235,7 +235,7 @@ public function getPageSizeMax(): int
return $this->pageSizeMax;
}

public function setPageSizeMax(int $pageSizeMax): EmberNexusConfiguration
public function setPageSizeMax(int $pageSizeMax): self
{
$this->pageSizeMax = $pageSizeMax;

Expand All @@ -247,7 +247,7 @@ public function isRegisterEnabled(): bool
return $this->registerEnabled;
}

public function setRegisterEnabled(bool $registerEnabled): EmberNexusConfiguration
public function setRegisterEnabled(bool $registerEnabled): self
{
$this->registerEnabled = $registerEnabled;

Expand All @@ -259,7 +259,7 @@ public function getRegisterUniqueIdentifier(): string
return $this->registerUniqueIdentifier;
}

public function setRegisterUniqueIdentifier(string $registerUniqueIdentifier): EmberNexusConfiguration
public function setRegisterUniqueIdentifier(string $registerUniqueIdentifier): self
{
if (0 === strlen($registerUniqueIdentifier)) {
throw new Exception('Unique identifier can not be an empty string.');
Expand All @@ -277,7 +277,7 @@ public function getRegisterUniqueIdentifierRegex(): string|false
return $this->registerUniqueIdentifierRegex;
}

public function setRegisterUniqueIdentifierRegex(string|false $registerUniqueIdentifierRegex): EmberNexusConfiguration
public function setRegisterUniqueIdentifierRegex(string|false $registerUniqueIdentifierRegex): self
{
$this->registerUniqueIdentifierRegex = $registerUniqueIdentifierRegex;

Expand All @@ -289,7 +289,7 @@ public function isInstanceConfigurationEnabled(): bool
return $this->instanceConfigurationEnabled;
}

public function setInstanceConfigurationEnabled(bool $instanceConfigurationEnabled): EmberNexusConfiguration
public function setInstanceConfigurationEnabled(bool $instanceConfigurationEnabled): self
{
$this->instanceConfigurationEnabled = $instanceConfigurationEnabled;

Expand All @@ -301,7 +301,7 @@ public function isInstanceConfigurationShowVersion(): bool
return $this->instanceConfigurationShowVersion;
}

public function setInstanceConfigurationShowVersion(bool $instanceConfigurationShowVersion): EmberNexusConfiguration
public function setInstanceConfigurationShowVersion(bool $instanceConfigurationShowVersion): self
{
$this->instanceConfigurationShowVersion = $instanceConfigurationShowVersion;

Expand All @@ -313,7 +313,7 @@ public function getTokenMinLifetimeInSeconds(): int
return $this->tokenMinLifetimeInSeconds;
}

public function setTokenMinLifetimeInSeconds(int $tokenMinLifetimeInSeconds): EmberNexusConfiguration
public function setTokenMinLifetimeInSeconds(int $tokenMinLifetimeInSeconds): self
{
$this->tokenMinLifetimeInSeconds = $tokenMinLifetimeInSeconds;

Expand All @@ -325,7 +325,7 @@ public function getTokenDefaultLifetimeInSeconds(): int
return $this->tokenDefaultLifetimeInSeconds;
}

public function setTokenDefaultLifetimeInSeconds(int $tokenDefaultLifetimeInSeconds): EmberNexusConfiguration
public function setTokenDefaultLifetimeInSeconds(int $tokenDefaultLifetimeInSeconds): self
{
$this->tokenDefaultLifetimeInSeconds = $tokenDefaultLifetimeInSeconds;

Expand All @@ -337,7 +337,7 @@ public function getTokenMaxLifetimeInSeconds(): false|int
return $this->tokenMaxLifetimeInSeconds;
}

public function setTokenMaxLifetimeInSeconds(bool|int $tokenMaxLifetimeInSeconds): EmberNexusConfiguration
public function setTokenMaxLifetimeInSeconds(bool|int $tokenMaxLifetimeInSeconds): self
{
$this->tokenMaxLifetimeInSeconds = $tokenMaxLifetimeInSeconds;

Expand All @@ -349,7 +349,7 @@ public function getTokenDeleteExpiredTokensAutomaticallyInSeconds(): bool|int
return $this->tokenDeleteExpiredTokensAutomaticallyInSeconds;
}

public function setTokenDeleteExpiredTokensAutomaticallyInSeconds(bool|int $tokenDeleteExpiredTokensAutomaticallyInSeconds): EmberNexusConfiguration
public function setTokenDeleteExpiredTokensAutomaticallyInSeconds(bool|int $tokenDeleteExpiredTokensAutomaticallyInSeconds): self
{
$this->tokenDeleteExpiredTokensAutomaticallyInSeconds = $tokenDeleteExpiredTokensAutomaticallyInSeconds;

Expand Down
2 changes: 1 addition & 1 deletion public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
header('Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method');
header('Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK');
header('Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK');
header('X-Powered-By: Ember-Nexus-API');
header('X-Powered-By: Ember Nexus API');
$method = $_SERVER['REQUEST_METHOD'];
if ('OPTIONS' == $method) {
exit;
Expand Down
42 changes: 0 additions & 42 deletions src/Command/TestCommand.php

This file was deleted.

11 changes: 10 additions & 1 deletion src/Controller/Element/GetChildrenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Security\AccessChecker;
use App\Security\AuthProvider;
use App\Service\CollectionService;
use App\Service\EtagService;
use App\Type\AccessType;
use App\Type\ElementType;
use Laudis\Neo4j\Databags\Statement;
Expand All @@ -23,6 +24,7 @@ public function __construct(
private CollectionService $collectionService,
private AuthProvider $authProvider,
private AccessChecker $accessChecker,
private EtagService $etagService,
private Client404NotFoundExceptionFactory $client404NotFoundExceptionFactory
) {
}
Expand Down Expand Up @@ -127,6 +129,13 @@ public function getChildren(string $uuid): Response
}
}

return $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);
$response = $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);

$etag = $this->etagService->getChildrenCollectionEtag($parentUuid);
if ($etag) {
$response->headers->set('Etag', $etag);
}

return $response;
}
}
11 changes: 10 additions & 1 deletion src/Controller/Element/GetElementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Security\AccessChecker;
use App\Security\AuthProvider;
use App\Service\ElementResponseService;
use App\Service\EtagService;
use App\Type\AccessType;
use Ramsey\Uuid\Rfc4122\UuidV4;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
Expand All @@ -19,6 +20,7 @@ public function __construct(
private ElementResponseService $elementResponseService,
private AuthProvider $authProvider,
private AccessChecker $accessChecker,
private EtagService $etagService,
private Client404NotFoundExceptionFactory $client404NotFoundExceptionFactory
) {
}
Expand All @@ -40,6 +42,13 @@ public function getElement(string $uuid): Response
throw $this->client404NotFoundExceptionFactory->createFromTemplate();
}

return $this->elementResponseService->buildElementResponseFromUuid($elementUuid);
$response = $this->elementResponseService->buildElementResponseFromUuid($elementUuid);

$etag = $this->etagService->getElementEtag($elementUuid);
if ($etag) {
$response->headers->set('Etag', $etag);
}

return $response;
}
}
11 changes: 10 additions & 1 deletion src/Controller/Element/GetIndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Security\AuthProvider;
use App\Service\CollectionService;
use App\Service\EtagService;
use Laudis\Neo4j\Databags\Statement;
use Ramsey\Uuid\Rfc4122\UuidV4;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
Expand All @@ -17,6 +18,7 @@ public function __construct(
private CypherEntityManager $cypherEntityManager,
private AuthProvider $authProvider,
private CollectionService $collectionService,
private EtagService $etagService,
) {
}

Expand Down Expand Up @@ -47,6 +49,13 @@ public function getIndex(): Response
$nodeUuids[] = UuidV4::fromString($resultSet->get('element.id'));
}

return $this->collectionService->buildCollectionFromUuids($nodeUuids, [], count($nodeUuids));
$response = $this->collectionService->buildCollectionFromUuids($nodeUuids, [], count($nodeUuids));

$etag = $this->etagService->getIndexCollectionEtag($userUuid);
if ($etag) {
$response->headers->set('Etag', $etag);
}

return $response;
}
}
11 changes: 10 additions & 1 deletion src/Controller/Element/GetParentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Security\AccessChecker;
use App\Security\AuthProvider;
use App\Service\CollectionService;
use App\Service\EtagService;
use App\Type\AccessType;
use App\Type\ElementType;
use Laudis\Neo4j\Databags\Statement;
Expand All @@ -23,6 +24,7 @@ public function __construct(
private CollectionService $collectionService,
private AuthProvider $authProvider,
private AccessChecker $accessChecker,
private EtagService $etagService,
private Client404NotFoundExceptionFactory $client404NotFoundExceptionFactory
) {
}
Expand Down Expand Up @@ -127,6 +129,13 @@ public function getParents(string $uuid): Response
}
}

return $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);
$response = $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);

$etag = $this->etagService->getParentsCollectionEtag($childUuid);
if ($etag) {
$response->headers->set('Etag', $etag);
}

return $response;
}
}
11 changes: 10 additions & 1 deletion src/Controller/Element/GetRelatedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Security\AccessChecker;
use App\Security\AuthProvider;
use App\Service\CollectionService;
use App\Service\EtagService;
use App\Type\AccessType;
use App\Type\ElementType;
use Laudis\Neo4j\Databags\Statement;
Expand All @@ -23,6 +24,7 @@ public function __construct(
private CollectionService $collectionService,
private AuthProvider $authProvider,
private AccessChecker $accessChecker,
private EtagService $etagService,
private Client404NotFoundExceptionFactory $client404NotFoundExceptionFactory
) {
}
Expand Down Expand Up @@ -127,6 +129,13 @@ public function getRelated(string $uuid): Response
}
}

return $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);
$response = $this->collectionService->buildCollectionFromUuids($nodeUuids, $relationUuids, $totalCount);

$etag = $this->etagService->getRelatedCollectionEtag($centerUuid);
if ($etag) {
$response->headers->set('Etag', $etag);
}

return $response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public function isDeactivated(): bool
return $this->isDeactivated;
}

public function deactivate(): DeactivatableTraceableEventDispatcher
public function deactivate(): self
{
$this->logger?->notice('Activated TraceableEventDispatcher');
$this->isDeactivated = true;

return $this;
}

public function activate(): DeactivatableTraceableEventDispatcher
public function activate(): self
{
$this->isDeactivated = false;

Expand Down
Loading

0 comments on commit 89a7fde

Please sign in to comment.