src/Security/TokenAuthenticator.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use Symfony\Component\HttpFoundation\Request;
  4. use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
  5. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  6. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  7. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  10. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  11. use Symfony\Component\Security\Core\User\UserInterface;
  12. class TokenAuthenticator extends AbstractAuthenticator
  13. {
  14.     public function __construct(private FileTokenStorage $storage){}
  15.     public function supports(Request $request): ?bool
  16.     { return $request->headers->has('X-DASH-TOKEN') || $request->query->has('token') || $request->getSession()->has('tv_token'); }
  17.     public function authenticate(Request $request): Passport
  18.     {
  19.         $tokenVal = $request->headers->get('X-DASH-TOKEN') ?? $request->query->get('token') ?? $request->getSession()->get('tv_token');
  20.     $row = $tokenVal ? $this->storage->find($tokenVal) : null;
  21.         if(!$row) {
  22.             throw new CustomUserMessageAuthenticationException('Invalid token');
  23.         }
  24.         if(empty($row['active']) || ($row['active'] !== true)) {
  25.             if (!empty($row['expiresAt']) && strtotime($row['expiresAt']) < time()) {
  26.                 throw new CustomUserMessageAuthenticationException('Token expired');
  27.             }
  28.             throw new CustomUserMessageAuthenticationException('Token disabled');
  29.         }
  30.         $this->storage->touch($row['token']);
  31.         return new SelfValidatingPassport(new UserBadge('token:'.$row['token'], function() use ($row): UserInterface {
  32.             return new class($row) implements UserInterface {
  33.                 public function __construct(private array $t){}
  34.                 public function getRoles(): array { $r=$this->t['roles'] ?? []; if(!in_array('ROLE_USER',$r,true)){$r[]='ROLE_USER';} return $r; }
  35.                 public function getPassword(){ return null; }
  36.                 public function getSalt(){}
  37.                 public function getUserIdentifier(): string { return 'token_user'; }
  38.                 public function getUsername(): string { return 'token_user'; }
  39.                 public function eraseCredentials(){}
  40.             };
  41.         }));
  42.     }
  43.     public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { return null; }
  44.     public function onAuthenticationFailure(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $exception): ?Response
  45.     { return new \Symfony\Component\HttpFoundation\JsonResponse(['error'=>'Auth token failed'], 401); }
  46. }