<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
class TokenAuthenticator extends AbstractAuthenticator
{
public function __construct(private FileTokenStorage $storage){}
public function supports(Request $request): ?bool
{ return $request->headers->has('X-DASH-TOKEN') || $request->query->has('token') || $request->getSession()->has('tv_token'); }
public function authenticate(Request $request): Passport
{
$tokenVal = $request->headers->get('X-DASH-TOKEN') ?? $request->query->get('token') ?? $request->getSession()->get('tv_token');
$row = $tokenVal ? $this->storage->find($tokenVal) : null;
if(!$row) {
throw new CustomUserMessageAuthenticationException('Invalid token');
}
if(empty($row['active']) || ($row['active'] !== true)) {
if (!empty($row['expiresAt']) && strtotime($row['expiresAt']) < time()) {
throw new CustomUserMessageAuthenticationException('Token expired');
}
throw new CustomUserMessageAuthenticationException('Token disabled');
}
$this->storage->touch($row['token']);
return new SelfValidatingPassport(new UserBadge('token:'.$row['token'], function() use ($row): UserInterface {
return new class($row) implements UserInterface {
public function __construct(private array $t){}
public function getRoles(): array { $r=$this->t['roles'] ?? []; if(!in_array('ROLE_USER',$r,true)){$r[]='ROLE_USER';} return $r; }
public function getPassword(){ return null; }
public function getSalt(){}
public function getUserIdentifier(): string { return 'token_user'; }
public function getUsername(): string { return 'token_user'; }
public function eraseCredentials(){}
};
}));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { return null; }
public function onAuthenticationFailure(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $exception): ?Response
{ return new \Symfony\Component\HttpFoundation\JsonResponse(['error'=>'Auth token failed'], 401); }
}