headless_cms-1.0.3/modules/headless_cms_preview/src/Authentication/Provider/PreviewToken.php
modules/headless_cms_preview/src/Authentication/Provider/PreviewToken.php
<?php
declare(strict_types=1);
namespace Drupal\headless_cms_preview\Authentication\Provider;
use Drupal\Core\Authentication\AuthenticationProviderInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\headless_cms_preview\PreviewToken\PreviewTokenNegotiator;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
/**
* Authentication provider for headless preview tokens.
*
* This authentication provider authenticates the user as the user
* specified in a preview token, BUT only for the JSON:API preview
* routes.
*/
class PreviewToken implements AuthenticationProviderInterface {
public function __construct(
protected PreviewTokenNegotiator $previewTokenNegotiator,
protected EntityTypeManagerInterface $entityTypeManager,
#[Autowire('@router.no_access_checks')]
protected RouterInterface $router,
) {}
/**
* {@inheritdoc}
*
* Checks that this authentication provider only applies to preview
* requests that match the entity in the preview token.
*/
public function applies(Request $request) {
$token = $this->previewTokenNegotiator->negotiateFromRequest($request);
if (!$token) {
return FALSE;
}
$previewRoute = sprintf(
'jsonapi.%s--%s.individual.preview',
$token->entityTypeId,
$token->entityTypeBundle,
);
$individualRoute = sprintf(
'jsonapi.%s--%s.individual',
$token->entityTypeId,
$token->entityTypeBundle,
);
// Check entity type and bundle matches route.
$match = $this->router->match($request->getPathInfo());
if (!$match) {
return FALSE;
}
// If preview route matches and token matches entity, return TRUE.
if ($match['_route'] === $previewRoute && $match['node_preview']->uuid() === $token->entityUuid) {
return TRUE;
}
// If individual route matches and token matches entity, return TRUE.
if ($match['_route'] === $individualRoute && $match['entity']->uuid() === $token->entityUuid) {
return TRUE;
}
return FALSE;
}
/**
* {@inheritdoc}
*
* If the authentication provider applies, return the user entity
* declared in the preview token.
*/
public function authenticate(Request $request) {
$token = $this->previewTokenNegotiator->negotiateFromRequest($request);
if (!$token || $token->ownerUid < 1) {
return NULL;
}
return $this->entityTypeManager->getStorage('user')->load($token->ownerUid);
}
}
